I noticed that the WIT format allows for a package name with a version. Is it possible to define multiple versions at once, and allow them to both function at the same time?
Initially I was thinking that I would store the expected "api version" alongside the binary, and then, based on that, decide which wit file to use (named things like apiv1.wit
, apiv2.wit
, etc.). But if I'm able to avoid that by using package versions, that would be nice.
The problem is, I'm struggling to find much info on it. Any direction on this would be appreciated.
Yes, multiple versions of the same package are allowed. You'll need to split them across folders, though, as each package has a single logical version and packages are defined in the same directory right now, so you'd need something like deps/v1/myapi.wit
and deps/v2/myapi.wit
is it possible to combine this with wasmtime::component::bindgen!()? I want to detect the version expected by a wasm binary and then use the correct apis, if possible
yes, you'll get a trait-per-version to implement and corresponding add_to_linker
functions
Awesome. One last question, if the host system has v1.1.0, but the guest code uses a previous 1.0.0, will it still work? Like, if I make changes to the API that are backward-compatible, is it ok if the versions don't match exactly (like minor/patch bumps)? Or do I need to keep every specific version until I'm ready to deprecate/remove it?
With this PR, yes, but that PR isn't in 18.0.2, it'll be in 19.0.0
Got it, thanks. Is there any roadmap, or release schedule, for 19.0.0 that you're aware of?
you can read about the release process here, and the answer you're looking for is "March 20"
I'm struggling to get this to work with wasmtime bindgen. I've tried this:
wit/deps/
v0/
api.wit
v1/
api.wit
bindgen!()
But it just errors out:
error: failed to parse package: /Users/circuitsacul/src/wasmbot/wasmbot/app/runtime/wit
Caused by:
no `package` header was found in any WIT file for this package
Both the api.wit files have a package header (one is @0.1.0, the other is @1.0.0). I also tried adding another top-level wit file and use
ing the api package, but it couldn't find the package by name.
What does work is using bindgen!()
and referring to the path specifically, but I can't do that for two versions of the same package because the generated code would conflict (in particular, the struct name and the package:name).
What am I doing wrong here?
Ok I think I have a solution. I'll see if it actually works later when I try to run some wasm, but this is what I did:
wit/
v0/api.wit (@0.1.0)
v1/api.wit (@1.0.0)
mod v0 {
use wasmtime::component::bindgen;
bindgen!({
path: "wit/v0",
async: true
});
}
mod v1 {
use wasmtime::component::bindgen;
bindgen!({
path: "wit/v1",
async: true
});
}
struct State;
impl v0::wasmbot::api::host::Host for State {}
impl v1::wasmbot::api::host::Host for State {}
Now I just need to figure out how to determine which bindings to use. I suspect that v0::Api::instantiate_async
will return an error if the guest package is using a newer version of the api? Or should I just store the expected package version separately?
Oh that works as well, yeah, but the first error is that, for now at least, you need at least a dummy *.wit
file in the "root" folder as wit/$something.wit
, and then the deps
folder will get read
I get the same error doing that. Does something special need to be written in the dummy wit file?
# wit/deps/v0/api.wit
package wasmbot:api@0.1.0;
world api {
import host: interface {}
export guest: interface {
on-deploy: func();
on-ws-msg: func();
on-timer: func();
}
}
# wit/dummy.wit (empty)
bindgen!({ async: true });
error: failed to parse package: /Users/circuitsacul/src/wasmbot/wasmbot/app/runtime/wit
Caused by:
no `package` header was found in any WIT file for this package
ah yeah, sorry, you'll need at least a dummy package foo:bar;
in the dummy.wit
f ile
(we hope to lift these restrictions one day)
Doing that gives this error
error: no worlds found in package `dummy:dummy`
Trying bindgen!({world: "api"})
just says that the world "api" doesn't exist in this package
I think it's fine though, my method worked and I don't see any big downsides to that approach
ah yes, for that you'd specify world: "wasmbot:api/api@0.1.0"
but yeah if the other approach works for you no need to switch
Last updated: Dec 23 2024 at 13:07 UTC