import { WebSocket } from "ws"; import type { HomespunEvent, RecordDeltaMessage } from "./types.js"; export interface OpenStreamOptions { /** WebSocket base URL, e.g. wss://homespun.example.com (no trailing slash). */ wsBaseUrl: string; /** Homespun id. */ appId: string; /** Agent (or participant) bearer token. */ token: string; /** Opaque cursor: replay only events strictly after this id. */ since?: string | null; /** * #297 — subscribe to record-collection deltas. `"*"` expands to every * declared collection on the app's template; a comma list filters * to those names. Absent = no record traffic (legacy event-only stream). */ subscribeRecords?: string; /** * #297 — per-collection record-replay cursors. Map of collection name → * last observed seq, sent as `?since_record_seq.=` so the * relay's replay (#295) skips already-observed rows on reconnect. */ sinceRecordSeq?: Record; } /** Callbacks for a live stream. */ export interface StreamHandlers { /** Fired for every event envelope (replayed and live). */ onEvent?: (event: HomespunEvent) => void; /** Fired once when the initial event replay finishes. */ onReplayComplete?: () => void; /** * #297 — fired for every record-delta message (record.upsert / * record.delete / record.replay.complete) on the stream. Per-collection * record.replay.complete fires once per subscribed collection after * the replay set has been drained. */ onRecord?: (msg: RecordDeltaMessage) => void; /** Fired on a relay error frame. */ onRelayError?: (error: { code?: string; message?: string; details?: unknown; }) => void; /** Fired when the socket closes (cleanly or otherwise). */ onClose?: (info: { code: number; reason: string; }) => void; /** Fired on a transport-level error. */ onError?: (err: Error) => void; } /** A live handle to an open stream. */ export interface StreamHandle { /** Send an event frame into the app. */ send(frame: { type: string; data?: unknown; causation_id?: string; idempotency_key?: string; }): void; /** Close the stream. */ close(): void; /** The underlying ws socket (escape hatch). */ readonly socket: WebSocket; } /** * Open a WebSocket stream to a Homespun app. Replays on connect, then streams * live. Returns a handle for sending frames and closing. */ export declare function openStream(opts: OpenStreamOptions, handlers: StreamHandlers): StreamHandle;