Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Build a plugin

The initial SDK targets Rust and WASI 0.2 components. Install the component target:

rustup target add wasm32-wasip2

The reference implementation uses Rust 1.98. Plugin source can use compatible Rust releases, but its generated component must satisfy the supported WIT API. Native subprocess, OS-specific and unrestricted networking crates are not automatically available inside a component.

Start with the SDK

The SDK lives at plugin_system/sdk in the Memona repository. Until a crates.io release is published, use a checked-out, pinned Memona revision and a path dependency:

[package]
name = "my-memona-plugin"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"]

[dependencies]
memona-plugin-sdk = { path = "../memona/plugin_system/sdk" }

The path is relative to your own Cargo.toml; adjust it to your checkout. Pin the checkout revision so your build does not silently pick up an API change.

The SDK includes the canonical WIT and generated Rust types. Implement its Guest trait and invoke its export! macro for your implementation type. You do not need wasm-bindgen, wasm-pack, or WIT copies in your plugin repository. cargo doc also exposes the generated Rust API.

struct MyProvider;

// Implement every method of memona_plugin_sdk::Guest for MyProvider.
// Unsupported optional operations return ErrorCode::Unsupported.
memona_plugin_sdk::export!(MyProvider);

This short excerpt shows registration, not a complete implementation. The full buildable example is plugin_system/test-component/src/lib.rs. It is a test fixture, not a WebDAV or IPFS client. From a Memona checkout, build it with:

cargo build --manifest-path plugin_system/Cargo.toml \
  -p memona-plugin-test-component --target wasm32-wasip2 --release

Build your own plugin with:

cargo build --release --target wasm32-wasip2

Call the host

Use the SDK’s generated host interface for network requests. For example, this helper retrieves a bounded HTTP response through the connection’s permissions:

use memona_plugin_sdk::memona::filesystem::host;

pub fn get_bytes(url: &str) -> Result<Vec<u8>, host::HostError> {
    let response = host::http(&host::Request {
        method: "GET".into(),
        url: url.into(),
        headers: Vec::new(),
        body: Vec::new(),
    })?;
    if !(200..300).contains(&response.status) {
        return Err(host::HostError::Unavailable);
    }
    Ok(response.body)
}

Map HTTP statuses to appropriate filesystem errors in a real provider. Supply authentication through request headers using connection configuration; do not hard-code tokens. The host checks exact destinations and private-network permission and limits request/response bodies to 4 MiB. Reads exported by the filesystem provider have the smaller 1 MiB transfer limit.

Prepare a release

Copy the resulting .wasm component to plugin.wasm, write manifest.json, and ZIP the files at the archive root. Name the archive with a .memona-plugin suffix. A directory wrapping the files inside the ZIP is not accepted.

Use the filesystem behavior guide to handle revisions, unsupported operations and mutation failures correctly. Before publishing, exercise your provider against its real service and test lost connections.