Stream: general

Topic: Importing wasi:* types into my world


view this post on Zulip zslayton (Jul 31 2024 at 23:41):

Hi all! Rookie question here. I'm trying to modify cargo component new's default world.wit file so there's a function that takes a wasi:filesystem InputStream. However, I'm not having any luck with the first step--importing wasi:filesystem (or any other wasi component).

package ion:xl;

/// An example world for the component to target.
world example {
    import wasi:filesystem/filesystem;
    export hello-world: func() -> string;
}

Running cargo component build --release for the above produces:

error: failed to create a target world for package `ionxl` (/Users/zslayton/experiment_wasm/jcotest/ionxl/Cargo.toml)

Caused by:
    0: failed to merge local target `/Users/zslayton/experiment_wasm/jcotest/ionxl/wit`
    1: package not found
            --> /Users/zslayton/experiment_wasm/jcotest/ionxl/wit/world.wit:5:12
             |
           5 |     import wasi:filesystem/filesystem;
             |            ^--------------

I took this to mean that I needed to supply my own copy of the WASI .wit files, so I downloaded them from GitHub and placed them in wit/deps alongside wit/world.wit:

wit
wit/world.wit
wit/deps
wit/deps/sockets
wit/deps/sockets/instance-network.wit
wit/deps/sockets/world.wit
wit/deps/sockets/ip-name-lookup.wit
wit/deps/sockets/tcp-create-socket.wit
wit/deps/sockets/udp.wit
wit/deps/sockets/tcp.wit
wit/deps/sockets/udp-create-socket.wit
wit/deps/sockets/network.wit
wit/deps/clocks
wit/deps/clocks/world.wit
wit/deps/clocks/wall-clock.wit
wit/deps/clocks/monotonic-clock.wit
wit/deps/io
wit/deps/io/world.wit
wit/deps/io/streams.wit
wit/deps/io/error.wit
wit/deps/io/poll.wit
wit/deps/filesystem
wit/deps/filesystem/world.wit
wit/deps/filesystem/preopens.wit
wit/deps/filesystem/types.wit
wit/deps/cli
wit/deps/cli/imports.wit
wit/deps/cli/terminal.wit
wit/deps/cli/stdio.wit
wit/deps/cli/command.wit
wit/deps/cli/exit.wit
wit/deps/cli/run.wit
wit/deps/cli/environment.wit
wit/deps/README.md
wit/deps/http
wit/deps/http/handler.wit
wit/deps/http/proxy.wit
wit/deps/http/types.wit
wit/deps/random
wit/deps/random/world.wit
wit/deps/random/insecure.wit
wit/deps/random/insecure-seed.wit
wit/deps/random/random.wit

This didn't improve things, though. Is there something else I need to do to tell cargo component where to find the wasi:* WITs?

view this post on Zulip zslayton (Aug 01 2024 at 19:19):

Answering my own question: despite several examples I found, it turns out you can't just import something without explicitly stating the version of the import. This works:

world example {
    use wasi:io/streams@0.2.0.{input-stream, output-stream, stream-error};
    export hello-world: func() -> string;
    export count-bytes: func(input: input-stream) -> result<u64, stream-error>;
}

Notice the @0.2.0 in the use statement.

I assume this is a point-in-time limitation, but it took a lot of trial and error to identify a working solution so I wanted to share it.

view this post on Zulip Victor Adossi (Aug 02 2024 at 05:30):

If you ran into any docs that almost helped, but didn't, I'd be happy to try updating them or if you want to update them that'd be great :)

Also Zulip has a "mark as resolved feature" if you're feeling this is fully resolved!

view this post on Zulip zslayton (Aug 11 2024 at 16:33):

Victor Adossi said:

If you ran into any docs that almost helped, but didn't, I'd be happy to try updating them or if you want to update them that'd be great :)

Also Zulip has a "mark as resolved feature" if you're feeling this is fully resolved!

Thanks, Victor! (And apologies for the delayed reply, I've been traveling.)

I seem to have fallen into the natural documentation gap formed by the ecosystem migrating from wasi 0.1 to 0.2 on a variety of timelines. Some things that might've made my journey shorter:

A consolidated arewewasiyet.rs-type page

... that summarizes where the ecosystem is in its development. As a newcomer, I visited several sites trying to get up to speed:

* https://wasi.dev
* https://component-model.bytecodealliance.org/
* https://webassembly.org/getting-started/developers-guide/
* https://github.com/bytecodealliance/cargo-component
* https://github.com/bytecodealliance/wac
It took me a while to realize that many things were still referring to wasi 0.1 concepts like Modules which (I think?) are no longer relevant in wasi 0.2+.

It would have been great to encounter an overview page that told me up front that:

An example that demonstrates dependencies on wasi:* types

More narrowly, I wanted to build a component that took in an input-stream and handed out a resource that processed that input-stream incrementally over the course of many method calls.

The highly-ranked WASI tutorial targets wasi 0.1, and so doesn't demonstrate dependencies.

In the process of writing this up, I noticed the Rust component example does demonstrate an import statement using a version number, but it was subtle enough that I didn't notice it before.

An error message saying I needed a version number

The error messages I was encountering when I left the version number off (reproduced below for ease-of-reference) didn't mention a version number. They also point to the beginning of the name of the package being imported, so I thought it couldn't find the package itself:
error: failed to create a target world for package ionxl (/Users/zslayton/experiment_wasm/jcotest/ionxl/Cargo.toml)

Caused by:
    0: failed to merge local target `/Users/zslayton/experiment_wasm/jcotest/ionxl/wit`
    1: package not found
            --> /Users/zslayton/experiment_wasm/jcotest/ionxl/wit/world.wit:5:12
             |
           5 |     import wasi:filesystem/filesystem;
             |            ^--------------

If you think adding detail to an error message would be an approachable first issue, I'd be happy to give it a shot!

The WebAssembly System Interface (WASI) is a group of standard API specifications for software compiled to the W3C WebAssembly (Wasm) standard. WASI is designed to provide a secure standard interface for applications that can be compiled to Wasm from any language, and that may run anywhere—from browsers to clouds to embedded devices.
A Cargo subcommand for creating WebAssembly components based on the component model proposal. - bytecodealliance/cargo-component
WebAssembly Composition (WAC) tooling. Contribute to bytecodealliance/wac development by creating an account on GitHub.
A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.
Modules and components

Last updated: Dec 23 2024 at 12:05 UTC