2026-07-30 07:40:02 +08:00
|
|
|
package wasmeld:resident@0.1.0;
|
|
|
|
|
|
|
|
|
|
/// Event/effect ABI for Components that remain active without monopolizing
|
|
|
|
|
/// their Actor thread. The Host owns timers, subscriptions, sockets, streams,
|
|
|
|
|
/// and all operating-system handles. A Component handles one bounded event and
|
|
|
|
|
/// returns effects before control goes back to the Runtime.
|
|
|
|
|
interface actor {
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Opaque, nonzero identity allocated by the Host for one resident session.
|
|
|
|
|
///
|
|
|
|
|
/// IDs are scoped to one service revision and session. They are never OS
|
|
|
|
|
/// handles, must not be guessed, and become invalid after Host release.
|
2026-07-30 07:40:02 +08:00
|
|
|
type resource-id = u64;
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// One occurrence of a previously registered and armed timer.
|
2026-07-30 07:40:02 +08:00
|
|
|
record timer-fired {
|
|
|
|
|
timer-id: resource-id,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Driver monotonic deadline in nanoseconds, not wall-clock time.
|
2026-07-30 07:40:02 +08:00
|
|
|
scheduled-at-ns: u64,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A stream accepted by a previously registered TCP or Unix endpoint.
|
2026-07-30 07:40:02 +08:00
|
|
|
record stream-opened {
|
|
|
|
|
endpoint-id: resource-id,
|
|
|
|
|
stream-id: resource-id,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Driver-formatted peer address when the transport provides one.
|
2026-07-30 07:40:02 +08:00
|
|
|
peer: option<string>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// One bounded read chunk. Chunk boundaries are not message boundaries.
|
2026-07-30 07:40:02 +08:00
|
|
|
record stream-chunk {
|
|
|
|
|
stream-id: resource-id,
|
|
|
|
|
bytes: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Terminal reason reported by the Host driver.
|
2026-07-30 07:40:02 +08:00
|
|
|
enum close-reason {
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The peer closed the transport normally.
|
2026-07-30 07:40:02 +08:00
|
|
|
peer-closed,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The platform or Component requested closure.
|
2026-07-30 07:40:02 +08:00
|
|
|
host-closed,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The configured inactivity deadline elapsed.
|
2026-07-30 07:40:02 +08:00
|
|
|
idle-timeout,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Protocol validation failed above the transport layer.
|
2026-07-30 07:40:02 +08:00
|
|
|
protocol-error,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The operating-system transport returned an error.
|
2026-07-30 07:40:02 +08:00
|
|
|
transport-error,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Final event for a stream identity.
|
2026-07-30 07:40:02 +08:00
|
|
|
record stream-closed {
|
|
|
|
|
stream-id: resource-id,
|
|
|
|
|
reason: close-reason,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// One UDP datagram. A datagram is never split across events.
|
2026-07-30 07:40:02 +08:00
|
|
|
record datagram {
|
|
|
|
|
endpoint-id: resource-id,
|
|
|
|
|
peer: string,
|
|
|
|
|
bytes: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// One delivery from a Host-owned broker or internal queue.
|
2026-07-30 07:40:02 +08:00
|
|
|
record message {
|
|
|
|
|
subscription-id: resource-id,
|
|
|
|
|
message-id: u64,
|
|
|
|
|
bytes: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Escape hatch for Host-owned event sources such as filesystem watchers,
|
|
|
|
|
/// serial devices, process signals, or platform-specific buses. `kind` and
|
|
|
|
|
/// `payload` are interpreted by the separately versioned Host capability
|
|
|
|
|
/// that created `source-id`.
|
|
|
|
|
record source-event {
|
|
|
|
|
source-id: resource-id,
|
|
|
|
|
kind: string,
|
|
|
|
|
payload: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
variant event {
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A registered timer reached its monotonic deadline.
|
2026-07-30 07:40:02 +08:00
|
|
|
timer(timer-fired),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A Host driver accepted a new stream.
|
2026-07-30 07:40:02 +08:00
|
|
|
stream-opened(stream-opened),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A stream produced one bounded read chunk.
|
2026-07-30 07:40:02 +08:00
|
|
|
stream-data(stream-chunk),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The driver can accept writes after previous backpressure.
|
2026-07-30 07:40:02 +08:00
|
|
|
stream-writable(resource-id),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The peer closed its write half; local writes may still be valid.
|
2026-07-30 07:40:02 +08:00
|
|
|
stream-half-closed(resource-id),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The stream is terminal and its identity will be released.
|
2026-07-30 07:40:02 +08:00
|
|
|
stream-closed(stream-closed),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A UDP endpoint received one datagram.
|
2026-07-30 07:40:02 +08:00
|
|
|
datagram(datagram),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A subscription delivered one message.
|
2026-07-30 07:40:02 +08:00
|
|
|
message(message),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// A separately versioned extension source produced an event.
|
2026-07-30 07:40:02 +08:00
|
|
|
source(source-event),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// The session is stopping. No later events will be delivered.
|
2026-07-30 07:40:02 +08:00
|
|
|
shutdown,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Request to enqueue bytes for a stream driver.
|
2026-07-30 07:40:02 +08:00
|
|
|
record stream-write {
|
|
|
|
|
stream-id: resource-id,
|
|
|
|
|
bytes: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Request to send one datagram through a registered UDP endpoint.
|
2026-07-30 07:40:02 +08:00
|
|
|
record datagram-send {
|
|
|
|
|
endpoint-id: resource-id,
|
|
|
|
|
peer: string,
|
|
|
|
|
bytes: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Request to arm or replace a registered timer schedule.
|
2026-07-30 07:40:02 +08:00
|
|
|
record timer-arm {
|
|
|
|
|
timer-id: resource-id,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Delay from operation application, in milliseconds.
|
2026-07-30 07:40:02 +08:00
|
|
|
delay-ms: u64,
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Optional repeating interval in milliseconds.
|
2026-07-30 07:40:02 +08:00
|
|
|
interval-ms: option<u64>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Request to acknowledge a previously delivered message.
|
2026-07-30 07:40:02 +08:00
|
|
|
record message-ack {
|
|
|
|
|
subscription-id: resource-id,
|
|
|
|
|
message-id: u64,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Driver-specific command for a separately versioned extension source.
|
2026-07-30 07:40:02 +08:00
|
|
|
record source-command {
|
|
|
|
|
source-id: resource-id,
|
|
|
|
|
command: string,
|
|
|
|
|
payload: list<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Host operations requested after handling one event.
|
|
|
|
|
///
|
|
|
|
|
/// Effects are declarations, not completed I/O. The Host validates the
|
|
|
|
|
/// entire returned list before applying any item, then the external driver
|
|
|
|
|
/// performs the operations in order.
|
2026-07-30 07:40:02 +08:00
|
|
|
variant effect {
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Enqueue bytes for an open stream.
|
2026-07-30 07:40:02 +08:00
|
|
|
write-stream(stream-write),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Begin closing an open stream.
|
2026-07-30 07:40:02 +08:00
|
|
|
close-stream(resource-id),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Stop delivering new read data until resumed.
|
2026-07-30 07:40:02 +08:00
|
|
|
pause-stream(resource-id),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Resume delivery after a matching pause.
|
2026-07-30 07:40:02 +08:00
|
|
|
resume-stream(resource-id),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Send one UDP datagram.
|
2026-07-30 07:40:02 +08:00
|
|
|
send-datagram(datagram-send),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Arm or replace one timer.
|
2026-07-30 07:40:02 +08:00
|
|
|
arm-timer(timer-arm),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Disarm one timer; its identity remains registered.
|
2026-07-30 07:40:02 +08:00
|
|
|
cancel-timer(resource-id),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Acknowledge one broker or queue message.
|
2026-07-30 07:40:02 +08:00
|
|
|
acknowledge-message(message-ack),
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Forward an extension-specific command.
|
2026-07-30 07:40:02 +08:00
|
|
|
source-command(source-command),
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Expected Component failure while processing a resident event.
|
2026-07-30 07:40:02 +08:00
|
|
|
variant resident-error {
|
|
|
|
|
event-failed(string),
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Handles exactly one serialized, bounded event.
|
|
|
|
|
///
|
|
|
|
|
/// This callback must not run an internal infinite loop or block on network
|
|
|
|
|
/// I/O. Update Component state, return requested effects, and let the Host
|
|
|
|
|
/// wait for the next external event. A trap faults the Actor; `event-failed`
|
|
|
|
|
/// reports an application error without changing the ABI.
|
2026-07-30 07:40:02 +08:00
|
|
|
handle-event: func(input: event) -> result<list<effect>, resident-error>;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 08:13:24 +08:00
|
|
|
/// Optional export world for Components that need long-lived Host-driven I/O.
|
|
|
|
|
///
|
|
|
|
|
/// A Component may compose this package with `wasmeld:service` and only the
|
|
|
|
|
/// capability packages it actually imports.
|
2026-07-30 07:40:02 +08:00
|
|
|
world resident-component {
|
|
|
|
|
export actor;
|
|
|
|
|
}
|