Connections and Channels
Scoped peer and channel access through an active capability handle
An avenue handle owns its connections. Normal application code uses three views over that owner:
const cursors = space.state<Cursor>('cursor');
cursors.watch(({ peerId, value }) => updateCursor(peerId, value));
cursors.set(position);
const chat = space.channel<ChatMessage>('chat');
chat.onMessage(({ peerId, message }) => addMessage(peerId, message));
await chat.send(message);
space.onConnection((connection) => {
connection.onMessage((message) => handleCustomMessage(connection.peerId, message));
});
state() is best-effort and coalesces superseded values. channel() is reliable and ordered per peer; send settlement means the local transport accepted the message, not that the remote application completed an effect. Durable chat and product actions still need application message IDs, storage, deduplication, and acknowledgements.
TypeScript generics do not validate network input. Check message fields and bounds before rendering or applying product effects.
In a room joined with architecture: "sparse"—or selected as sparse by the
default "auto" policy—channel().send() uses
bounded multi-hop gossip over four OpenRTC-owned neighbors. Rust verifies the
device-signed envelope before delivery. For sparse broadcasts, the event's
peerId is the authenticated durable device ID, not an Iroh route ID. Sparse
rooms reject state() because abrupt multi-hop publisher loss cannot provide
the direct connection's truthful null transition; use monotonic latest-state
events on a named channel. onConnection() reports physical neighbors, not the
whole room. A non-neighbor sendTo() fails closed because V1 never forwards a
targeted payload through other members. Automatic on-demand direct-route
requests are planned but are not part of the current public API.
onConnection() includes current and future connections without transferring reconnect or route-replacement ownership to the application. The diagnostics namespace and low-level framing primitives under openrtc/runtime remain for debugging and specialized integrations, not normal message handling.