@rindle/optimistic 0.1.0-rc.5
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/LICENSE +201 -0
- package/README.md +66 -0
- package/dist/agg-overlay.d.ts +86 -0
- package/dist/agg-overlay.d.ts.map +1 -0
- package/dist/agg-overlay.js +224 -0
- package/dist/agg-overlay.js.map +1 -0
- package/dist/backend.d.ts +243 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +998 -0
- package/dist/backend.js.map +1 -0
- package/dist/client-id.d.ts +12 -0
- package/dist/client-id.d.ts.map +1 -0
- package/dist/client-id.js +60 -0
- package/dist/client-id.js.map +1 -0
- package/dist/client.d.ts +64 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +81 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
- package/src/agg-overlay.ts +257 -0
- package/src/backend.ts +1155 -0
- package/src/client-id.ts +61 -0
- package/src/client.ts +156 -0
- package/src/index.ts +68 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import type { Ast, Backend, ChangeEvent, ColsMap, Mutation, OptimisticSource, QueryId, RemoteQuery, ResultType, Schema, WireValue } from "@rindle/client";
|
|
2
|
+
/** A keyed row: column name → cell. The ergonomic shape — column names are validated
|
|
3
|
+
* against the schema at runtime, so a typo throws immediately with the valid names. */
|
|
4
|
+
export type KeyedRow = Record<string, WireValue>;
|
|
5
|
+
/** The write handle a client mutator runs against (the client `MutationTx`, §4.2):
|
|
6
|
+
* reads see the current base + this transaction's own staged writes (§4.1).
|
|
7
|
+
*
|
|
8
|
+
* Prefer the KEYED methods (`insert`/`update`/`upsert`/`delete`/`row`) — named columns,
|
|
9
|
+
* schema-checked. The positional methods (`get`/`add`/`remove`/`edit`) are the raw wire
|
|
10
|
+
* shape: bare cells in schema column order, `pk` cells in `primaryKey` order. */
|
|
11
|
+
export interface MutationTx {
|
|
12
|
+
/** Read one row by primary key (e.g. `tx.row("issue", { id: 1 })`). */
|
|
13
|
+
row(table: string, pk: KeyedRow): KeyedRow | undefined;
|
|
14
|
+
/** Insert a FULL row (every column named; missing or unknown columns throw). */
|
|
15
|
+
insert(table: string, row: KeyedRow): void;
|
|
16
|
+
/** Update the row identified by the pk columns; only the named non-pk columns change.
|
|
17
|
+
* A missing row is a NO-OP (rebase-friendly: the row may have vanished upstream). */
|
|
18
|
+
update(table: string, row: KeyedRow): void;
|
|
19
|
+
/** Insert, or fully replace when the pk already exists (a FULL row, like `insert`). */
|
|
20
|
+
upsert(table: string, row: KeyedRow): void;
|
|
21
|
+
/** Delete the row identified by the pk columns. A missing row is a NO-OP. */
|
|
22
|
+
delete(table: string, pk: KeyedRow): void;
|
|
23
|
+
get(table: string, pk: WireValue[]): WireValue[] | undefined;
|
|
24
|
+
add(table: string, row: WireValue[]): void;
|
|
25
|
+
remove(table: string, row: WireValue[]): void;
|
|
26
|
+
edit(table: string, oldRow: WireValue[], newRow: WireValue[]): void;
|
|
27
|
+
}
|
|
28
|
+
/** A client mutator: optimistic, deterministic, replayable — a pure function of
|
|
29
|
+
* `(base, args)` (§5: no clock, no randomness; it is RE-INVOKED on every rebase). */
|
|
30
|
+
export type ClientMutator = (tx: MutationTx, args: never) => void;
|
|
31
|
+
/** The client registry (§4.2) — one of the two registries; the server's authoritative
|
|
32
|
+
* twin shares names (and possibly code), never the wire. */
|
|
33
|
+
export type ClientRegistry = Record<string, ClientMutator>;
|
|
34
|
+
export type { ResultType };
|
|
35
|
+
/** A virtual-clock seam for the fold debounce/maxWait timers (FOLDED-MUTATIONS-DESIGN §9): the
|
|
36
|
+
* oracle injects a deterministic scheduler; production defaults to real timers + `Date.now`. */
|
|
37
|
+
export interface FoldClock {
|
|
38
|
+
setTimeout(cb: () => void, ms: number): unknown;
|
|
39
|
+
clearTimeout(handle: unknown): void;
|
|
40
|
+
now(): number;
|
|
41
|
+
}
|
|
42
|
+
/** Options for a folded call site (FOLDED-MUTATIONS-DESIGN §3). `key` is the identity half of the
|
|
43
|
+
* fold key (combined with the mutator name); the rest tune the debounce policy. */
|
|
44
|
+
export interface FoldOptions {
|
|
45
|
+
/** The identity half of the fold key (typically the targeted primary key). Required. */
|
|
46
|
+
key: unknown;
|
|
47
|
+
/** Trailing debounce: the flush fires this long after the LAST invoke for `key`. Default 120ms. */
|
|
48
|
+
debounceMs?: number;
|
|
49
|
+
/** Hard cap so a never-idle drag still persists periodically (trailing throttle). Unbounded if
|
|
50
|
+
* omitted — an idle gap of `debounceMs` is then the only thing that flushes. */
|
|
51
|
+
maxWaitMs?: number;
|
|
52
|
+
/** Keep deferring across overlapping non-fold writes for maximum economy, accepting the §4.2
|
|
53
|
+
* read-dependent reorder snap. Default `false` (flush-on-enqueue — correct-and-boring). */
|
|
54
|
+
deferAcrossWrites?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/** The handle a folded call site gets back (FOLDED-MUTATIONS-DESIGN §3): no `mid` is assigned yet
|
|
57
|
+
* (§4.1), so this exposes `flush()` to force the window now and a `mid` promise that resolves with
|
|
58
|
+
* the wire id once the window flushes — a caller that needs the server ack can await it. */
|
|
59
|
+
export interface FoldHandle {
|
|
60
|
+
flush(): void;
|
|
61
|
+
readonly mid: Promise<number>;
|
|
62
|
+
}
|
|
63
|
+
export interface OptimisticBackendOptions {
|
|
64
|
+
/** Stable per-client identity for the upstream envelopes (§8.1). */
|
|
65
|
+
clientID: string;
|
|
66
|
+
/** Buffered-frame ceiling before the §8.5 escape (drop + re-hydrate). */
|
|
67
|
+
bufferCap?: number;
|
|
68
|
+
/** Virtual-clock seam for the fold debounce timers (FOLDED-MUTATIONS-DESIGN §9). Defaults to
|
|
69
|
+
* real `setTimeout`/`clearTimeout`/`Date.now`; the fold oracle injects a deterministic clock. */
|
|
70
|
+
clock?: FoldClock;
|
|
71
|
+
}
|
|
72
|
+
export declare class OptimisticBackend<S extends ColsMap> implements Backend {
|
|
73
|
+
private readonly local;
|
|
74
|
+
private readonly sync;
|
|
75
|
+
private readonly source;
|
|
76
|
+
private readonly registry;
|
|
77
|
+
private readonly clientID;
|
|
78
|
+
private readonly bufferCap;
|
|
79
|
+
/** Column order + pk indices per table, for the keyed `MutationTx` methods. */
|
|
80
|
+
private readonly specs;
|
|
81
|
+
/** Each table's full column count (union-row width) + column-name → base ColId — to learn a
|
|
82
|
+
* projected query's per-table projection off its `hello` and register it with the sync layer,
|
|
83
|
+
* so it scatters that query's narrower rows into the shared union (PROJECTION-SUPPORT-DESIGN
|
|
84
|
+
* §5.2). Without this a projected query's short rows reach the wasm `Db` un-scattered and fail
|
|
85
|
+
* its width check. */
|
|
86
|
+
private readonly colCounts;
|
|
87
|
+
private readonly colIndex;
|
|
88
|
+
/** The client's OWN typed per-table schemas + the reserved lmid table — the fixed base
|
|
89
|
+
* of the expected-schema set (CRIT#4 validation). Synthetic agg tables are appended as
|
|
90
|
+
* queries arrive (`ensureSyntheticTables`). */
|
|
91
|
+
private readonly clientTablesBase;
|
|
92
|
+
/** Synthetic aggregate tables (`__agg_*`) registered so far, by name (AGGREGATE-SYNC-DESIGN
|
|
93
|
+
* §3.3). Per aggregate DEFINITION (not per query), so two queries over the same count
|
|
94
|
+
* share one table. */
|
|
95
|
+
private readonly synthetic;
|
|
96
|
+
/** Synthetic table name → how many registered LOCAL queries reference it. A table is
|
|
97
|
+
* materialized on the `0→1` transition and reclaimed (engine source + baseline + refcount
|
|
98
|
+
* layer + overlay def) on `1→0` — so aggregate state is not permanent (§4). */
|
|
99
|
+
private readonly syntheticRefs;
|
|
100
|
+
/** Local qid → the synthetic tables it referenced at registration, to decrement on teardown. */
|
|
101
|
+
private readonly queryAggTables;
|
|
102
|
+
/** The optimistic aggregate overlay (§4–§6): the per-aggregate definitions + the per-group
|
|
103
|
+
* pending delta `displayed = server_base ⊕ local_pending_delta` is applied from. */
|
|
104
|
+
private readonly overlay;
|
|
105
|
+
private handler;
|
|
106
|
+
private pendingMutations;
|
|
107
|
+
private nextMid;
|
|
108
|
+
/** The live fold entries, by fold key `${name}\0${identityJSON}` — at most one per key
|
|
109
|
+
* (FOLDED-MUTATIONS-DESIGN §8). Insertion order is creation order (the drain/flush tiebreak). */
|
|
110
|
+
private readonly folds;
|
|
111
|
+
/** The fold debounce clock (real timers by default; the oracle injects a virtual one). */
|
|
112
|
+
private readonly clock;
|
|
113
|
+
/** The high-water confirmed mutation id, folded from the lmid system query's
|
|
114
|
+
* RELEASED ops (lmid-as-data) — never from a frame. */
|
|
115
|
+
private confirmedLmid;
|
|
116
|
+
private buffer;
|
|
117
|
+
private nextSeq;
|
|
118
|
+
private appliedCv;
|
|
119
|
+
private readonly asts;
|
|
120
|
+
/** Per query: the base tables its result can draw from (from the AST tree). */
|
|
121
|
+
private readonly queryTables;
|
|
122
|
+
private readonly remoteSubs;
|
|
123
|
+
private readonly sourceToRemote;
|
|
124
|
+
private readonly localToRemote;
|
|
125
|
+
private readonly remoteRetainToLocal;
|
|
126
|
+
private readonly resultTypes;
|
|
127
|
+
/** Local view qids that are server-authoritative: a query with no remote sub (purely local) is
|
|
128
|
+
* hydrated on registration; a remote query is hydrated when its sub's first snapshot releases.
|
|
129
|
+
* An un-hydrated query reports `unknown` (still loading) — the basis of `resultType`. */
|
|
130
|
+
private readonly hydrated;
|
|
131
|
+
private resultTypeHandler;
|
|
132
|
+
/** The pending AXIS (§7.2), split off `ResultType`: per query, whether any pending mutation
|
|
133
|
+
* touches its tables. Cached so `onPending` fires only on transitions (invoke ↔ confirm). */
|
|
134
|
+
private readonly pendingState;
|
|
135
|
+
private pendingHandler;
|
|
136
|
+
constructor(schema: Schema<S>, source: OptimisticSource, registry: ClientRegistry, opts: OptimisticBackendOptions);
|
|
137
|
+
registerQuery(qid: QueryId, ast: Ast, remote?: RemoteQuery): void;
|
|
138
|
+
/** Register every synthetic aggregate table `ast` needs that we haven't seen yet: on the
|
|
139
|
+
* local engine (which auto-tracks it for the optimistic rebase loop), on `NormalizedSync`
|
|
140
|
+
* (so its rows refcount/GC by group key), and into the source's expected-schema set (so
|
|
141
|
+
* the server's `hello` — which advertises the same table — passes CRIT#4 validation).
|
|
142
|
+
* Idempotent across queries that share an aggregate definition. */
|
|
143
|
+
private ensureSyntheticTables;
|
|
144
|
+
/** Decrement the refcount of every synthetic table query `qid` referenced; for each one that
|
|
145
|
+
* reaches 0 (no live reader left), remove it from the engine, the refcount layer, and the
|
|
146
|
+
* overlay — so aggregate state is reclaimed, not permanent (§4). Must run AFTER
|
|
147
|
+
* `local.unregisterQuery(qid)` so the engine source has no live connection when
|
|
148
|
+
* `unregisterTable` frees it (the engine refuses otherwise). */
|
|
149
|
+
private releaseSyntheticTables;
|
|
150
|
+
unregisterQuery(qid: QueryId): void;
|
|
151
|
+
retainRemoteQuery(qid: QueryId, remote: RemoteQuery, localQueryId?: QueryId): void;
|
|
152
|
+
releaseRemoteQuery(qid: QueryId): void;
|
|
153
|
+
/** Raw CRUD has no optimistic story (§9 replaces it with named mutators). Register a
|
|
154
|
+
* mutator — even a trivial one — and `invoke` it. */
|
|
155
|
+
mutate(_mutations: Mutation[]): Promise<void>;
|
|
156
|
+
onEvent(handler: (qid: QueryId, ev: ChangeEvent) => void): void;
|
|
157
|
+
/** Run the named client mutator optimistically: the prediction applies to the live
|
|
158
|
+
* engine now (affected views update synchronously), `(mid, name, args)` joins the
|
|
159
|
+
* pending stack, and the envelope ships upstream. Returns the assigned `mid`. */
|
|
160
|
+
invoke(name: string, args: unknown): number;
|
|
161
|
+
/** Run a FOLDED invoke (FOLDED-MUTATIONS-DESIGN §8): apply the prediction to the live engine now
|
|
162
|
+
* (like `invoke`), but collapse a run of same-key invokes into ONE pending entry whose `args`
|
|
163
|
+
* are overwritten in place, debounce the server write, and ship only the last value. The `mid`
|
|
164
|
+
* is assigned at flush, not here (§4.1) — so the return is a {@link FoldHandle}, not a mid. */
|
|
165
|
+
invokeFolded(name: string, opts: FoldOptions, args: unknown): FoldHandle;
|
|
166
|
+
/** Flush-on-enqueue (§4.2): for each outstanding fold whose touched tables overlap `tables`,
|
|
167
|
+
* assign its mid NOW and ship it — in creation (insertion) order, so the wire stays gapless. A
|
|
168
|
+
* `deferAcrossWrites` fold opts out (it keeps deferring, accepting the read-dependent snap). The
|
|
169
|
+
* incoming write's own fold key (if any) is skipped — it is being folded into, not flushed. */
|
|
170
|
+
private drainOverlapping;
|
|
171
|
+
/** Flush one fold (§8): deal its `mid` from `nextMid` (SEND order — never reserved, so gapless
|
|
172
|
+
* by construction), stamp the entry, ship the envelope with the LATEST args, resolve the handle.
|
|
173
|
+
* The entry stays on `pendingMutations` (now with a real mid) until the lmid release confirms it. */
|
|
174
|
+
private flushFold;
|
|
175
|
+
/** Drain every outstanding fold immediately (FOLDED-MUTATIONS-DESIGN §3): the explicit
|
|
176
|
+
* `app.flushFolds()` and the `beforeunload`/`close` hook. Creation (insertion) order. */
|
|
177
|
+
flushFolds(): void;
|
|
178
|
+
/** A `trackingTx` op collector that records only the ops over a tracked aggregate's child
|
|
179
|
+
* table (the others can't move any count). Applied to the overlay by the caller AFTER the
|
|
180
|
+
* mutator succeeds, so a throwing mutator (whose staged write is discarded) leaves no delta. */
|
|
181
|
+
private opCollector;
|
|
182
|
+
/** Push the optimistic per-group delta onto the `__agg` head rows (§4):
|
|
183
|
+
* `target = server_base ⊕ delta`. A head-only write to the (tracked) synthetic table, so it
|
|
184
|
+
* joins the optimistic layer and is rewound/rebuilt by the reconcile cycle like any
|
|
185
|
+
* prediction. `server_base` is read from `NormalizedSync` (the authoritative base) — NOT
|
|
186
|
+
* from head, which already carries the optimistic layer (a torn read). Works standalone (an
|
|
187
|
+
* ordinary delivery) and inside an open cycle (the write buffers into it). */
|
|
188
|
+
private reconcileAggHead;
|
|
189
|
+
/** The SERVER CHANNEL's state for a query (§7): `unknown` while not hydrated, else `complete`.
|
|
190
|
+
* A pending local mutation no longer moves it — see {@link pending}. */
|
|
191
|
+
resultType(qid: QueryId): ResultType;
|
|
192
|
+
onResultType(handler: (qid: QueryId, rt: ResultType) => void): void;
|
|
193
|
+
/** Whether any pending mutation (folded or not) touches this query's tables — "is a prediction
|
|
194
|
+
* pending here?" (FOLDED-MUTATIONS-DESIGN §7.2). Orthogonal to {@link resultType}; this is the
|
|
195
|
+
* same `queryTables ∩ pending.touched` computation that used to be smuggled into `unknown`. */
|
|
196
|
+
pending(qid: QueryId): boolean;
|
|
197
|
+
/** Reactive pending axis (§7.2): fires when a query's pending-ness flips (invoke ↔ confirm), so a
|
|
198
|
+
* "saving…" affordance clears on its own when `lmid` catches up. */
|
|
199
|
+
onPending(handler: (qid: QueryId, pending: boolean) => void): void;
|
|
200
|
+
/** The coarse, table-level pending indicator set (§7.2): every table some pending mutation touched. */
|
|
201
|
+
pendingTables(): Set<string>;
|
|
202
|
+
/** Recompute the pending axis for every query and fire `onPending` on transitions only. Called
|
|
203
|
+
* from the two points that move the pending set: invoke/invokeFolded (add) and the confirm-drop
|
|
204
|
+
* (remove) — exactly where `:359`/`:468` used to flip ResultType (§7.3). */
|
|
205
|
+
private refreshPending;
|
|
206
|
+
private onNormalized;
|
|
207
|
+
private onProgress;
|
|
208
|
+
/** Fold the lmid system query's released ops (lmid-as-data): the one row's
|
|
209
|
+
* `last_mutation_id` cell is this client's confirmed high-water mid. */
|
|
210
|
+
private foldLmidOps;
|
|
211
|
+
/** One §1.3 reconcile cycle: rewind the optimistic layer and fold the coherent SERVER
|
|
212
|
+
* delta into BOTH head AND the `sync` baseline (`serverBatchBegin`), re-invoke every
|
|
213
|
+
* still-pending mutator to re-stage the optimistic layer (the rewind un-applied it), then
|
|
214
|
+
* deliver the coalesced result (`serverBatchEnd`). This is the engine's only sync-moving
|
|
215
|
+
* boundary — `onProgress` releases and `unregisterQuery`'s GC both go through here so head
|
|
216
|
+
* and sync never diverge (the §1.2 invariant; CRIT#2). */
|
|
217
|
+
private runReconcileCycle;
|
|
218
|
+
/** The daemon restarted (a new boot id): it lost all materialization + `cv` state and its `cv`
|
|
219
|
+
* sequence reset, so previously-released `cv`s no longer bound the new stream. The source has
|
|
220
|
+
* already re-subscribed every query (reconnect → resync); drop the buffer and the `cv`
|
|
221
|
+
* watermark so the fresh, low-`cv` snapshots are RELEASED instead of dropped as stale
|
|
222
|
+
* (`onNormalized`/`onProgress` gate on `appliedCv`). Pending optimistic mutations stay put —
|
|
223
|
+
* they re-apply on the next reconcile, and the lmid system query's fresh snapshot restores the
|
|
224
|
+
* confirmation watermark. */
|
|
225
|
+
private resetForRestart;
|
|
226
|
+
/** The §8.5 escape: the buffer outgrew its cap (a pinned `cvMin` under churn). Drop
|
|
227
|
+
* everything buffered and re-register every query on the source — the fresh
|
|
228
|
+
* snapshots arrive as ordinary frames and the next release re-hydrates via the
|
|
229
|
+
* footprint diff (the §5.3 path); still-pending optimism re-applies in that cycle. */
|
|
230
|
+
private overflow;
|
|
231
|
+
private setResultType;
|
|
232
|
+
/** Recompute a query's server-channel state from hydration alone (§7): a pending mutation no
|
|
233
|
+
* longer affects it. Used when a remote sub attaches to or hydrates a local view. */
|
|
234
|
+
private recomputeResultType;
|
|
235
|
+
/** A remote sub's first snapshot landed: mark it (and every local view it feeds) hydrated, then
|
|
236
|
+
* lift those views out of `unknown` (loading). Idempotent — a re-hydrate snapshot re-marks
|
|
237
|
+
* harmlessly; a source qid with no sub (the lmid system query) is a no-op. */
|
|
238
|
+
private markSubHydrated;
|
|
239
|
+
private retainRemote;
|
|
240
|
+
private releaseRemote;
|
|
241
|
+
private addServerDependencyTables;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
|