com um clique
iii-stream
Durable real-time streams with a CRUD function surface plus reactive triggers that fire on item changes and WebSocket subscriber lifecycle — reach for it to build live backends without polling.
Menu
Durable real-time streams with a CRUD function surface plus reactive triggers that fire on item changes and WebSocket subscriber lifecycle — reach for it to build live backends without polling.
WebSocket-routed worker mesh — the engine's Function/Trigger/Worker model and the iii-sdk surface for authoring them. Teaches the ordered way to gain a capability before writing code — (1) check functions already registered in the engine, (2) search the public registry via iii-directory, (3) build a worker. Single self-contained skill — meant for system-prompt injection; do not re-fetch.
Expose registered functions as HTTP endpoints via an `http` trigger, with a preHandler middleware chain for auth, rate limiting, and logging. Reach for it to serve REST without standing up a separate web server.
Ephemeral microVM sandboxes for running untrusted or agent-generated code in isolation — a one-call run path, a create/exec/stop lifecycle, and a set of filesystem operations.
Connect this engine to another iii engine over a long-lived WebSocket so functions call across the boundary. Wire stable ids with `forward:`/`expose:`; `bridge.invoke` is the ad-hoc escape hatch.
Schedule any registered function on a 6- or 7-field cron expression, with once-only execution across a fleet when backed by the redis adapter. Its whole surface is the `cron` trigger type.
OpenTelemetry-backed tracing, structured logs, metrics with rollups, alerts, sampling, and baggage for the engine — emit and query telemetry through `engine::*` functions and react to logs with a `log` trigger.
| name | iii-stream |
| description | Durable real-time streams with a CRUD function surface plus reactive triggers that fire on item changes and WebSocket subscriber lifecycle — reach for it to build live backends without polling. |
The iii-stream worker stores real-time data as a three-level hierarchy (stream_name -> group_id -> item_id) in the configured adapter and exposes two surfaces: a CRUD-shaped stream::* function namespace for reading and writing items, and reactive trigger types (stream, stream:join, stream:leave) that fire on data changes and on WebSocket subscriber connect/disconnect. Reactive backends are built by binding handlers to those triggers rather than by polling.
A write persists the new value, dispatches matching stream triggers on a spawned task (fire-and-forget, so the originating call returns before handlers finish), and broadcasts the change to every WebSocket client subscribed to that (stream_name, group_id). The stream:join trigger doubles as an authorization gate: returning { unauthorized: true } from its handler rejects the subscription before any data flows. Pair it with the worker's auth_function config, which runs once per WebSocket handshake and stamps a context value into every join/leave event.
Adapters: kv (default; in-memory or file-backed; single-instance only, no cross-process fan-out) or redis (required for multi-instance fleets that need real-time fan-out). Browser and client subscriptions use the Browser SDK (iii-browser-sdk), which subscribes to stream changes over a single engine WebSocket. Connecting directly to the stream port (ws://host:{port}/stream/{stream_name}/{group_id}) is deprecated in favor of the Browser SDK.
stream::list.stream_name/group_id/item_id). Use iii-state for scope/key values.kv adapter does not fan out across processes; multi-instance fleets that need real-time broadcast must use redis.stream:leave is not an authorization gate — the subscription is already gone by the time it fires, and its return value is ignored.stream::set — persist an item and broadcast a create/update event; returns the previous value alongside the new one.stream::update — atomically apply ordered set/merge/increment/decrement/append/remove ops to an existing item.stream::delete — remove an item and broadcast a delete event carrying the removed value.stream::send — broadcast a transient event to a group's subscribers without persisting it (typing indicators, cursor positions).stream::get — read one item by its full (stream, group, item) triple.stream::list — enumerate items in a group.stream::list_groups — enumerate groups in a stream.stream::list_all — enumerate every stream's metadata.Bind a stream-family trigger when a function should run automatically on stream activity — without polling stream::list. Three types cover two concerns: stream reacts to data changes, while stream:join / stream:leave react to WebSocket subscriber lifecycle.
Reach for them when:
set/update/delete/send should drive a projection, audit log, or downstream notification.stream:join) or paired setup/teardown (stream:join + stream:leave).If you only need the current value on demand, call stream::get instead of binding a trigger.
iii.registerFunction('presence::on-change', handler).iii.registerTrigger({
type: 'stream',
function_id: 'presence::on-change',
config: {
stream_name: 'presence', // required for `stream`; the worker indexes triggers by it.
group_id: 'room-1', // optional. Empty/omitted = match every group.
item_id: 'user-123', // optional. Empty/omitted = match every item.
// condition_function_id is also supported.
},
})
stream requires a non-empty stream_name; group_id / item_id use empty-as-wildcard, exact-match-otherwise semantics. stream:join and stream:leave take no config fields — branch inside the handler on the event. A stream:join handler returning { unauthorized: true } rejects the subscription; any other return allows it. Mutations that fire stream: stream::set, stream::update, stream::delete, stream::send. Reads do not.
For the event payload shape, call iii get function info on the trigger type or handler function id.