TL;DR
- Warg でログインし、WIT パッケージと WebAssembly Component をレジストリ wa.dev に登録する。
- 登録した Component を wac で CLI アプリケーションと合成し、Wasmtime で実行する。
内容
CLI から wa.dev に接続する
クライアントツールから wa.dev を使うには、wa.dev に公開鍵を登録する必要がある。ヘッダの「Setup new CLI」に手順が表示されるので、それに従う。
warg login --registry warg.wa.devを実行し、wa.dev に表示されたトークンを入力する。公開鍵が生成されて表示される- 生成された公開鍵を wa.dev に貼り付ける
- 「Create credentials」をクリックする
warg でログインすれば、ログイン状態やパッケージのキャッシュなどは wkg や cargo-component にも共有される。別々にログインする必要はない。
WIT パッケージをレジストリに登録する
wit ディレクトリを作り、登録する WIT ファイルを書く。
package radish:glitch-art;
interface png-glitchable {
enum filter-type {
none,
sub,
up,
average,
paeth
}
record scan-line {
filter-type: filter-type,
pixel-data: list<u8>
}
glitch: func(scan-line: scan-line) -> scan-line;
}
world png-glitcher {
export png-glitchable;
}
world png-glitcher-cli {
import png-glitchable;
}wkg wit build を実行すると文法をチェックし、エラーがなければ WIT パッケージの Wasm ファイルと wkg.lock を生成する。
登録には、wa.dev の Web 画面でパッケージを作成したときに表示される warg publish release コマンドを使う。レジストリはパッケージをセマンティックバージョニングで管理しており、--version でバージョンを指定する。
wkg wit build
warg publish release --name radish:glitch-art --version 0.0.1 radish:glitch-art.wasm登録した WIT を実装する Component
cargo-component で、レジストリ上の World を対象にしたプロジェクトを作る。
cargo component new \
--lib \
--target radish:glitch-art/[email protected] \
--namespace radish \
first-glitch-artこのとき、wkg のデフォルトレジストリに wa.dev を設定しておかないと no registry configured for namespace "radish" というエラーになる(wasm-pkg-tools の README)。
wkg config --default-registry wa.dev生成された src/lib.rs で、png-glitchable インタフェースの glitch 関数を実装する。ここでは、スキャンラインの先頭の画素をランダムな値に置き換える。
impl Guest for Component {
fn glitch(mut scan_line: ScanLine) -> ScanLine {
let mut rng = rand::thread_rng();
scan_line.pixel_data[0] = rng.gen_range(0..=255);
scan_line
}
}cargo component build -r でビルドし、WIT パッケージと同じく warg publish release で wa.dev に登録する(https://wa.dev/radish:first-glitch-art)。
登録した Component を使う CLI
png-glitcher-cli World を実装する CLI アプリケーション png-glitch-cli を作る。cargo new でプロジェクトを作り、clap、anyhow、png-glitch などのクレートを追加する。先ほどの wit ディレクトリ、wkg.lock、WIT パッケージの Wasm ファイルをプロジェクト内に移し、Cargo.toml に実装する World を書く。
[package.metadata.component]
package = "radish:png-glitch-cli"
target = "radish:glitch-art/[email protected]"bindings モジュールは World の定義から生成するので、ビルドには cargo component build を使う。src/main.rs では、png-glitch クレートの FilterType と WIT で定義した FilterType を相互に変換するため、両方向に From トレイトを実装する。そのうえで、画像のスキャンラインごとに import した glitch 関数を呼び出し、結果を書き戻す。
cargo component build -r でビルドすると Component ができるが、glitch の実装を持っていないので、そのままでは実行できない。そこで、wa.dev に登録した radish:first-glitch-art と wac で合成する(第5章)。--plug には、レジストリに登録した Component を指定できる。
wac plug \
--plug radish:first-glitch-art \
target/wasm32-wasip1/release/png-glitch-cli.wasm \
-o first-glitch.wasmWasmtime で実行する。--dir で、Component がアクセスできるディレクトリを指定する。ここではカレントディレクトリへのアクセスを許可している。
wasmtime --dir=./ first-glitch.wasm original.pngキーワード
自分の理解
WIT パッケージの登録では、最初に wkg publish を試してつまずいた。まず component package version not found というエラーになり、issue のコメントから、パッケージ名にバージョン(package radish:[email protected];)が必要だと分かった。次は no registry configured for namespace "radish" と言われた。wa.dev を探しに行ってくれるものだと思っていたが、原因は wkg のデフォルトレジストリを設定していなかったことだった。README の一番上に書いてあった。結局、wa.dev の画面に表示された warg publish release を使って登録できた。