API index and search · Build metadata
Supporting declarations
packages/remote/src/protocol.ts. These declarations explain referenced types. Only package-page symbols are package exports.
Fnv
export declare class Fnv {
h: bigint;
private byte;
u8(v: number): void;
/** A `u32` little-endian (matching Rust `v.to_le_bytes()`). */
u32(v: number): void;
/** A length-prefixed string: `u32(byteLen)` then the UTF-8 bytes (disambiguates joins). */
s(str: string): void;
}schemaFp
/** A `WireSchema`'s content fingerprint — FNV-1a 64 over the canonical, length-prefixed byte
* stream of `src/wire_schema.rs`, rendered as 16-char lowercase hex (=== Rust `SchemaFp`
* `Display`). A string (not a JS number) so the full 64 bits survive JSON without precision loss. */
export declare function schemaFp(ws: WireSchema): string;Hello
/** The subscription handshake, sent once before any {@link Batch}. */
export interface Hello {
epoch: number;
comparatorVersion: number;
schema: WireSchema;
schemaFp: string;
}Batch
/** One transaction's flat changes (or the seq-0 hydrate snapshot). `events` apply in order. */
export interface Batch {
epoch: number;
seq: number;
schemaFp: string;
events: FlatChange[];
}SubscribeClientMsg
/** The multiplexed wire messages (many queries over one connection, tagged by `queryId`).
* `subscribe.mode` selects the serializer (default flat); a normalized subscription gets
* `nhello`/`nbatch` back instead of `hello`/`batch` (NORMALIZED-CHANGES-DESIGN.md §6).
* Embedded servers receive `{name,args}`. Daemon/serverless deployments can instead receive an
* opaque `leaseToken` that the app API server minted after auth + named-query resolution.
*
* The OPTIMISTIC path (OPTIMISTIC-WRITES-DESIGN.md §8) adds `init` (the connection
* identifies its stable clientID, so progress frames can carry that client's `lmid`) and
* `pushMutation` (one named-mutator envelope up); the server answers with the normalized
* frames (`cv`-stamped) plus connection-level `progress` frames. */
export type SubscribeClientMsg = {
t: "subscribe";
queryId: number;
name: string;
args: unknown;
mode?: "flat" | "normalized";
} | {
t: "subscribe";
queryId: number;
leaseToken: string;
mode?: "flat" | "normalized";
};ClientMsg
export type ClientMsg = {
t: "init";
clientID: string;
} | SubscribeClientMsg | {
t: "unsubscribe";
queryId: number;
} | {
t: "mutate";
mutations: Mutation[];
} | {
t: "pushMutation";
envelope: MutationEnvelope;
};ServerMsg
export type ServerMsg = {
t: "hello";
queryId: number;
hello: Hello;
} | {
t: "batch";
queryId: number;
batch: Batch;
} | {
t: "nhello";
queryId: number;
hello: NormalizedHello;
bootId?: string;
} | {
t: "nbatch";
queryId: number;
batch: NormalizedBatch;
} | {
t: "queryError";
queryId: number;
message: string;
code?: string;
retryable?: boolean;
retryAfterMs?: number;
} | {
t: "progress";
frame: ProgressFrame;
} | {
t: "affinity";
ticket: string;
} | {
t: "mutationOutcome";
mid: number;
kind: "deopt" | "rejected";
reason?: string;
name?: string;
args?: unknown;
} | {
t: "error";
queryId?: number;
message: string;
};Publisher
/** Sender side: stamps batches with the subscription `epoch` + `schemaFp` and drives the
* gap-free seq. The hydrate snapshot is seq 0; increments are seq 1, 2, …. An empty
* transaction emits no batch and consumes no seq (so a gap always means a lost batch). */
export declare class Publisher {
readonly epoch: number;
readonly schema: WireSchema;
readonly schemaFp: string;
private nextSeq;
constructor(epoch: number, schema: WireSchema);
hello(): Hello;
/** The hydrate snapshot (seq 0). Always emitted, even when empty, so the receiver learns it. */
snapshot(events: FlatChange[]): Batch;
/** One transaction's events — `null` for an empty transaction (no batch, no seq consumed). */
commit(events: FlatChange[]): Batch | null;
private emit;
}ProtocolErrorKind
export type ProtocolErrorKind = "comparator-mismatch" | "epoch-mismatch" | "schema-mismatch" | "gap";ProtocolError
/** A protocol violation. All but a duplicate (handled silently) are unrecoverable for the
* current subscription — the RemoteBackend re-hydrates under a new epoch. */
export declare class ProtocolError extends Error {
readonly kind: ProtocolErrorKind;
constructor(kind: ProtocolErrorKind, message: string);
}Subscriber
/** Receiver side: validates a frame stream (comparator at `hello`; per batch — epoch match,
* schema-fp match, strict in-order seq) and emits the clean `hello`/`snapshot`/`batch`
* `ChangeEvent`s. It does NOT fold (the core `ArrayView` does) — the §2.2 split. */
export declare class Subscriber {
readonly epoch: number;
readonly schemaFp: string;
private readonly emit;
private phase;
private lastSeq;
constructor(hello: Hello, emit: (ev: ChangeEvent) => void);
/** Apply one incremental batch (or the seq-0 snapshot). Returns `"duplicate"` for an
* already-applied seq (discarded — rc ops are not idempotent); throws {@link ProtocolError}
* on a gap / epoch / schema mismatch (the caller re-hydrates). */
apply(batch: Batch): "applied" | "duplicate";
}