API index and search · Build metadata
Supporting declarations
packages/normalized/src/backend.ts. These declarations explain referenced types. Only package-page symbols are package exports.
NormalizedBackend
export declare class NormalizedBackend<S extends ColsMap> implements Backend {
private readonly local;
private readonly sync;
private readonly source;
private handler;
/** The Store's commit-boundary handler ({@link Backend.onCommitBoundary}), forwarded from the
* local engine's `dispatch` brackets so the Store folds every affected view before notifying any
* subscriber (cross-view-atomic notification). A normalized batch becomes net base mutations
* applied to the local engine in one commit, which fans to every view reading those rows — this
* carries that commit's boundary up so all those views notify together. */
private boundaryHandler;
private readonly devObservers;
private readonly remoteSubs;
private readonly localToRemote;
private readonly remoteRetainToLocal;
private readonly sourceToRemote;
private readonly resultTypes;
private readonly hydrated;
/** Local qids that are JUST hydrating on the in-flight `onNormalized` snapshot — set only for the
* duration of its `local.mutate`, so the local-event forwarder stamps their fold `catchUp`: the
* whole first result set arrives as a `batch` (we hydrate the view by mutating the embedded engine,
* which speaks in batches — there is no second `snapshot`), and `catchUp` is the flag that tells the
* Store this batch IS hydration (retire the SSR seed, phase it as a snapshot for narration). The
* optimistic backend does the identical thing across its reconcile cycle. `null` outside a hydrate. */
private catchUpQids;
private resultTypeHandler;
/** The client's OWN typed per-table schemas (for CRIT#4 validation), fixed at construction. */
private readonly clientTables;
/** Synthetic aggregate tables (`__agg_*`) registered so far, by name (§3.3). Per aggregate
* DEFINITION (not per query), so two queries over the same count share one table. */
private readonly synthetic;
/** table → (column name → base ColId), for mapping a projected hello to base positions. */
private readonly colIndex;
/** table → full column count, to detect whether a hello's table is projected. */
private readonly colCounts;
/** Synthetic table name → how many registered queries reference it. Materialized on `0→1`,
* reclaimed (engine source + refcount layer) on `1→0` — so aggregate state is not permanent (§4). */
private readonly syntheticRefs;
/** queryId → the synthetic tables it referenced at registration, to decrement on teardown. */
private readonly queryAggTables;
constructor(schema: Schema<S>, source: NormalizedSource);
registerQuery(qid: QueryId, ast: Ast, remote?: RemoteQuery): void;
/** Register every synthetic aggregate table `ast` needs that we haven't seen yet: on the
* local engine (so it can join to it), on `NormalizedSync` (so its rows refcount/GC by
* group key), and into the source's expected-schema set (so the server's `hello` — which
* advertises the same table — passes CRIT#4 validation, the client deriving the schema
* identically). Idempotent across queries that share an aggregate definition. */
private ensureSyntheticTables;
/** Decrement each synthetic table query `qid` referenced; remove the ones that reach 0 (no
* reader left) from the engine + refcount layer — aggregate state reclaimed, not permanent
* (§4). Runs AFTER `local.unregisterQuery(qid)` so the source has no live connection when
* `unregisterTable` frees it. */
private releaseSyntheticTables;
unregisterQuery(qid: QueryId): void;
retainRemoteQuery(qid: QueryId, remote: RemoteQuery, localQueryId?: QueryId, ast?: Ast): void;
releaseRemoteQuery(qid: QueryId): void;
/** Writes are authoritative-only here: send to the server, the stream reconciles locally.
* (Optimistic local apply + rebase is Slice 6.) */
mutate(mutations: Mutation[]): Promise<void>;
onEvent(handler: (qid: QueryId, ev: ChangeEvent) => void): void;
onCommitBoundary(handler: (phase: "begin" | "end") => void): void;
onResultType(handler: (qid: QueryId, rt: ResultType) => void): void;
__attachDevtoolsServerDeltas(observer: BackendDevObserver): () => void;
private onNormalized;
private emitServerDelta;
private localQidsForSource;
private retainRemote;
private releaseRemote;
private markSubHydrated;
private hasRemoteDependency;
private setResultType;
private recomputeResultType;
}createNormalizedStore
/** A local-first {@link Store} whose base tables are fed by a server's normalized stream.
* The returned Store is the ordinary `@rindle/client` Store — `store.query…materialize()` and
* `store.write(…)` work as always; only the backend composition differs. */
export declare function createNormalizedStore<S extends ColsMap>(schema: Schema<S>, source: NormalizedSource): Store<S>;