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 { /// 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. type resource-id = u64; /// One occurrence of a previously registered and armed timer. record timer-fired { timer-id: resource-id, /// Driver monotonic deadline in nanoseconds, not wall-clock time. scheduled-at-ns: u64, } /// A stream accepted by a previously registered TCP or Unix endpoint. record stream-opened { endpoint-id: resource-id, stream-id: resource-id, /// Driver-formatted peer address when the transport provides one. peer: option, } /// One bounded read chunk. Chunk boundaries are not message boundaries. record stream-chunk { stream-id: resource-id, bytes: list, } /// Terminal reason reported by the Host driver. enum close-reason { /// The peer closed the transport normally. peer-closed, /// The platform or Component requested closure. host-closed, /// The configured inactivity deadline elapsed. idle-timeout, /// Protocol validation failed above the transport layer. protocol-error, /// The operating-system transport returned an error. transport-error, } /// Final event for a stream identity. record stream-closed { stream-id: resource-id, reason: close-reason, } /// One UDP datagram. A datagram is never split across events. record datagram { endpoint-id: resource-id, peer: string, bytes: list, } /// One delivery from a Host-owned broker or internal queue. record message { subscription-id: resource-id, message-id: u64, bytes: list, } /// 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, } variant event { /// A registered timer reached its monotonic deadline. timer(timer-fired), /// A Host driver accepted a new stream. stream-opened(stream-opened), /// A stream produced one bounded read chunk. stream-data(stream-chunk), /// The driver can accept writes after previous backpressure. stream-writable(resource-id), /// The peer closed its write half; local writes may still be valid. stream-half-closed(resource-id), /// The stream is terminal and its identity will be released. stream-closed(stream-closed), /// A UDP endpoint received one datagram. datagram(datagram), /// A subscription delivered one message. message(message), /// A separately versioned extension source produced an event. source(source-event), /// The session is stopping. No later events will be delivered. shutdown, } /// Request to enqueue bytes for a stream driver. record stream-write { stream-id: resource-id, bytes: list, } /// Request to send one datagram through a registered UDP endpoint. record datagram-send { endpoint-id: resource-id, peer: string, bytes: list, } /// Request to arm or replace a registered timer schedule. record timer-arm { timer-id: resource-id, /// Delay from operation application, in milliseconds. delay-ms: u64, /// Optional repeating interval in milliseconds. interval-ms: option, } /// Request to acknowledge a previously delivered message. record message-ack { subscription-id: resource-id, message-id: u64, } /// Driver-specific command for a separately versioned extension source. record source-command { source-id: resource-id, command: string, payload: list, } /// 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. variant effect { /// Enqueue bytes for an open stream. write-stream(stream-write), /// Begin closing an open stream. close-stream(resource-id), /// Stop delivering new read data until resumed. pause-stream(resource-id), /// Resume delivery after a matching pause. resume-stream(resource-id), /// Send one UDP datagram. send-datagram(datagram-send), /// Arm or replace one timer. arm-timer(timer-arm), /// Disarm one timer; its identity remains registered. cancel-timer(resource-id), /// Acknowledge one broker or queue message. acknowledge-message(message-ack), /// Forward an extension-specific command. source-command(source-command), } /// Expected Component failure while processing a resident event. variant resident-error { event-failed(string), } /// 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. handle-event: func(input: event) -> result, resident-error>; } /// 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. world resident-component { export actor; }