@rindle/optimistic 0.5.0 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/backend.d.ts +159 -323
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +471 -829
- package/dist/backend.js.map +1 -1
- package/dist/client-id.d.ts +5 -0
- package/dist/client-id.d.ts.map +1 -1
- package/dist/client-id.js +45 -0
- package/dist/client-id.js.map +1 -1
- package/dist/client.d.ts +28 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +98 -40
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/backend.ts +519 -1028
- package/src/client-id.ts +44 -0
- package/src/client.ts +143 -52
- package/src/index.ts +6 -5
package/dist/backend.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { Ast, Backend, BackendDevObserver, ChangeEvent, ColsMap,
|
|
2
|
-
import { type WritableDescriptor } from "@rindle/wasm";
|
|
1
|
+
import type { Ast, Backend, BackendDevObserver, ChangeEvent, ColsMap, IsoTx, KeyedRow, Mutation, MutationEnvelope, MutationGen, MutatorCtx, OptimisticSource, QueryArg, QueryId, QueryResultRow, RemoteQuery, ResultType, Schema, WireValue } from "@rindle/client";
|
|
3
2
|
import { type SystemStreamSpec } from "./system-streams.ts";
|
|
4
3
|
export type { SystemStreamSpec, SystemStreamTable } from "./system-streams.ts";
|
|
5
4
|
/** A keyed row: column name → cell. The ergonomic shape — column names are validated against the
|
|
@@ -60,16 +59,13 @@ export type { ResultType };
|
|
|
60
59
|
* the post-write image (positional wire cells, schema column order); `undefined` for a `remove` —
|
|
61
60
|
* no row survives it, and `row === undefined` stays the remove marker.
|
|
62
61
|
*
|
|
63
|
-
* `oldRow` is the PRE-IMAGE, captured for a `remove`
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* H-i's `provenanceOf` routes by). A captured remove/edit thus always carries a full-width
|
|
71
|
-
* pre-image (the engine width-checks `holdBackAbsent`; Slice H evaluates writable predicates on
|
|
72
|
-
* it) — with ONE exception: a record that collapses to a (re-)insert has none, see the matrix.
|
|
62
|
+
* `oldRow` is the PRE-IMAGE, captured for a `remove` AND an `edit` (H-ii): the full-width row
|
|
63
|
+
* read via `tx.get` immediately BEFORE the write staged — read-your-writes, so a write to the
|
|
64
|
+
* same pk earlier in the SAME invocation shows through — falling back to the caller's asserted
|
|
65
|
+
* old row when the pk is not txn-visible (a raw remove/edit of an absent row; incl. the
|
|
66
|
+
* pk-MOVING raw edit, whose record is keyed by the NEW pk yet whose pre-image is the caller's
|
|
67
|
+
* OLD row). A captured remove/edit thus always carries a full-width pre-image — with ONE
|
|
68
|
+
* exception: a record that collapses to a (re-)insert has none, see the matrix.
|
|
73
69
|
*
|
|
74
70
|
* Coalescing within one invocation is last-write-wins per pk on `row` (the final image matches
|
|
75
71
|
* the engine head's own semantics for that pk) with `oldRow` pinned to the TXN-ENTRY BASE — the
|
|
@@ -114,119 +110,19 @@ export interface ReadRecord {
|
|
|
114
110
|
table: string;
|
|
115
111
|
pk: WireValue[];
|
|
116
112
|
outcome: ReadOutcome;
|
|
117
|
-
/** Per-read provenance (H-ii, §3.2 #3): the engine's `provenanceOf` answer AT THE MOMENT OF THE
|
|
118
|
-
* READ — which source ("daemon" / a room key) served the row the mutator saw. Live pre-commit
|
|
119
|
-
* state: an open txn's staged writes are not consulted (H-i), so a PRESENT read of a pk this
|
|
120
|
-
* txn itself created reports `undefined` — recorded honestly, key omitted (the router treats
|
|
121
|
-
* self-reads via write-set membership, not provenance). ABSENT reads carry no source (the
|
|
122
|
-
* mutator saw no row; there is no full-width row to probe with — a pk this txn staged-removed
|
|
123
|
-
* thus also records `undefined`, again a write-set-membership case for the router). Probed only
|
|
124
|
-
* on a PROMOTED table ({@link promotedTables}): a never-promoted (Collapsed) table is
|
|
125
|
-
* daemon-owned by construction, so a pure single-domain app pays zero wasm calls per read and
|
|
126
|
-
* `undefined` is still correct (everything is daemon-owned). One probe call per recorded
|
|
127
|
-
* present read, at read time. */
|
|
128
|
-
source?: string;
|
|
129
113
|
}
|
|
130
114
|
/** The read-log captured over ONE mutator invocation when recording is armed (RINDLE-REALTIME-
|
|
131
115
|
* QUERY-ENABLEMENT-DESIGN.md §3.2 #2): every point read (`reads` — the public `tx.get`/`tx.row`
|
|
132
116
|
* and, since H-ii, the keyed writers' internal pre-existence probes) plus every resolved query AST
|
|
133
117
|
* (`queries`, from `tx.query`). A SIBLING of the folded read TRAP (`FoldReadError` below) — the
|
|
134
118
|
* trap arms on the folded path and throws before any read completes (recording never runs there);
|
|
135
|
-
* recording arms on the ordinary (non-folded) prediction run and never throws. Pure capture
|
|
136
|
-
*
|
|
119
|
+
* recording arms on the ordinary (non-folded) prediction run and never throws. Pure capture for
|
|
120
|
+
* devtools/inspection (the §3 routing derivation it once fed was removed by
|
|
121
|
+
* 302-ROOM-STORE-SEPARATION-DESIGN.md §5 — mutators DECLARE their domain now). */
|
|
137
122
|
export interface ReadLog {
|
|
138
123
|
reads: ReadRecord[];
|
|
139
124
|
queries: Ast[];
|
|
140
125
|
}
|
|
141
|
-
/** One promoted `(sourceKey, table)`'s client-held routing spec — THE per-table routing record the
|
|
142
|
-
* §3 prove-or-slow-path router reads (H-iii). Recorded by {@link OptimisticBackend.promoteRoomTable}
|
|
143
|
-
* in the same breath as the engine attach, from the lease's `RealtimeLeaseTableSpec` (the
|
|
144
|
-
* api-server's `RoomTableSpec`, one compiler with the boot wire).
|
|
145
|
-
*
|
|
146
|
-
* - `writable`: whether the room may write this table AT ALL — `true` iff the registered engine
|
|
147
|
-
* {@link WritableDescriptor} is not `none` (a context/"followed" table is `none`; the daemon
|
|
148
|
-
* stays write-authoritative for it, §2.2). Rule #1 of the write proof.
|
|
149
|
-
* - `joinKeyCols`: the correlation columns the footprint binds on this table — the "room mutators
|
|
150
|
-
* never change join keys" input (an edit with a moved join-key cell would re-parent the row
|
|
151
|
-
* across the footprint's correlation and is refused room-routing). Deliberately client-side —
|
|
152
|
-
* they never cross the wasm {@link WritableDescriptor} ABI (the room GATE enforces them
|
|
153
|
-
* engine-side, H-iv).
|
|
154
|
-
* - `where`: the lease's row-local writable predicate (advisory here — the router evaluates the
|
|
155
|
-
* ENGINE's compiled copy via `writableMatches`, never this one; kept for introspection parity
|
|
156
|
-
* with the wire).
|
|
157
|
-
* - `footprintWhere`: the EXACT footprint-membership predicate (H-iv-b: root-node-only, lossless
|
|
158
|
-
* extraction; the vacuous-true `{type:"and",conditions:[]}` for an exact unconstrained root;
|
|
159
|
-
* ABSENT for child/correlated tables). The read proof's pk-membership test input — see
|
|
160
|
-
* {@link OptimisticBackend.deriveDomain}. */
|
|
161
|
-
export interface RoomTableRouting {
|
|
162
|
-
writable: boolean;
|
|
163
|
-
joinKeyCols: string[];
|
|
164
|
-
where?: Condition;
|
|
165
|
-
footprintWhere?: Condition;
|
|
166
|
-
}
|
|
167
|
-
/** The per-table spec {@link OptimisticBackend.promoteRoomTable} receives beside the engine
|
|
168
|
-
* descriptor (H-iii spec plumbing) — the wire-facing half of {@link RoomTableRouting}
|
|
169
|
-
* (`writable` is derived from the descriptor's kind, never passed separately). */
|
|
170
|
-
export interface RoomTableRoutingSpec {
|
|
171
|
-
joinKeyCols?: readonly string[];
|
|
172
|
-
where?: Condition;
|
|
173
|
-
footprintWhere?: Condition;
|
|
174
|
-
}
|
|
175
|
-
/** The §3 router's Q6 measurement hook ({@link OptimisticBackend.__inspectDomains}`().routing`):
|
|
176
|
-
* how often derivation succeeded (per derived room) and why it fell back to the daemon (per
|
|
177
|
-
* failure reason). `reasons` counts PER-CANDIDATE proof failures plus the terminal reasons
|
|
178
|
-
* (`no-candidates` / `tx-query` / `ambiguous`) — with multiple candidate rooms one derivation can
|
|
179
|
-
* bump several reason counters (one per failing candidate), and a candidate's failure is counted
|
|
180
|
-
* even when a sibling candidate ultimately proved. Explicit-policy pins bump NOTHING (the router
|
|
181
|
-
* never ran). */
|
|
182
|
-
export interface RoutingInspect {
|
|
183
|
-
/** Successful DERIVED routes, per room key. */
|
|
184
|
-
derived: Record<string, number>;
|
|
185
|
-
/** Derivation failures, per {@link RoutingFailureReason}. */
|
|
186
|
-
reasons: Record<string, number>;
|
|
187
|
-
}
|
|
188
|
-
/** Why a §3 derivation (or one candidate's proof) fell to the daemon — the {@link RoutingInspect}
|
|
189
|
-
* counter keys. */
|
|
190
|
-
export type RoutingFailureReason =
|
|
191
|
-
/** No connected room gate with a promoted table — the single-domain fast path. */
|
|
192
|
-
"no-candidates"
|
|
193
|
-
/** The invocation ran `tx.query` — a declarative read is not room-provable client-side
|
|
194
|
-
* (rindle-cover is native-only BY DESIGN), so the whole derivation fails unconditionally. */
|
|
195
|
-
| "tx-query"
|
|
196
|
-
/** Two or more candidate rooms both proved. Principled disambiguation is a §9.2 (multi-room
|
|
197
|
-
* clients + budgets) NON-goal, deferred past Slice J; routing slow is always sound (the §3.3
|
|
198
|
-
* gate is the contract). Reachable essentially only for zero-write mutations — real writes
|
|
199
|
-
* can't be writable in two rooms (§2.2 exactly-one-writer per doc). */
|
|
200
|
-
| "ambiguous"
|
|
201
|
-
/** A write touched a table not promoted for the candidate, or promoted `writable: none`
|
|
202
|
-
* (context) — the room may not write it at all. */
|
|
203
|
-
| "write-unwritable-table"
|
|
204
|
-
/** `writableMatches` refused the write's post-image (add/edit) or pre-image (remove). */
|
|
205
|
-
| "write-scope-miss"
|
|
206
|
-
/** An edit moved a join-key cell (old vs new differ on a `joinKeyCols` column). */
|
|
207
|
-
| "write-join-key-change"
|
|
208
|
-
/** The engine's provenance for the write's probe row names a DIFFERENT room. */
|
|
209
|
-
| "write-cross-room-provenance"
|
|
210
|
-
/** A recorded read was served by a DIFFERENT room. */
|
|
211
|
-
| "read-cross-room"
|
|
212
|
-
/** A read needed the pk-membership test but the table has no `footprintWhere` (child /
|
|
213
|
-
* correlated / inexact extraction / never-promoted table). */
|
|
214
|
-
| "read-no-footprint-where"
|
|
215
|
-
/** `footprintWhere` references a non-pk column — not decidable from the key alone. */
|
|
216
|
-
| "read-not-key-decidable"
|
|
217
|
-
/** `footprintWhere` is key-decidable but outside the deliberately-minimal client evaluator
|
|
218
|
-
* (an op other than `=`/`!=`, a null/type-mixed comparison, column-vs-column, …). */
|
|
219
|
-
| "read-not-evaluable"
|
|
220
|
-
/** `footprintWhere` evaluated FALSE on the read's pk — the room provably never holds it. */
|
|
221
|
-
| "read-outside-footprint"
|
|
222
|
-
/** NOT a derivation failure (H-v): a routed mutation came back `mutationOutcome
|
|
223
|
-
* {kind:"deopt"}` — the room GATE refused it at commit and the client re-enqueued it onto the
|
|
224
|
-
* daemon. Counted per processed deopt frame so Q6's picture is complete: derived-and-deopted
|
|
225
|
-
* routes are visible beside derived successes (a rising `deopt` count against a rising
|
|
226
|
-
* `derived` count means the client proof and the gate disagree — a compiler/evaluator skew
|
|
227
|
-
* worth investigating; each one costs a room round-trip + a burnt room mid, never
|
|
228
|
-
* correctness). */
|
|
229
|
-
| "deopt";
|
|
230
126
|
/** A virtual-clock seam for the fold debounce/maxWait timers (FOLDED-MUTATIONS-DESIGN §9): the
|
|
231
127
|
* oracle injects a deterministic scheduler; production defaults to real timers + `Date.now`. */
|
|
232
128
|
export interface FoldClock {
|
|
@@ -284,6 +180,19 @@ export interface DowngradeStuckEvent {
|
|
|
284
180
|
doc: string;
|
|
285
181
|
mids: number[];
|
|
286
182
|
}
|
|
183
|
+
/** The 302 §6.1 context-coverage event ({@link OptimisticBackend.onRoomContextJoin}): a view
|
|
184
|
+
* swapping onto room `sourceKey`'s namespaced tables still references `tables` the room does NOT
|
|
185
|
+
* own — those refs keep reading the PLAIN daemon tables (the client-side join across kinds), and
|
|
186
|
+
* the room's relayed copies of them are dropped by design (§6). Whether a daemon subscription
|
|
187
|
+
* covers the joined rows is unknowable here, so the condition is surfaced ONCE per view: without
|
|
188
|
+
* coverage the join renders silently empty for the whole room session. Fired at swap-in — a view
|
|
189
|
+
* whose every referenced table is room-owned (every in-repo app today) never fires it. */
|
|
190
|
+
export interface RoomContextJoinEvent {
|
|
191
|
+
sourceKey: string;
|
|
192
|
+
name: string;
|
|
193
|
+
args: unknown;
|
|
194
|
+
tables: string[];
|
|
195
|
+
}
|
|
287
196
|
export interface OptimisticBackendOptions {
|
|
288
197
|
/** Stable per-client identity for the upstream envelopes (§8.1). */
|
|
289
198
|
clientID: string;
|
|
@@ -297,14 +206,13 @@ export interface OptimisticBackendOptions {
|
|
|
297
206
|
/** Virtual-clock seam for the fold debounce timers (FOLDED-MUTATIONS-DESIGN §9). Defaults to
|
|
298
207
|
* real `setTimeout`/`clearTimeout`/`Date.now`; the fold oracle injects a deterministic clock. */
|
|
299
208
|
clock?: FoldClock;
|
|
300
|
-
/** The
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
* write
|
|
306
|
-
*
|
|
307
|
-
* byte-for-byte as before. */
|
|
209
|
+
/** The DECLARED confirming stream per mutation (302 §5: declared, not derived — there is no
|
|
210
|
+
* routing proof). A policy returning a string pins that domain verbatim: the mutation stages
|
|
211
|
+
* onto that room's namespaced tables and ships on its channel. Returning `undefined` (or
|
|
212
|
+
* configuring no policy) means `"daemon"`. The client layer builds this from the app's declared
|
|
213
|
+
* realtime mutators + the currently attached rooms; a misdeclaration fails SOFT (302 §5.1) —
|
|
214
|
+
* the write lands on the other authority's tables and the view simply stops feeling instant
|
|
215
|
+
* until the echo relays it. */
|
|
308
216
|
domainPolicy?: (name: string, args: unknown) => string | undefined;
|
|
309
217
|
/** A FINAL (authz/validation) mutation rejection's reason surface — the room plane's twin of the
|
|
310
218
|
* HTTP mutate route's `onRejected` (H-v; the H-iv-b `mutationOutcome {kind:"rejected"}` frame).
|
|
@@ -442,15 +350,23 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
442
350
|
* an evicted mid would be re-processed — the same bounded-window trade the shell makes, and it
|
|
443
351
|
* takes 512 interleaving non-applied outcomes on one domain to open it. */
|
|
444
352
|
private readonly outcomesProcessed;
|
|
445
|
-
/** THE
|
|
446
|
-
*
|
|
447
|
-
* as the engine
|
|
448
|
-
*
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
353
|
+
/** THE room-table registry (302 §2 — one source per table): per connected room `sourceKey`, the
|
|
354
|
+
* wire-table → engine-table map for the tables that room OWNS (its writable scope). Written by
|
|
355
|
+
* {@link registerRoomTables} (same breath as the engine registration); read by the gate's
|
|
356
|
+
* release rename/filter, the mutator staging map, the view swap ({@link processSwapIns}), and
|
|
357
|
+
* the client's `__realtimeInspect` bookkeeping. The record outlives a downgrade's disconnect —
|
|
358
|
+
* the ghost's views still read the engine tables — and drops at {@link dropGhost} (or the last
|
|
359
|
+
* clean release via {@link unregisterRoomTables}). */
|
|
360
|
+
private readonly roomTables;
|
|
361
|
+
/** Local view qids currently REGISTERED on a room's namespaced tables (302 §4 swap-in), →
|
|
362
|
+
* their sourceKey. Set by {@link processSwapIns}; cleared by the swap-back ({@link dropGhost})
|
|
363
|
+
* and view teardown. The original AST stays in {@link asts} throughout — the swap re-registers
|
|
364
|
+
* only the ENGINE query. */
|
|
365
|
+
private readonly roomSwappedViews;
|
|
366
|
+
/** Room subs whose FIRST snapshot released in the current release — their views swap onto the
|
|
367
|
+
* room tables at the release tail ({@link processSwapIns}), strictly AFTER the reconcile folded
|
|
368
|
+
* the snapshot into those tables (swapping earlier would hydrate the view EMPTY, a flash). */
|
|
369
|
+
private readonly pendingSwapIns;
|
|
454
370
|
/** The live fold entries, by fold key `${name}\0${identityJSON}` — at most one per key
|
|
455
371
|
* (FOLDED-MUTATIONS-DESIGN §8). Insertion order is creation order (the drain/flush tiebreak). */
|
|
456
372
|
private readonly folds;
|
|
@@ -473,45 +389,6 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
473
389
|
* scalars (`__inspect`) read it directly; its `sync` IS {@link sync} (the agg overlay and
|
|
474
390
|
* synthetic tables are daemon-tracked by design). */
|
|
475
391
|
private readonly daemonGate;
|
|
476
|
-
/** Tables promoted to a MERGED multi-source engine (a room source attached). Written by the one
|
|
477
|
-
* promotion seam ({@link promoteRoomTable}; the test-named {@link __addRoomSource} and Slice
|
|
478
|
-
* G-v's lease-driven promotion from `RoomTableSpec[]` both flow through it). Read by the §7.3
|
|
479
|
-
* hold-back trigger in
|
|
480
|
-
* {@link applyRelease}: parking on a never-promoted (Collapsed) table is SKIPPED — inert anyway
|
|
481
|
-
* today (`rewind_collapsed` never consults `held_back`), and a live hazard if the table later
|
|
482
|
-
* promotes (a stale Collapsed-era entry turns overlay-first-visible and pins forever). Slice H's
|
|
483
|
-
* prove-or-slow-path routing keeps the real scenario — a room-confirmed mutation writing a
|
|
484
|
-
* Collapsed table — impossible; this gate covers the window until then. */
|
|
485
|
-
private readonly promotedTables;
|
|
486
|
-
/** The §301 pin registry ({@link EchoFencePin}): every parked §7.3 hold-back's delivery-fence
|
|
487
|
-
* inputs, keyed `${table}\0${sourceKey}\0${pkKey}`. Written in the same breath as the
|
|
488
|
-
* `holdBack`/`holdBackAbsent` park; read by {@link dropEchoFencePins} at the tail of every
|
|
489
|
-
* release. Empty on every single-domain client — the drop pass is then a structural no-op. */
|
|
490
|
-
private readonly pins;
|
|
491
|
-
/** The §301 direction-A fence input: per room domain, the highest lmid the DAEMON-CARRIED
|
|
492
|
-
* ledger rows have folded ({@link foldSystemFrames} step 2 — and ONLY that path: the room
|
|
493
|
-
* socket's own lmid stream confirms long before the flush reaches the daemon, so it folds
|
|
494
|
-
* into the shared {@link watermark} but never here, 301 §1.1). When this covers a pin's mid,
|
|
495
|
-
* the same coherent release (or an earlier one) folded the flush data that carried it into
|
|
496
|
-
* the daemon baseline — the fence. */
|
|
497
|
-
private readonly daemonCarriedLmid;
|
|
498
|
-
/** The §301 §2.4 boot rule's inputs: the daemon boot ids this client has OBSERVED, in order
|
|
499
|
-
* (id → ordinal), plus the current one. Boot ids are opaque — ordering is the client's own
|
|
500
|
-
* observation ({@link OptimisticSource.onBootId} on the daemon gate). Direction-B pins stamp
|
|
501
|
-
* the current boot; a room advertising a LATER-observed boot proves absorption (its
|
|
502
|
-
* re-snapshot came from a daemon state that durably includes the confirmed write). */
|
|
503
|
-
private readonly daemonBootOrdinals;
|
|
504
|
-
private daemonBootId;
|
|
505
|
-
/** The per-read provenance probe `invoke` hands `trackingTx` when recording is armed (H-ii,
|
|
506
|
-
* §3.2 #3): the engine's `provenanceOf` — the VISIBLE overlay-first winner for the row's pk,
|
|
507
|
-
* read from LIVE pre-commit state (an open txn's staged writes are not consulted; H-i). Gated
|
|
508
|
-
* on PER-TABLE {@link promotedTables} membership — the cheapest existing signal, and the
|
|
509
|
-
* correct one: provenance is an ENGINE-merge question, not a channel question ({@link gates}
|
|
510
|
-
* can hold a connected-but-unpromoted room feed, and the oracle harness promotes with no gate),
|
|
511
|
-
* and a never-promoted (Collapsed) table is daemon-owned by construction. So a pure
|
|
512
|
-
* single-domain app pays ZERO wasm calls per recorded read; the recorded `source` is then
|
|
513
|
-
* `undefined`, which is also correct — everything is daemon-owned (see {@link ReadRecord}). */
|
|
514
|
-
private readonly readProvenance;
|
|
515
392
|
/** System retains by source qid ({@link retainSystemQuery}): a subscription with NO store view
|
|
516
393
|
* and NO user-visible table — its frames buffer on its gate exactly like {@link LMID_QID}'s and
|
|
517
394
|
* fold at RELEASE time ({@link foldSystemFrames}), never entering the sync layer or the local
|
|
@@ -552,6 +429,12 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
552
429
|
* only through outcome resolution; the ghost holds rather than inventing a timeout-retire).
|
|
553
430
|
* Default no-op. */
|
|
554
431
|
private downgradeStuckHandler;
|
|
432
|
+
/** The 302 §6.1 context-coverage surface ({@link onRoomContextJoin}) — fired at most once per
|
|
433
|
+
* view ({@link contextJoinWarned}), at swap-in, when its AST references tables the room does
|
|
434
|
+
* not own. Default no-op. */
|
|
435
|
+
private roomContextJoinHandler;
|
|
436
|
+
/** Views the context-coverage event already fired for (once per view; cleared on teardown). */
|
|
437
|
+
private readonly contextJoinWarned;
|
|
555
438
|
private readonly asts;
|
|
556
439
|
/** Per query: the base tables its result can draw from (from the AST tree). */
|
|
557
440
|
private readonly queryTables;
|
|
@@ -590,6 +473,18 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
590
473
|
* a domain may exist with no connected gate (`__testRelease` drives confirms gate-less); the
|
|
591
474
|
* live production path stays daemon-only until G calls this. */
|
|
592
475
|
connectSource(sourceKey: string, source: OptimisticSource): void;
|
|
476
|
+
/** Register the tables room `sourceKey` OWNS (its writable scope — 302 §2): each wire table
|
|
477
|
+
* gets its own namespaced ENGINE table (`{@link roomEngineTable}`), an ordinary tracked table
|
|
478
|
+
* whose sole authority is the room channel. From here on the channel's released deltas rename
|
|
479
|
+
* into these tables (wire tables outside the map are DROPPED — context stays daemon-owned,
|
|
480
|
+
* 302 §6), room-domain mutators stage onto them, and a room-homed view swaps onto them once
|
|
481
|
+
* the room sub hydrates ({@link processSwapIns}). Idempotent per (sourceKey, table); a wire
|
|
482
|
+
* table unknown to the schema is skipped (nothing to hold rows for). */
|
|
483
|
+
registerRoomTables(sourceKey: string, tables: readonly string[]): void;
|
|
484
|
+
/** The wire-table → engine-table map for room `sourceKey`'s owned tables (empty when none) —
|
|
485
|
+
* the client's idempotence check and `__realtimeInspect` read THIS record (one source of
|
|
486
|
+
* truth; the client keeps no shadow copy). */
|
|
487
|
+
roomTablesFor(sourceKey: string): ReadonlyMap<string, string>;
|
|
593
488
|
/** `channel` (G-iii registration-time routing) names the authority channel the remote sub
|
|
594
489
|
* registers on — a `connectSource`d gate key; default `"daemon"` (every existing caller is
|
|
595
490
|
* byte-identical). Slice G-v threads the lease's `realtime.sourceKey` here. Validated FIRST
|
|
@@ -632,17 +527,15 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
632
527
|
* precedent), flip `sub.channel`, re-arm `sub.hydrated` (the room's own snapshot is the
|
|
633
528
|
* cutover point), and register on the room source (its resolver presents the handed
|
|
634
529
|
* roomToken). The old gate's SYNC rows are deliberately NOT dropped: they keep the view's
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* net-zero again. No emission carries a disappearance at any point.
|
|
530
|
+
* plain tables populated through the window — the view still reads them until the swap.
|
|
531
|
+
* 2. AT THE ROOM'S FIRST RELEASED SNAPSHOT: the reconcile folds the snapshot into the room's
|
|
532
|
+
* namespaced tables, the release tail SWAPS every local view onto them (302 §4.1,
|
|
533
|
+
* {@link processSwapIns} — the accepted-flash boundary), and {@link flushRetargetGc}'s
|
|
534
|
+
* deferred `dropQuery`+reconcile on the OLD gate then GCs the plain-table rows the sub
|
|
535
|
+
* alone referenced — invisible to the swapped views.
|
|
642
536
|
*
|
|
643
537
|
* Idempotent per target channel: a sub already on `sourceKey` returns immediately (the
|
|
644
|
-
* double-doorbell / re-entrancy guard — one retarget per (query, sourceKey)
|
|
645
|
-
* {@link promoteRoomTable}'s caller-side per-(sourceKey, table) idempotence). Validates before
|
|
538
|
+
* double-doorbell / re-entrancy guard — one retarget per (query, sourceKey)). Validates before
|
|
646
539
|
* mutating: a throw here leaves the sub fully daemon-attached (the client's fail-open). */
|
|
647
540
|
retargetRemoteQuery(remote: RemoteQuery, sourceKey: string): QueryId;
|
|
648
541
|
/** Phase 2 of {@link retargetRemoteQuery}, run at the end of every gate release: once a
|
|
@@ -653,35 +546,24 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
653
546
|
* mid-window was already swept by `releaseRemoteQuery`/`unregisterQuery` (which delete the
|
|
654
547
|
* record); a vanished record here is pruned defensively. */
|
|
655
548
|
private flushRetargetGc;
|
|
656
|
-
/** The I-v downgrade orchestration primitive (§4.2/§7.4
|
|
657
|
-
* watermark fence. The caller has ALREADY
|
|
658
|
-
* ({@link retargetRemoteQuery} room→daemon —
|
|
659
|
-
*
|
|
660
|
-
* `doc` keys the §4.2 watermark fold,
|
|
549
|
+
/** The I-v downgrade orchestration primitive (§4.2/§7.4, re-expressed by 302 §4.2 as the
|
|
550
|
+
* SWAP-BACK GATE): retire room `sourceKey` behind the watermark fence. The caller has ALREADY
|
|
551
|
+
* retargeted every live sub off the channel ({@link retargetRemoteQuery} room→daemon —
|
|
552
|
+
* validated loudly below) and holds the fence from the api-server's downgrade response
|
|
553
|
+
* (`finalFlushSeq` = the room's last COMMITTED flush seq; `doc` keys the §4.2 watermark fold,
|
|
554
|
+
* {@link roomWatermarks}). Steps, in order:
|
|
661
555
|
*
|
|
662
|
-
* 1. **
|
|
663
|
-
* {@link deriveDomain} stops proposing the room (zero candidates ⇒ `"daemon"`). Unsent
|
|
664
|
-
* pending (`mid === null`) re-routes for free — a fold's flush re-derives from the live
|
|
665
|
-
* candidate set (§7.5 rule 1). The engine's frozen scope still ANSWERS (`writableMatches`
|
|
666
|
-
* / `provenanceOf` — freezing gates serving, not the scope definition); routing is
|
|
667
|
-
* TS-gated here.
|
|
668
|
-
* 2. **Freeze** the WRITABLE promoted tables (`freezeSource`): the room slice becomes the
|
|
669
|
-
* §4.2 ghost — wins-if-present in the merge (D4), so its rows (at-or-ahead of the daemon
|
|
670
|
-
* until the flush echoes) stay visible while the slice accepts nothing. Context tables
|
|
671
|
-
* (`writable: false`) are deliberately NOT frozen: the daemon is authoritative for them
|
|
672
|
-
* LIVE (§5.2's context tier) and freezing would invert that, pinning a possibly-BEHIND
|
|
673
|
-
* relayed copy over fresher daemon rows; unfrozen they keep exactly the live tiering.
|
|
674
|
-
* 3. **Disconnect** the channel ({@link disconnectSource}): handlers detached, gate + buffer
|
|
556
|
+
* 1. **Disconnect** the channel ({@link disconnectSource}): handlers detached, gate + buffer
|
|
675
557
|
* dropped. `nextMid`/`watermark`/processed-outcomes for the domain are KEPT FOREVER (§7.1:
|
|
676
558
|
* an assigned mid pins its domain; a later re-upgrade of the same doc continues the
|
|
677
559
|
* sequence — {@link connectSource} attaches a fresh gate and the lmid snapshot max-folds
|
|
678
560
|
* into the surviving watermark). Disconnecting BEFORE the daemon sub's first release is
|
|
679
561
|
* load-bearing: it makes {@link flushRetargetGc}'s deferred old-channel GC a no-op (gate
|
|
680
|
-
* gone ⇒ record deleted, nothing dropped)
|
|
681
|
-
*
|
|
682
|
-
*
|
|
683
|
-
*
|
|
684
|
-
*
|
|
562
|
+
* gone ⇒ record deleted, nothing dropped). The room's namespaced tables — and the views
|
|
563
|
+
* swapped onto them — deliberately stay: frozen at the room's last state, they keep the
|
|
564
|
+
* document visible while the falling-back follower may still lack the final flush.
|
|
565
|
+
* Swapping back earlier would show its pre-flush images — the regression §4.2 prevents.
|
|
566
|
+
* 2. **Ghost + first evaluation**: the record joins {@link ghosts} and is evaluated once
|
|
685
567
|
* immediately — `finalFlushSeq === 0` (a never-flushed room) with no room-domain pending
|
|
686
568
|
* drops on the spot, the single-daemon first-frame case.
|
|
687
569
|
*
|
|
@@ -705,6 +587,10 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
705
587
|
* later registration replaces it, the {@link onScopeSessions} convention); client.ts maps it
|
|
706
588
|
* onto the loud anomaly surface. */
|
|
707
589
|
onDowngradeStuck(handler: (event: DowngradeStuckEvent) => void): void;
|
|
590
|
+
/** Register the 302 §6.1 context-coverage sink — see {@link RoomContextJoinEvent}. One handler
|
|
591
|
+
* (a later registration replaces it, the {@link onScopeSessions} convention); client.ts maps
|
|
592
|
+
* it onto the loud anomaly surface. */
|
|
593
|
+
onRoomContextJoin(handler: (event: RoomContextJoinEvent) => void): void;
|
|
708
594
|
/** The I-v ghost-drop watcher (§4.2), run after every applied release ({@link applyRelease} —
|
|
709
595
|
* the seam where {@link roomWatermarks} has just folded and the confirm-drop has just run) and
|
|
710
596
|
* once at demote time. For each ghost: the fence must be satisfied
|
|
@@ -714,16 +600,20 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
714
600
|
* HOLDS and the stuck event fires exactly once, naming the mids). Both satisfied ⇒
|
|
715
601
|
* {@link dropGhost}. */
|
|
716
602
|
private evaluateGhosts;
|
|
717
|
-
/** Drop one cleared ghost
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
603
|
+
/** Drop one cleared ghost — the 302 §4.2 SWAP-BACK: under the fence the daemon tables are
|
|
604
|
+
* value-equal-or-ahead of the room's final state, so (1) every view swapped onto the room's
|
|
605
|
+
* namespaced tables re-registers on its ORIGINAL (daemon-table) AST — visually a no-op, the
|
|
606
|
+
* Store folds the re-hello as an in-place reset; (2) the namespaced tables unregister (no
|
|
607
|
+
* reader is left after the swap); (3) ONE daemon reconcile re-invokes the pending set so any
|
|
608
|
+
* entry whose writes had staged onto the now-gone room tables re-stages onto the daemon tables
|
|
609
|
+
* (its domain policy stopped naming the dead room when the client dropped it). The whole drop
|
|
610
|
+
* runs under one commit boundary so the swap and the re-staged predictions notify as ONE step.
|
|
611
|
+
* After this, a FUTURE upgrade of the same doc registers again from scratch. */
|
|
726
612
|
private dropGhost;
|
|
613
|
+
/** Unregister room `sourceKey`'s namespaced engine tables and drop the {@link roomTables}
|
|
614
|
+
* record. Callers must have no view registered on them (the engine refuses otherwise —
|
|
615
|
+
* loud by design). No-op for an unknown sourceKey. */
|
|
616
|
+
unregisterRoomTables(sourceKey: string): void;
|
|
727
617
|
/** Retain one minted SYSTEM subscription (RINDLE-REALTIME-QUERY-ENABLEMENT-DESIGN.md §4, Slice
|
|
728
618
|
* I-iii): a wire sub with NO store view and NO user-visible table. Registered through the same
|
|
729
619
|
* {@link RemoteSub} bookkeeping as any remote retain — so qid→channel ownership, the overflow
|
|
@@ -802,30 +692,30 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
802
692
|
* and takes only the fresh mid (the dealSeq bump is harmless: seq consumers order, never
|
|
803
693
|
* count). */
|
|
804
694
|
private dealMid;
|
|
805
|
-
/** The
|
|
806
|
-
*
|
|
807
|
-
*
|
|
695
|
+
/** The declared confirming stream for one invocation: the `domainPolicy`'s verdict, `"daemon"`
|
|
696
|
+
* when it abstains. Resolved BEFORE the prediction runs — the domain picks the staging map
|
|
697
|
+
* (a room domain stages its owned tables onto the room's namespaced twins). */
|
|
808
698
|
private resolveDomain;
|
|
809
|
-
/**
|
|
810
|
-
*
|
|
811
|
-
*
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
*
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
private
|
|
699
|
+
/** The staging table map for a `domain`-routed prediction ({@link trackingTx}'s `stage`):
|
|
700
|
+
* wire table → the room's namespaced engine table for the tables the room owns; identity for
|
|
701
|
+
* everything else (including the whole map for the daemon domain). */
|
|
702
|
+
private stagingMap;
|
|
703
|
+
/** The PLAIN (daemon-homed) engine AST for `ast` — aggregate relationships rewritten to their
|
|
704
|
+
* synthetic `__agg_*` reads, no room renames. The ONE form every non-swapped engine
|
|
705
|
+
* registration uses ({@link registerQuery}, {@link dropGhost}'s swap-back) and the base the
|
|
706
|
+
* swap-in renames ({@link processSwapIns}). */
|
|
707
|
+
private plainEngineAst;
|
|
708
|
+
/** Mutator names the cross-authority warn below already fired for (once per name). */
|
|
709
|
+
private readonly warnedCrossAuthority;
|
|
710
|
+
/** 302 §5.1 dev-time guard: a room-DECLARED mutator wrote tables the room does not own. Those
|
|
711
|
+
* writes staged onto the PLAIN daemon tables (the staging map covers only owned tables), but
|
|
712
|
+
* the entry confirms on the ROOM stream — and only the room's OWNED tables flush back to the
|
|
713
|
+
* daemon, so nothing upstream ever echoes them: once the room confirm retires the entry, the
|
|
714
|
+
* next release's whole-store rewind reverts them for good. The first-party room shell refuses
|
|
715
|
+
* such a mutation (the §3.3 deopt/reject backstop re-routes it to the daemon), so this warns
|
|
716
|
+
* for the shapes where that backstop may be absent (a BYO relay) — loud, once, soft (§5.1:
|
|
717
|
+
* misdeclarations never throw). */
|
|
718
|
+
private warnCrossAuthorityWrites;
|
|
829
719
|
/** Run the named client mutator optimistically: the prediction applies to the live
|
|
830
720
|
* engine now (affected views update synchronously), `(mid, name, args)` joins the
|
|
831
721
|
* pending stack, and the envelope ships upstream. Returns the assigned `mid`. */
|
|
@@ -951,54 +841,32 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
951
841
|
nextMid: Record<string, number>;
|
|
952
842
|
watermark: Record<string, number>;
|
|
953
843
|
/** Per connected CHANNEL (§5.1): its release watermark + buffered-frame depth — the axis the
|
|
954
|
-
* gate-isolation assertions read (one source's laggy cvMin must never move the other's)
|
|
955
|
-
* plus the §301 upstream-absorption advert last recorded from its progress frames (a ROOM
|
|
956
|
-
* gate with a new shell; absent otherwise). */
|
|
844
|
+
* gate-isolation assertions read (one source's laggy cvMin must never move the other's). */
|
|
957
845
|
gates: Record<string, {
|
|
958
846
|
appliedCv: number;
|
|
959
847
|
bufferedFrames: number;
|
|
960
|
-
upstreamCv?: number;
|
|
961
|
-
upstreamBoot?: string;
|
|
962
848
|
}>;
|
|
963
|
-
/**
|
|
964
|
-
*
|
|
965
|
-
|
|
966
|
-
|
|
849
|
+
/** Per connected/registered room: its wire-table → engine-table map (302 §2) and which local
|
|
850
|
+
* view qids are currently swapped onto it (302 §4). */
|
|
851
|
+
roomTables: Record<string, Record<string, string>>;
|
|
852
|
+
swappedViews: Record<number, string>;
|
|
967
853
|
/** The §4 lifecycle plane's folded state (Slice I-iii introspection): the per-doc §4.2 fence
|
|
968
854
|
* value (`roomWatermarks`, I-v's ghost-drop input), the per-scope §4.1 occupancy map
|
|
969
855
|
* (`scopeSessions`: scope → client_id → expires_at, I-iv's doorbell input), and the live
|
|
970
|
-
* I-v ghosts (demoted room sources still awaiting their fence). */
|
|
856
|
+
* I-v ghosts (demoted room sources still awaiting their swap-back fence). */
|
|
971
857
|
lifecycle: {
|
|
972
858
|
roomWatermarks: Record<string, number>;
|
|
973
859
|
scopeSessions: Record<string, Record<string, number>>;
|
|
974
860
|
ghosts: Record<string, {
|
|
975
861
|
doc: string;
|
|
976
862
|
finalFlushSeq: number;
|
|
977
|
-
tables: string[];
|
|
978
863
|
}>;
|
|
979
864
|
};
|
|
980
|
-
/** The live §301 pin registry (`301-ECHO-FENCE-DESIGN.md` §2.5 — the devtools/Q6 surface):
|
|
981
|
-
* every parked hold-back's fence inputs plus its tripwire state, keyed
|
|
982
|
-
* `${table}\0${sourceKey}\0${pkKey}`. Pruned lazily, so an entry here may briefly outlive
|
|
983
|
-
* its engine pin (never the reverse). */
|
|
984
|
-
pins: Record<string, {
|
|
985
|
-
table: string;
|
|
986
|
-
sourceKey: string;
|
|
987
|
-
domain: string;
|
|
988
|
-
mid: number;
|
|
989
|
-
daemonBoot?: string;
|
|
990
|
-
daemonCv?: number;
|
|
991
|
-
tripwired: boolean;
|
|
992
|
-
}>;
|
|
993
|
-
/** The §301 direction-A fence map: per room domain, the highest DAEMON-CARRIED ledger lmid. */
|
|
994
|
-
daemonCarriedLmid: Record<string, number>;
|
|
995
865
|
pending: {
|
|
996
866
|
mid: number | null;
|
|
997
867
|
seq: number | null;
|
|
998
868
|
name: string;
|
|
999
869
|
domain: string;
|
|
1000
|
-
touchedSources: string[];
|
|
1001
|
-
writeSources: Record<string, string>;
|
|
1002
870
|
}[];
|
|
1003
871
|
};
|
|
1004
872
|
/** Recompute the pending axis for every query and fire `onPending` on transitions only. Called
|
|
@@ -1036,50 +904,18 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
1036
904
|
* exercise a room-domain confirm before the real second lmid stream / per-source gate is wired
|
|
1037
905
|
* (E-iii-b/c). The `__`-prefix marks it a test hook, alongside {@link __inspect}. */
|
|
1038
906
|
__testRelease(sourceKey: string, deltas: Mutation[], watermarkUpdate?: number): void;
|
|
1039
|
-
/**
|
|
1040
|
-
* the engine
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
*
|
|
1046
|
-
* the fence — benign), drop every pin whose fence cleared (one engine drop each, delivered on
|
|
1047
|
-
* the ordinary event stream, bracketed as ONE notification commit), and tripwire the rest. */
|
|
1048
|
-
private dropEchoFencePins;
|
|
1049
|
-
/** Has `pin`'s delivery fence provably closed its confirm→echo window? (§2.3/§2.4.) */
|
|
1050
|
-
private pinFenceCleared;
|
|
1051
|
-
/** The §2.5 stuck-pin tripwire, in the scopesHash spirit: log ONCE per pin when its slice's
|
|
1052
|
-
* baseline row has CHANGED VALUE since park while the pin still holds — the suspicious state
|
|
1053
|
-
* that precedes every forever-pin (a fence-less pairing, a fence bug). Never drops anything. */
|
|
1054
|
-
private maybeTripwirePin;
|
|
1055
|
-
/** Record one observed daemon boot id (§2.4): first observation of an id assigns the next
|
|
1056
|
-
* ordinal (the client's own total order over opaque boot ids); every call refreshes the
|
|
1057
|
-
* current-boot stamp for direction-B parks. */
|
|
1058
|
-
private observeDaemonBoot;
|
|
1059
|
-
/** Promote `table` to a MERGED multi-source engine with room `sourceKey`'s per-row writable
|
|
1060
|
-
* scope (RINDLE-REALTIME-QUERY-ENABLEMENT-DESIGN.md §5.2) — THE one promotion seam. The engine
|
|
1061
|
-
* attach and the {@link promotedTables} record move in the same breath: the §7.3 hold-back
|
|
1062
|
-
* trigger in {@link applyRelease} parks ONLY on promoted tables, so a promotion that bypassed
|
|
1063
|
-
* the record would silently disable the echo hold-back for that table (and a record without the
|
|
1064
|
-
* engine attach would park onto a slice that doesn't exist). Recorded AFTER the engine accepts —
|
|
1065
|
-
* a rejected descriptor/table must not leave a phantom promotion. Slice G-v's client drives this
|
|
1066
|
-
* from the lease's `realtime.tables` (`RoomTableSpec` → {@link WritableDescriptor}); idempotence
|
|
1067
|
-
* per `(sourceKey, table)` is the CALLER's job (the engine refuses a duplicate room).
|
|
907
|
+
/** Swap every view of each just-hydrated ROOM sub onto the room's namespaced tables (302 §4.1):
|
|
908
|
+
* re-register the local engine query with the AST's room-owned table references renamed
|
|
909
|
+
* ({@link remapAstTables}); the Store folds the re-hello as an in-place reset, so the caller's
|
|
910
|
+
* view reference survives and subscribers see ONE transition. Runs at the applyRelease tail —
|
|
911
|
+
* the reconcile has already folded the sub's snapshot into the room tables, so the swapped
|
|
912
|
+
* view hydrates straight to the room state (swapping earlier would flash it empty). The
|
|
913
|
+
* ORIGINAL ast stays in {@link asts}; the swap-back ({@link dropGhost}) re-registers it.
|
|
1068
914
|
*
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
|
|
1073
|
-
* `footprintWhere` (that room's reads then fail closed to the daemon unless self/room-served). */
|
|
1074
|
-
promoteRoomTable(table: string, sourceKey: string, writable: WritableDescriptor, spec?: RoomTableRoutingSpec): void;
|
|
1075
|
-
/** The recorded routing specs for `sourceKey`'s promoted tables (table → its
|
|
1076
|
-
* {@link RoomTableRouting}) — read-only: the client's `__realtimeInspect`/idempotence
|
|
1077
|
-
* bookkeeping reads THIS record instead of keeping its own shadow copy (one source of truth).
|
|
1078
|
-
* Empty map when the room has promoted nothing. */
|
|
1079
|
-
roomTablesFor(sourceKey: string): ReadonlyMap<string, RoomTableRouting>;
|
|
1080
|
-
/** Test-named alias of {@link promoteRoomTable} (E-iii-b scaffolding — the multi-domain oracle
|
|
1081
|
-
* and per-source-gate suites drive it). Pure delegation: ONE body, one `promotedTables` record. */
|
|
1082
|
-
__addRoomSource(table: string, roomKey: string, writable: WritableDescriptor, spec?: RoomTableRoutingSpec): void;
|
|
915
|
+
* This is the accepted-flash boundary (302 §4.1/§7.1): the room's copy may be behind the
|
|
916
|
+
* daemon rows the view showed a moment ago — accepted by decision, revisit on a real
|
|
917
|
+
* two-region deploy. */
|
|
918
|
+
private processSwapIns;
|
|
1083
919
|
/** Fold `domain`'s lmid system query's released ops (lmid-as-data): the one row's
|
|
1084
920
|
* `last_mutation_id` cell is this client's confirmed high-water mid in that domain — it advances
|
|
1085
921
|
* `watermark[domain]` and, on a fresh session ahead of our issued mids, `nextMid[domain]`. The
|
|
@@ -1177,8 +1013,10 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
1177
1013
|
* longer affects it. Used when a remote sub attaches to or hydrates a local view. */
|
|
1178
1014
|
private recomputeResultType;
|
|
1179
1015
|
/** A remote sub's first snapshot landed: mark it (and every local view it feeds) hydrated, then
|
|
1180
|
-
* lift those views out of `unknown` (loading).
|
|
1181
|
-
*
|
|
1016
|
+
* lift those views out of `unknown` (loading). A ROOM sub's hydration additionally queues the
|
|
1017
|
+
* 302 §4.1 swap-in — performed at the applyRelease TAIL ({@link processSwapIns}), once the
|
|
1018
|
+
* reconcile has folded this snapshot into the room tables. Idempotent — a re-hydrate snapshot
|
|
1019
|
+
* re-marks harmlessly; a source qid with no sub (the lmid system query) is a no-op. */
|
|
1182
1020
|
private markSubHydrated;
|
|
1183
1021
|
/** `channel` (G-iii registration-time routing): the gate the sub registers on — the qid's
|
|
1184
1022
|
* ownership is fixed HERE, at retain time (no lazy claim; `onFrame` only asserts it). Default
|
|
@@ -1187,19 +1025,17 @@ export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
|
1187
1025
|
private releaseRemote;
|
|
1188
1026
|
private addServerDependencyTables;
|
|
1189
1027
|
}
|
|
1190
|
-
/**
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1198
|
-
*
|
|
1199
|
-
*
|
|
1200
|
-
*
|
|
1201
|
-
*
|
|
1202
|
-
|
|
1203
|
-
* partial evaluation could otherwise claim a verdict the engine's semantics might contradict. */
|
|
1204
|
-
export declare function evalFootprintOnPk(cond: Condition, pkCells: ReadonlyMap<string, WireValue>): boolean | undefined;
|
|
1028
|
+
/** The namespaced ENGINE table backing wire `table` for room `sourceKey` (302 §2: `room_deck` ≠
|
|
1029
|
+
* `deck` — one authority per table). `@` appears in no schema table name — ENFORCED by
|
|
1030
|
+
* `createSchema`/`extendSchema`'s addTableMeta ban (packages/client/src/schema.ts), so the name
|
|
1031
|
+
* cannot collide with a real table. */
|
|
1032
|
+
export declare function roomEngineTable(table: string, sourceKey: string): string;
|
|
1033
|
+
/** Rename every TABLE reference in a query AST through `map` (302 §2 point 3 — the room-homed
|
|
1034
|
+
* view's rewrite): the root `table`, every `related` subquery, every `correlatedSubquery`
|
|
1035
|
+
* (EXISTS) condition — walking the KNOWN wire-AST shape, never a blind key scan: `start.row` is
|
|
1036
|
+
* keyed by COLUMN name (a schema column literally named `table` must keep its bound value), and
|
|
1037
|
+
* the same goes for any future column-keyed record. Tables absent from the map keep their name —
|
|
1038
|
+
* that is the client-side join across kinds (a room table joined to daemon-owned context,
|
|
1039
|
+
* 201-style). Structural clone; the input AST is never mutated. */
|
|
1040
|
+
export declare function remapAstTables(ast: Ast, map: ReadonlyMap<string, string>): Ast;
|
|
1205
1041
|
//# sourceMappingURL=backend.d.ts.map
|