moonbit component model
https://github.com/wasmCloud/wasmCloud-contrib にサンプルがある
以下を参考にコマンドを叩いていく
## Prerequisites
- [Rust toolchain](https://www.rust-lang.org/tools/install) to install prerequisites
- wit-deps
- `cargo install wit-deps-cli`
- wasm-tools
- `cargo install wasm-tools`
- Moonbit wit-bindgen fork
- `cargo install wit-bindgen-cli --git https://github.com/peter-jerry-ye/wit-bindgen/ --branch moonbit`
- [Moonbit CLI](https://www.moonbitlang.com/download/#moonbit-cli-tools)
- [wash CLI](https://wasmcloud.com/docs/installation)
wash 入れたけど、wasmCloud shell らしいがこれなんだろう?あとで調べる。
wash build
wash wit2wadm ./build/gen.wasm --name moonbit-http --description "HTTP hello world demo with a component written in Moonbit" > wadm.yaml
wash up -d
wash app deploy ./wadm.yaml
立ち上がったように見えるけど、サーバーの立ち上げに失敗している。
$ curl localhost:8000
failed to invoke `wrpc:http/incoming-handler.handle`: failed to invoke `wrpc:http/incoming-handler@0.1.0.handle`: failed to shutdown synchronous parameter channel: not connected% ```
wasmcloud 自体を調べないといけなくなった。nats-server というのが必要らしい。
とりあえず mac なので brew install nats-server した。
もういちど wash app deloy して、 wash app list で確認してみる。
$ wash app list
Name Latest Version Deployed Version Deploy Status Description
moonbit-http v0.1.0 v0.1.0 Reconciling HTTP hello world demo with a component written in Moonbit
Reconciling となってるのがマズそう
一旦 wash app delete moonbit-http
してから再度デプロイし直すと、ステータスが Deployed
になった。
Name Latest Version Deployed Version Deploy Status Description
moonbit-http v0.1.0 v0.1.0 Deployed HTTP hello world demo with a component written in Moonbit
が、 curl で疎通せず。
うーん、wasm cloud のことは後で調べよう。今回の本筋じゃないし。
必要なのはこれ
cargo install wit-deps-cli
cargo install wasm-tools
cargo install wit-bindgen-cli --git https://github.com/peter-jerry-ye/wit-bindgen/ --branch moonbit
この後、moonbit をビルドする。
moon build --target wasm
wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm -o target/wasm/release/build/gen/gen.wasm --encoding utf16
wasm-tools component new target/wasm/release/build/gen/gen.wasm -o target/wasm/release/build/gen/gen.wasm
wasi-http を見る
$ tree -I target
.
├── Makefile
├── README
├── ffi
│ ├── moon.pkg.json
│ └── top.mbt
├── gen
│ ├── ffi.mbt
│ ├── interface_exports_wasi_http_incoming_handler_export.mbt
│ ├── moon.pkg.json
│ └── worlds_server_export.mbt
├── interface
│ ├── exports
│ │ └── wasi
│ │ └── http
│ │ └── incomingHandler
│ │ ├── README.md
│ │ ├── moon.pkg.json
│ │ └── top.mbt
│ └── imports
│ └── wasi
│ ├── clocks
│ │ └── monotonicClock
│ │ ├── README.md
│ │ ├── moon.pkg.json
│ │ └── top.mbt
│ ├── http
│ │ └── types
│ │ ├── README.md
│ │ ├── moon.pkg.json
│ │ └── top.mbt
│ └── io
│ ├── error
│ │ ├── moon.pkg.json
│ │ └── top.mbt
│ ├── poll
│ │ ├── README.md
│ │ ├── moon.pkg.json
│ │ └── top.mbt
│ └── streams
│ ├── README.md
│ ├── moon.pkg.json
│ └── top.mbt
├── moon.mod.json
├── wit
│ ├── deps
│ │ ├── cli
│ │ │ ├── command.wit
│ │ │ ├── environment.wit
│ │ │ ├── exit.wit
│ │ │ ├── imports.wit
│ │ │ ├── run.wit
│ │ │ ├── stdio.wit
│ │ │ └── terminal.wit
│ │ ├── clocks
│ │ │ ├── monotonic-clock.wit
│ │ │ ├── timezone.wit
│ │ │ ├── wall-clock.wit
│ │ │ └── world.wit
│ │ ├── filesystem
│ │ │ ├── preopens.wit
│ │ │ ├── types.wit
│ │ │ └── world.wit
│ │ ├── http
│ │ │ ├── handler.wit
│ │ │ ├── proxy.wit
│ │ │ └── types.wit
│ │ ├── io
│ │ │ ├── error.wit
│ │ │ ├── poll.wit
│ │ │ ├── streams.wit
│ │ │ └── world.wit
│ │ ├── random
│ │ │ ├── insecure-seed.wit
│ │ │ ├── insecure.wit
│ │ │ ├── random.wit
│ │ │ └── world.wit
│ │ └── sockets
│ │ ├── instance-network.wit
│ │ ├── ip-name-lookup.wit
│ │ ├── network.wit
│ │ ├── tcp-create-socket.wit
│ │ ├── tcp.wit
│ │ ├── udp-create-socket.wit
│ │ ├── udp.wit
│ │ └── world.wit
│ ├── deps.lock
│ ├── deps.toml
│ └── world.wit
└── worlds
└── server
├── import.mbt
├── moon.pkg.json
└── top.mbt
ステップバイステップでやっていく。空の moon リポジトリを作って、 wit を生成する。
wit-deps はcomponent-model の型定義マネージャみたいなもので、TypeScript でいうと dts みたいなものだろうか。
$ moon new cmp
$ cd cmp
$ mkidr wit
定義ファイルを置く。
http = "https://github.com/WebAssembly/wasi-http/archive/v0.2.1.tar.gz"
package moonbit:example;
world server {
export wasi:http/incoming-handler@0.2.1;
}
この状態で $ wit-deps update
すると、wit/deps/*
が生える。
wit/deps
├── cli
│ ├── command.wit
│ ├── environment.wit
│ ├── exit.wit
│ ├── imports.wit
│ ├── run.wit
│ ├── stdio.wit
│ └── terminal.wit
├── clocks
│ ├── monotonic-clock.wit
│ ├── timezone.wit
│ ├── wall-clock.wit
│ └── world.wit
├── filesystem
│ ├── preopens.wit
│ ├── types.wit
│ └── world.wit
├── http
│ ├── handler.wit
│ ├── proxy.wit
│ └── types.wit
├── io
│ ├── error.wit
│ ├── poll.wit
│ ├── streams.wit
│ └── world.wit
├── random
│ ├── insecure-seed.wit
│ ├── insecure.wit
│ ├── random.wit
│ └── world.wit
└── sockets
├── instance-network.wit
├── ip-name-lookup.wit
├── network.wit
├── tcp-create-socket.wit
├── tcp.wit
├── udp-create-socket.wit
├── udp.wit
└── world.wit
```
パッチした wit-bindgen
で このディレクトリ下にファイルを生成する
$ wit-bindgen moonbit --out-dir . wit --derive-show --derive-eq
こんな感じでファイルが生える。
ffi
├── moon.pkg.json
└── top.mbt
gen
├── ffi.mbt
├── interface_exports_wasi_http_incoming_handler_export.mbt
├── moon.pkg.json
└── worlds_server_export.mbt
interface
├── exports
│ └── wasi
│ └── http
│ └── incomingHandler
│ ├── README.md
│ ├── moon.pkg.json
│ └── top.mbt
└── imports
└── wasi
├── clocks
│ └── monotonicClock
│ ├── README.md
│ ├── moon.pkg.json
│ └── top.mbt
├── http
│ └── types
│ ├── README.md
│ ├── moon.pkg.json
│ └── top.mbt
└── io
├── error
│ ├── moon.pkg.json
│ └── top.mbt
├── poll
│ ├── README.md
│ ├── moon.pkg.json
│ └── top.mbt
└── streams
├── README.md
├── moon.pkg.json
└── top.mbt
なので gitignore はこんな感じだろうか。
target/
.mooncakes/
wit/deps/
ffi/
gen/
worlds/
ドキュメントにはこう書いてあるので、ここがエントリポイントになりそう。
Update
interface/exports/wasi/http/incomingHandler/top.mbt
for more functionalities.