API index and search · Build metadata
Supporting declarations
packages/room/src/shell.ts. These declarations explain referenced types. Only package-page symbols are package exports.
UpstreamOptions
/** The upstream half of the shell's config: where rindled lives and what to follow. */
export interface UpstreamOptions {
/** rindled's public subscription plane, e.g. `ws://127.0.0.1:7601`. */
wsUrl: string;
/** rindled's private control plane, e.g. `http://127.0.0.1:7600` (lease minting). */
controlUrl: string;
/** Bearer token for the control plane (required unless rindled runs unauthenticated). */
authToken?: string;
/** The document footprint — a wire `Ast` (§3.1). What this room follows and serves from. */
footprintAst: unknown;
/** Lease TTL passed to `/materialize` (rindled's default when omitted). */
leaseTtlMs?: number;
/** The `init` clientID on the upstream socket (diagnostic identity). */
clientId?: string;
}DownstreamOptions
/** The downstream half: how clients are authorized and served (§4/§10.1). */
export interface DownstreamOptions {
/** This room's document id — lease tokens for any other doc are refused. */
docId: string;
/** Token key ring: `kid` → shared secret (the API server signs with the same ring). */
tokenKeys: Record<string, string>;
/** Idle grace before an unsubscribed query's pipeline is reclaimed (default 30s). */
idleTtlMs?: number;
/** Lease-expiry / idle-sweep cadence (default 1s). */
sweepIntervalMs?: number;
/** How long a revocation keeps refusing pre-revocation tokens (default 30min — set
* it ≥ the longest token TTL the API server mints). */
revocationWindowMs?: number;
/** The room's private control plane (`POST /revoke`, `GET /stats`). Omit to run
* without one (no revocation surface). */
control?: {
authToken: string;
port?: number;
};
/** The write plane (§5.1). Omit to run read-only (writes are refused). */
writes?: WritesOptions;
/** Per-socket downstream send budget in bytes (§9; default 4 MiB). A socket whose
* queued bytes would exceed it is terminated with a gap — re-subscribing is the
* repair. */
sendBudgetBytes?: number;
}RoomScopeSpec
/** One table's §3.3 scope spec (H-iv-b): an element of the api-server's
* `RoomBootResponse.scopes`, passed VERBATIM to the wasm room's `enableWritesV2`.
* Structurally identical to `@rindle/api-server`'s `RoomScopeSpec` (declared locally —
* the shell must not depend on the api-server package; TS structural typing keeps the
* two in lockstep at the host's threading site). */
export interface RoomScopeSpec {
table: string;
/** The footprint's row-local predicate for this table (a wire `Condition`) — drives
* the commit gate's absent-read proof. Absent ⇒ absent reads on this table always
* deopt (fail closed). */
footprintWhere?: unknown;
writable: {
kind: "none";
} | {
kind: "predicate";
where?: unknown;
joinKeyCols: string[];
};
}WritesOptions
/** The §5.1 write plane: the room's own mutator registry over its owned tables. */
export interface WritesOptions {
/** The server registry (§4.2): named mutators run against the shared head. PLAIN
* synchronous `(tx, args, ctx)` functions only — a `shared(...)` GENERATOR registry
* does NOT register verbatim (nothing drives it here; the shell rejects a mutator
* that returns a generator/promise — see `assertSyncMutatorReturn`). */
mutators: Record<string, RoomMutator>;
/** §3.2's owned set — the only tables mutators may write. Must all be in the
* upstream footprint; followed tables and the ledger are never writable. */
ownedTables: string[];
/** The §3.3 per-table scope specs from the boot wire (`RoomBootResponse.scopes` —
* H-iv-b). Present ⇒ the write plane enables in v2 GATED mode (`enableWritesV2`):
* staged writes validate against the writable predicates, join-key edits refuse,
* absent reads must prove against `footprintWhere`, context (`kind:"none"`) tables
* become txGet-READABLE, and a violating commit returns a structured DEOPT instead
* of applying. The scopes' writable tables must be a SUBSET of {@link ownedTables}
* (the host's own declaration) — a wider server scope throws at construction, so a
* self-hoster's owned set can never be extended from the wire. Absent ⇒ the v1
* table-granular write plane, byte-identical to before. */
scopes?: RoomScopeSpec[];
/** The durable sidecar an ack means (§8.1). Defaults to `memoryJournal()` — the
* "survives nothing beyond the process" class; hosts bring their own. */
journal?: RoomJournal;
/** The journal group-commit window (default 5ms): mutations arriving within it
* share one append, and their acks ride one ledger commit. */
groupCommitMs?: number;
/** The write authority (§5.3.1) — the API server's `/apply-row-change-txn` host
* (or the P3 gate's mock). Omit to run journal-only (P2 semantics: nothing is
* ever durable upstream). With an authority, the shell claims a placement epoch
* at boot, probes durable lmids before replay, and write-behinds on the flush
* cadence (§5.3). */
authority?: RoomAuthority;
/** The flush debounce (§5.3; default 250ms, within the design's ≤1s budget). */
flushDebounceMs?: number;
/** Flush immediately once this many keys are dirty (default 512). */
flushDirtyMax?: number;
}RoomShellOptions
export interface RoomShellOptions {
upstream: UpstreamOptions;
downstream: DownstreamOptions;
/** Downstream ws port (default 0 = ephemeral; bound on 127.0.0.1). */
port?: number;
/** Diagnostic sink (default: silent). */
log?: (line: string) => void;
}RoomShell
export interface RoomShell {
/** The bound downstream port. */
readonly port: number;
/** The bound control-plane port (0 when no control plane was configured). */
readonly controlPort: number;
/** Resolves when the CURRENT incarnation is live (seq-0 snapshot applied);
* immediately if it already is. */
awaitLive(): Promise<void>;
/** The last-applied upstream commit version, if live. */
cv(): number | undefined;
/** The upstream subscription epoch of the current incarnation, if any. */
upstreamEpoch(): number | undefined;
/** This incarnation's downstream bootId (rotates on every re-subscribe). */
bootId(): string;
/** Fire the write-behind flush now (instead of the debounce) and await its
* settlement — deterministic flushing for tests and drain-before-close. No-op
* without an authority. */
flushNow(): Promise<void>;
close(): Promise<void>;
}createRoomShell
/** Boot a room shell: init the wasm, mint the upstream lease, connect the upstream leg,
* and serve the downstream ws (+ the private control plane, if configured). Returns
* once the ports are bound and the upstream connection is underway — await
* `shell.awaitLive()` for the seed. */
export declare function createRoomShell(opts: RoomShellOptions): Promise<RoomShell>;