Open8

moonbit component model

mizchimizchi

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 らしいがこれなんだろう?あとで調べる。
https://wasmcloud.com/docs/installation?os=mac

mizchimizchi
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%                  ```                  
mizchimizchi

wasmcloud 自体を調べないといけなくなった。nats-server というのが必要らしい。

https://dev.classmethod.jp/articles/wasm-wasmcloud/
https://wasmcloud.com/docs/tour/hello-world

とりあえず 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 となってるのがマズそう

mizchimizchi

一旦 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 で疎通せず。

mizchimizchi

うーん、wasm cloud のことは後で調べよう。今回の本筋じゃないし。

mizchimizchi

必要なのはこれ

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
mizchimizchi

wasi-http を見る

https://github.com/moonbitlang/moonbit-docs/tree/main/examples/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

定義ファイルを置く。

wit/deps.toml
http = "https://github.com/WebAssembly/wasi-http/archive/v0.2.1.tar.gz"
wit/world.wit
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
    ```
mizchimizchi

パッチした 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.