WASI preview 2 plugins use Wasm components and require a WIT file to define the interface.
Steps:
- Configure
Cargo.toml with javy-plugin-api = "5.0.0" and wit-bindgen = "0.47.0". - Create a
wit/world.wit file defining your exports (e.g., compile-src, initialize-runtime, invoke) and any necessary imports. - Use the
javy_plugin! macro in src/lib.rs to implement the plugin logic, or implement the Guest trait directly if avoiding the macro. - Build using
cargo build --target=wasm32-wasip2 --release. - Initialize the plugin for the Javy CLI using:
javy init-plugin <path_to_plugin> -o <path_to_initialized_module>
Note: Because components are converted to modules, parameter and result types are lowered to core Wasm equivalents. Use cabi_realloc for structured data like strings or arrays.
[package]
name = "my-plugin-name"
version = "0.1.0"
[lib]
name = "my_plugin_name"
crate-type = ["cdylib"]
[dependencies]
javy-plugin-api = "5.0.0"
wit-bindgen = "0.47.0"
package yournamespace:my-javy-plugin@1.0.0;
world my-javy-plugin {
export compile-src: func(src: list<u8>) -> result<list<u8>, string>;
export initialize-runtime: func();
export invoke: func(bytecode: list<u8>, function: option<string>);
}
use javy_plugin_api::{
javy::{quickjs::prelude::Func, Runtime},
javy_plugin,
Config,
};
wit_bindgen::generate!({ world: "my-javy-plugin", generate_all });
fn config() -> Config {
Config::default()
}
fn modify_runtime(runtime: Runtime) -> Runtime {
runtime.context().with(|ctx| {
// Creates a `plugin` variable on the global set to `true`.
ctx.globals().set("plugin", true).unwrap();
ctx.globals()
.set(
"func",
Func::from(|| {
crate::imported_function();
}),
)
.unwrap();
});
runtime
}
struct Component;
// Set your plugin's import namespace.
javy_plugin!("my-javy-plugin", Component, config, modify_runtime);
export!(Component);