import type { Root, Streamable } from "./Root.js"; /** * Thrown (from both the `FieldBuilder` chainable and the decorator's * `addField` auto-flag) when a user attempts to stream an ArraySchema. * Centralized so the two callsites emit the same diagnostic. */ export declare const ARRAY_STREAM_NOT_SUPPORTED: string; /** * Per-instance bookkeeping for a streamable collection. Lazily allocated * by `ensureStreamState` when the collection's ChangeTree picks up the * `isStreamCollection` flag (or when the user touches `maxPerTick`). */ export interface StreamableState { /** Per-view ADD backlog: wire-indexes not yet sent to that view. */ pendingByView: Map>; /** Per-view SENT set — decides whether `remove()` emits a DELETE. */ sentByView: Map>; /** Broadcast-mode ADD backlog (no active views). */ broadcastPending: Set; /** Broadcast-mode SENT set. */ sentBroadcast: Set; /** Broadcast-mode DELETE queue — flushes next shared tick. */ broadcastDeletes: Set; /** Max ADD ops emitted per tick per view (or per shared tick). */ maxPerTick: number; /** * Priority callback seeded from the schema declaration. Receives the * client's StateView and the candidate element; higher return values * emit first. Broadcast `encode()` ignores this and drains FIFO. * Instance-level override: assign to `stream.priority`. */ priority?: (view: any, element: any) => number; /** * Per-view priority registered by `StateView.subscribe(collection, fn)`. * Takes precedence over the declaration-scope `priority` for that view. * Receives only the element — the client's own entity is captured in * the closure, so nothing has to be attached to the view. */ priorityByView?: Map number>; } export declare function createStreamableState(): StreamableState; /** Allocate `_stream` on first use (idempotent). Returns the state. */ export declare function ensureStreamState(s: Streamable): StreamableState; /** * Route an ADD into the pending backlogs. * - No active views: push into broadcast pending (shared encode drains up * to `maxPerTick` per tick). * - With views: push into per-view pending for every currently-bound view. */ export declare function streamRouteAdd(s: Streamable, root: Root, index: number): void; /** * Route a REMOVE: silent-drop if never sent, force DELETE if already sent. * Returns `true` iff no wire op reached any channel (caller can skip * follow-on work like snapshotting the deleted value). */ export declare function streamRouteRemove(s: Streamable, root: Root, refId: number, index: number): boolean; /** * Queue DELETE ops for every already-sent entry on all channels and * reset pending. Caller is responsible for actually clearing its own * storage and releasing any element refs it owns. */ export declare function streamRouteClear(s: Streamable, root: Root, refId: number): void; /** * True while a live view still has positions waiting on `maxPerTick`. * Entries of garbage-collected views are ignored — they never drain. */ export declare function streamHasViewBacklog(s: Streamable, root: Root): boolean; /** True while broadcast-mode ADDs or DELETEs are still queued. */ export declare function streamHasBroadcastBacklog(s: Streamable): boolean; /** * Push a single position into `_pendingByView[viewId]` — the building * block for `StateView.add(element)` when the element lives under a * streamable collection. Idempotent for already-pending positions. */ export declare function streamEnqueueForView(s: Streamable, viewId: number, index: number): void; /** * Unsubscribe a single position from a view. Returns true iff the * element had already been sent and a DELETE op was queued on * `view.changes`; false if it was only pending (silent drop) or not * present at all. */ export declare function streamDequeueForView(s: Streamable, viewId: number, refId: number, index: number, viewChanges: Map>): boolean; /** * Drop all per-view state for a disposing/GC'd StateView. Keeps memory * bounded in long-running rooms with client churn. */ export declare function streamDropView(s: Streamable, viewId: number): void;