Skip to content

Releases: bots-garden/capsule

v0.3.2 🤗 [WASM I/O 2023]

24 Mar 06:08
Compare
Choose a tag to compare

Merge of PR made by @evacchi #225

Capsule is now twice as fast 🚀

Thanks a lot @evacchi

v0.3.1 🐊 [Tampa Bay]

07 Feb 10:29
Compare
Choose a tag to compare

Dependencies updates: wazero to 1.0.0-pre.8 | Thank you to @evacchi

v0.3.0 🎄 [Christmas tree]

07 Nov 18:45
Compare
Choose a tag to compare

Refactoring (Capsule is at least 4 times faster than the previous version).

v0.2.9 🦜 [parrot]

27 Oct 07:06
Compare
Choose a tag to compare
📦 updates modules for v0.2.9

v0.2.8 🦤 [dodo]

09 Oct 23:40
Compare
Choose a tag to compare

Capsule uses now Fiber instead Gin.

v0.2.7 🦚 [peacock]

08 Oct 16:20
Compare
Choose a tag to compare

The fall version 🍁

The Docker image of Capsule will follow the same versioning.

Install Capsule

CAPSULE_VERSION="v0.2.7"
wget -O - https://raw.githubusercontent.com/bots-garden/capsule/${CAPSULE_VERSION}/install-capsule-launcher.sh| bash

The script will install Capsule in $HOME/.local/bin

🖐 On macOS:

  • create the $HOME/.local/bin directory
  • add it to your path:
    export CAPSULE_PATH="$HOME/.local"
    export PATH="$CAPSULE_PATH/bin:$PATH"

if you want to install Capsule somewhere else, override the CAPSULE_PATH variable (default value: CAPSULE_PATH="$HOME/.local/bin")

Install Capsule Builder (cabu)

CAPSULE_BUILDER_VERSION="v0.0.1"
wget -O - https://raw.githubusercontent.com/bots-garden/capsule-function-builder/${CAPSULE_BUILDER_VERSION}/install-capsule-builder.sh | bash

v0.2.6 🐝 [Bee]

01 Oct 05:12
Compare
Choose a tag to compare
v0.2.6 🐝 [Bee] Pre-release
Pre-release

v0.2.5 🦖 [T-Rex] MQTT

25 Sep 06:03
Compare
Choose a tag to compare
Pre-release

This new version brings MQTT support. A big thank you to @py4mac

You can now use Capsule as an MQTT subscriber:

package main

import (
	hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions"
)

func main() {
	hf.OnMqttMessage(Handle)
}

func Handle(params []string) {

	hf.Log("👋 on topic: " + hf.MqttGetTopic() + ", 🎉 message" + params[0])

	_, err := hf.MqttPublish("topic/reply", "it's a wasm module here")

	if err != nil {
		hf.Log("😡 ouch something bad is happening")
		hf.Log(err.Error())
	}
}
# the topic is defined when launching the capsule launcher
capsule \
   -wasm=./hello.wasm \
   -mode=mqtt \
   -mqttsrv=127.0.0.1:1883 \
   -topic=topic/sensor0 \
   -clientId=sensor

And you can use Capsule as an MQTT publisher:

package main

import (
	"errors"
	hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions"
	"strings"
)

func main() {
	hf.SetHandle(Handle)
}

func Handle(params []string) (string, error) {
	var errs []string

	// a new connection is created at every call/publish
	_, err1stMsg := hf.MqttConnectPublish("127.0.0.1:1883", "sensor_id0", "topic/sensor0", "🖐 Hello from WASM with MQTT 💜")
	_, err2ndMsg := hf.MqttConnectPublish("127.0.0.1:1883", "sensor_id0", "topic/sensor1", "👋 Hello World 🌍")

	if err1stMsg != nil {
		errs = append(errs, err1stMsg.Error())
	}
	if err2ndMsg != nil {
		errs = append(errs, err2ndMsg.Error())
	}

	return "MQTT Rocks!", errors.New(strings.Join(errs, "|"))
}
capsule \
   -wasm=./hello.wasm \
   -mode=cli

v0.2.4 🦎 [lizard] "flatjson"

24 Sep 09:41
Compare
Choose a tag to compare
Pre-release

Handling Json with TinyGo is not straight forward (but not impossible).
If your use case is very simple (a Json string without nested object or array) you can use:

  • flatjson.StrToMap(flatJsonStr string) map[string]interface{}: get a flat json string (no nested obj) and return a map
  • flatjson.MapToStr(jsonMap map[string]interface{}) string: get a flat json map and return a json string

Example:

package main

import (
    "github.com/bots-garden/capsule/capsulemodule/flatjson"
    hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions"
    "strconv"
)

func main() {
    hf.SetHandleHttp(Handle)
}

func Handle(request hf.Request) (response hf.Response, errResp error) {

    jsonMap := flatjson.StrToMap(request.Body)

    author := jsonMap["author"].(string)
    age := jsonMap["age"].(int)
    weight := jsonMap["weight"].(float64)
    isHuman := jsonMap["human"].(bool)
    message := jsonMap["message"].(string)

    hf.Log("👋 " + message + " by " + author + " 😄")
    hf.Log("👋 age: " + strconv.Itoa(age))
    hf.Log("👋 weight: " + strconv.FormatFloat(weight, 'f', 6, 64))

    if isHuman {
        hf.Log("I'm not a 🤖")
    }

    headersResp := map[string]string{
        "Content-Type": "application/json; charset=utf-8",
    }

    responseMap := map[string]interface{}{
        "message": "👋 hey! What's up?",
        "author":  "Bob",
    }

    return hf.Response{Body: flatjson.MapToStr(responseMap), Headers: headersResp}, nil
}

Call the function:

curl -v -X POST \
  http://localhost:7070 \
  -H 'content-type: application/json; charset=utf-8' \
  -d '{"message": "TinyGo 💚💜 wasm", "author": "@k33g", "text":"this is a text", "age":42, "human": true, "weight": 100.5}'

v0.2.3 🐢 [turtle]

23 Sep 05:27
Compare
Choose a tag to compare
v0.2.3 🐢 [turtle] Pre-release
Pre-release

Request and Reply

A NATS "publisher" can make a request to a NATS "subscriber" and wait for an answer

package main

import (
	"errors"
	hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions"
	"strings"
)

func main() {
	hf.SetHandle(Handle)
}

func Handle(params []string) (string, error) {

	// Publish and wait for an answer; 1 is the timeout in seconds
	res, err := hf.NatsConnectRequest("nats.devsecops.fun:4222", "notify", "👋 Hello World 🌍", 1)

	if err != nil {
		hf.Log("🔴" + err.Error())
	} else {
        // Display the answer
		hf.Log("🔵" + res)
	}

	return "NATS Rocks!", err
}

A NATS "subscriber" can reply to a request received on its subject

package main

import (
	hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions"
)

func main() {
	hf.OnNatsMessage(Handle)
}

func Handle(params []string) {

	hf.Log("Message on subject: " + hf.NatsGetSubject() + ", 🎉 message: " + params[0])

	// reply to the message on the current subject; 10 is the timeout in seconds
	_, _ = hf.NatsReply("Hey! What's up", 10)

}