docs(wit): document capability and component contracts
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
//! Example service that imports the versioned Wasmeld monotonic-clock capability.
|
||||
//!
|
||||
//! Each response is eight little-endian timestamp bytes followed by the input.
|
||||
//! The timestamp is Actor-local monotonic time, not a Unix timestamp.
|
||||
|
||||
mod bindings {
|
||||
// This macro generates Rust ABI adapters at compile time from the
|
||||
// materialized local WIT graph. It does not make a remote protocol call or
|
||||
// embed the WIT source files; the Component carries canonical ABI types.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "clock-probe-component",
|
||||
|
||||
@@ -4,12 +4,12 @@ schema_version = 1
|
||||
name = "wasmeld:clock"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/clock"
|
||||
sha256 = "93079c69d1b9cb3afc28da6fe4a7e37f724d0a09e780c847f8524d3920a90960"
|
||||
sha256 = "43ece485a550eca94cf06cb711f0b42c9f4977d275e9a042c3ac84eeb1f941e1"
|
||||
replaced = true
|
||||
|
||||
[[package]]
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package component:clock-probe@0.1.0;
|
||||
|
||||
/// Base service exports plus the exact monotonic-clock Host capability used by
|
||||
/// this Component. Other Wasmeld capabilities are not linked implicitly.
|
||||
world clock-probe-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
import wasmeld:clock/monotonic-clock@0.1.0;
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
//! Minimal stateful Component used to demonstrate a warm Actor Store.
|
||||
//!
|
||||
//! Invoke returns an eight-byte little-endian counter. The value survives
|
||||
//! calls to the same Actor but resets on `init`, restart, or process recovery.
|
||||
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
mod bindings {
|
||||
// Bindings are generated from `wit/world.wit` plus materialized
|
||||
// `wit/deps`; WIT is a compile-time ABI contract, not downloaded at run
|
||||
// time and not executed as code.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "counter-component",
|
||||
|
||||
@@ -4,5 +4,5 @@ schema_version = 1
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package component:counter@0.1.0;
|
||||
|
||||
/// Counter only needs the base service lifecycle and imports no Host capability.
|
||||
world counter-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
//! Smallest request/response Component example: it returns input bytes unchanged.
|
||||
|
||||
mod bindings {
|
||||
// Generate the guest trait and export adapter from the selected WIT world.
|
||||
// Dependency sync must populate `wit/deps` before this macro is compiled.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "echo-component",
|
||||
|
||||
@@ -4,5 +4,5 @@ schema_version = 1
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package component:echo@0.1.0;
|
||||
|
||||
/// Echo only needs the base service lifecycle and imports no Host capability.
|
||||
world echo-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
//! Deliberately trapping Component used to verify Actor fault isolation.
|
||||
//!
|
||||
//! Sending the exact bytes `fault` triggers a panic. This crate is a test
|
||||
//! fixture and must not be deployed as an application service.
|
||||
|
||||
mod bindings {
|
||||
// Compile the versioned WIT world into canonical ABI Rust bindings.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "fault-component",
|
||||
@@ -13,6 +19,8 @@ impl bindings::Guest for Fault {
|
||||
}
|
||||
|
||||
fn invoke(input: Vec<u8>) -> Result<Vec<u8>, bindings::ServiceError> {
|
||||
// A panic becomes a Wasm trap so Runtime tests can assert that one
|
||||
// faulted Actor does not corrupt other service instances.
|
||||
assert_ne!(input, b"fault", "intentional test fault");
|
||||
Ok(input)
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ schema_version = 1
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package component:fault@0.1.0;
|
||||
|
||||
/// Fault fixture exports only the base service lifecycle.
|
||||
world fault-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
//! Example service that exercises persistent, service-scoped Host KV.
|
||||
//!
|
||||
//! Input uses the test protocol `get:<key>`, `set:<key>:<value>`, or
|
||||
//! `delete:<key>`. Production Components should define an application-specific
|
||||
//! request format instead of copying this colon-delimited probe protocol.
|
||||
|
||||
mod bindings {
|
||||
// `generate_all` emits both the service export and imported KV module from
|
||||
// the exact versions selected in `wit/world.wit`.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "kv-probe-component",
|
||||
|
||||
@@ -4,12 +4,12 @@ schema_version = 1
|
||||
name = "wasmeld:kv"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/kv"
|
||||
sha256 = "6dc3a84dc03c7104aa8b305518466c95e4440e1031c4bef3b59843f40f24d0fb"
|
||||
sha256 = "10dc81b1f04bd9c8f7b324a96e0c1d24d5af0c2dabfc723d003b8729cfd933d9"
|
||||
replaced = true
|
||||
|
||||
[[package]]
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package component:kv-probe@0.1.0;
|
||||
|
||||
/// Base service exports plus the exact persistent KV Host capability used by
|
||||
/// this Component.
|
||||
world kv-probe-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
import wasmeld:kv/store@0.1.0;
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
//! Resident event/effect fixture covering every current Host-driven I/O family.
|
||||
//!
|
||||
//! The callback echoes stream chunks and datagrams, rearms fired timers,
|
||||
//! acknowledges messages, and reflects extension commands. It owns no socket,
|
||||
//! timer, or subscription handles; those resources remain in the Host driver.
|
||||
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
mod bindings {
|
||||
// One generated module contains both the base service export and resident
|
||||
// actor export because this component world composes both WIT packages.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "resident-probe-component",
|
||||
@@ -35,6 +43,8 @@ impl ResidentGuest for ResidentProbe {
|
||||
fn handle_event(
|
||||
input: Event,
|
||||
) -> Result<Vec<Effect>, bindings::exports::wasmeld::resident::actor::ResidentError> {
|
||||
// Event callbacks are serialized with normal invocations by the same
|
||||
// Actor mailbox, so this in-memory count is deterministic per Actor.
|
||||
EVENTS_HANDLED.fetch_add(1, Ordering::Relaxed);
|
||||
Ok(match input {
|
||||
Event::StreamData(chunk) => vec![Effect::WriteStream(StreamWrite {
|
||||
|
||||
@@ -4,12 +4,12 @@ schema_version = 1
|
||||
name = "wasmeld:resident"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/resident"
|
||||
sha256 = "683a3c7196a6dd77b3f619227aa093430ff6995c097d39bb82d501b7c59a196c"
|
||||
sha256 = "a13728b0e6f000c03eb0f88e2e54bad1c6e5160ac3ca4b9e87619247c0043d1b"
|
||||
replaced = true
|
||||
|
||||
[[package]]
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package component:resident-probe@0.1.0;
|
||||
|
||||
/// Composes ordinary request/response exports with the optional resident actor
|
||||
/// export. Network and timer drivers remain Host-owned.
|
||||
world resident-probe-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
export wasmeld:resident/actor@0.1.0;
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
//! CPU-bound fixture used to verify fuel and epoch deadline interruption.
|
||||
//!
|
||||
//! The input's first eight bytes select a little-endian iteration count.
|
||||
//! Initializing with `spin` intentionally runs without a finite loop bound.
|
||||
//! This crate is a Runtime test fixture, not an application service.
|
||||
|
||||
mod bindings {
|
||||
// Compile the base service WIT contract into guest and export adapters.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "spin-component",
|
||||
|
||||
@@ -4,5 +4,5 @@ schema_version = 1
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package component:spin@0.1.0;
|
||||
|
||||
/// Spin fixture exports only the base service lifecycle.
|
||||
world spin-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
//! Fixture proving that ambient WASI clock imports are denied by the sandbox.
|
||||
//!
|
||||
//! Calling `std::time::Instant::now` causes this Component to import WASI
|
||||
//! monotonic-clock directly. Wasmeld only links explicitly approved capability
|
||||
//! packages, so registration or startup must reject this fixture.
|
||||
|
||||
mod bindings {
|
||||
// The declared service WIT contains no WASI clock capability; the direct
|
||||
// standard-library use below deliberately creates an undeclared import.
|
||||
wit_bindgen::generate!({
|
||||
path: "wit",
|
||||
world: "wasi-clock-probe-component",
|
||||
|
||||
@@ -4,5 +4,5 @@ schema_version = 1
|
||||
name = "wasmeld:service"
|
||||
version = "0.1.0"
|
||||
source = "path+../../wit/service"
|
||||
sha256 = "d5497307bbcd1e159f7707f385b488a6f2e26362d5256d5bc1080ac603a51305"
|
||||
sha256 = "1b2069606ccbf5202789667570bc824f702f34b147aa38e81c2ab677444ffa0e"
|
||||
replaced = true
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package component:wasi-clock-probe@0.1.0;
|
||||
|
||||
/// The declared world grants only the base service contract. Any direct WASI
|
||||
/// clock import introduced by implementation code remains undeclared.
|
||||
world wasi-clock-probe-component {
|
||||
include wasmeld:service/service-component@0.1.0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user