diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce755d9..1c798bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,7 @@ jobs: extism call example/tiny_http.wasm --wasi http_get --github-token="$GITHUB_TOKEN" --allow-host "jsonplaceholder.typicode.com" | grep '"userId": 1' + extism call example/tiny_reactor.wasm read_file --input "example/reactor/test.txt" --allow-path ./example/reactor --wasi --log-level info | grep 'Hello World!' # run all the tests make test diff --git a/Makefile b/Makefile index 31fcaeb..36f5d16 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ example: tinygo build -o example/tiny_countvowels.wasm -target wasi ./example/countvowels tinygo build -o example/tiny_http.wasm -target wasi ./example/http + tinygo build -o example/tiny_reactor.wasm -target wasi ./example/reactor GOOS=wasip1 GOARCH=wasm go build -tags std -o example/std_countvowels.wasm ./example/countvowels GOOS=wasip1 GOARCH=wasm go build -tags std -o example/std_http.wasm ./example/http @@ -9,6 +10,7 @@ example: test: extism call example/tiny_countvowels.wasm count_vowels --wasi --input "this is a test" --set-config '{"thing": "1234"}' extism call example/tiny_http.wasm http_get --wasi --log-level info --allow-host "jsonplaceholder.typicode.com" + extism call example/tiny_reactor.wasm read_file --input "example/reactor/test.txt" --allow-path ./example/reactor --wasi --log-level info extism call example/std_countvowels.wasm _start --wasi --input "this is a test" --set-config '{"thing": "1234"}' extism call example/std_http.wasm _start --wasi --log-level info --allow-host "jsonplaceholder.typicode.com" \ No newline at end of file diff --git a/README.md b/README.md index 72104d2..bdd513f 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,44 @@ python3 app.py # => An argument to send to Python! ``` +## Reactor modules + +Since TinyGo doesn't support [Reactor modules](https://dylibso.com/blog/wasi-command-reactor/) yet, If you want to use WASI inside your Reactor module functions (exported functions other than `main`), you'll need to import `wasi-reactor` module which makes sure libc and go runtime are properly initialized: + +```go +package main + +import ( + "os" + + "github.com/extism/go-pdk" + _ "github.com/extism/go-pdk/wasi-reactor" +) + +//export read_file +func read_file() { + name := pdk.InputString() + + content, err := os.ReadFile(name) + if err != nil { + pdk.Log(pdk.LogError, err.Error()) + return + } + + pdk.Output(content) +} + +func main() {} +``` + +```bash +tinygo build -target wasi -o reactor.wasm .\tiny_main.go +extism call ./reactor.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info +# => Hello World! +``` + +Note: this is not required if you only have the `main` function. + ### Reach Out! Have a question or just want to drop in and say hi? [Hop on the Discord](https://extism.org/discord)! diff --git a/example/reactor/README.md b/example/reactor/README.md new file mode 100644 index 0000000..d6a67aa --- /dev/null +++ b/example/reactor/README.md @@ -0,0 +1,16 @@ +## Reactor module example +By including this package, you'll turn your plugin into a [Reactor](https://dylibso.com/blog/wasi-command-reactor/) module. This makes sure that you can use WASI (e.g. File Access) in your exported functions. + +To test this example, run: + +```bash +tinygo build -target wasi -o reactor.wasm .\tiny_main.go +extism call ./reactor.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info +# => Hello World! +``` + +If you don't include the pacakge, you'll see this output: +```bash +extism call .\c.wasm read_file --input "./test.txt" --allow-path . --wasi --log-level info +# => 2024/01/18 20:48:48 open ./test.txt: errno 76 +``` \ No newline at end of file diff --git a/example/reactor/test.txt b/example/reactor/test.txt new file mode 100644 index 0000000..c57eff5 --- /dev/null +++ b/example/reactor/test.txt @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/example/reactor/tiny_main.go b/example/reactor/tiny_main.go new file mode 100644 index 0000000..b4d5371 --- /dev/null +++ b/example/reactor/tiny_main.go @@ -0,0 +1,26 @@ +//go:build !std +// +build !std + +package main + +import ( + "os" + + "github.com/extism/go-pdk" + _ "github.com/extism/go-pdk/wasi-reactor" +) + +//export read_file +func read_file() { + name := pdk.InputString() + + content, err := os.ReadFile(name) + if err != nil { + pdk.Log(pdk.LogError, err.Error()) + return + } + + pdk.Output(content) +} + +func main() {} diff --git a/go.work b/go.work new file mode 100644 index 0000000..99b21af --- /dev/null +++ b/go.work @@ -0,0 +1,6 @@ +go 1.21.1 + +use ( + . + ./wasi-reactor +) diff --git a/wasi-reactor/extism_pdk_reactor.go b/wasi-reactor/extism_pdk_reactor.go new file mode 100644 index 0000000..5a5bd4a --- /dev/null +++ b/wasi-reactor/extism_pdk_reactor.go @@ -0,0 +1,9 @@ +package reactor + +//export __wasm_call_ctors +func __wasm_call_ctors() + +//export _initialize +func _initialize() { + __wasm_call_ctors() +} diff --git a/wasi-reactor/go.mod b/wasi-reactor/go.mod new file mode 100644 index 0000000..797bced --- /dev/null +++ b/wasi-reactor/go.mod @@ -0,0 +1,3 @@ +module github.com/extism/go-pdk/wasi-reactor + +go 1.21.1