@rindle/room 0.5.0

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.
@@ -0,0 +1,924 @@
1
+ /* @ts-self-types="./rindle_room.d.ts" */
2
+
3
+ /**
4
+ * One room instance: the upstream-fed base store plus its downstream serving state
5
+ * (materialized queries deduped by `QueryKey`, subscribers addressed by the host's
6
+ * opaque keys) and — once [`enableWrites`](Self::enable_writes) runs — the §5.1
7
+ * write plane, with **at most one mutation transaction open at a time** (the room is
8
+ * an actor; the host serializes mutations onto it).
9
+ */
10
+ export class WasmRoom {
11
+ static __wrap(ptr) {
12
+ const obj = Object.create(WasmRoom.prototype);
13
+ obj.__wbg_ptr = ptr;
14
+ WasmRoomFinalization.register(obj, obj.__wbg_ptr, obj);
15
+ return obj;
16
+ }
17
+ __destroy_into_raw() {
18
+ const ptr = this.__wbg_ptr;
19
+ this.__wbg_ptr = 0;
20
+ WasmRoomFinalization.unregister(this);
21
+ return ptr;
22
+ }
23
+ free() {
24
+ const ptr = this.__destroy_into_raw();
25
+ wasm.__wbg_wasmroom_free(ptr, 0);
26
+ }
27
+ /**
28
+ * Advance the ledger rows for journal-committed mutations — **the ack** (§5.1
29
+ * step 4; call once the journal append resolves). `entries_json` is a JSON array
30
+ * of `{clientID, mid}`. Returns `{"headCv": n}` — drain
31
+ * [`commitAll`](Self::commit_all) to ship the lmid frames — or `{"headCv": null}`
32
+ * when everything was already covered.
33
+ * @param {string} entries_json
34
+ * @returns {string}
35
+ */
36
+ ack(entries_json) {
37
+ let deferred3_0;
38
+ let deferred3_1;
39
+ try {
40
+ const ptr0 = passStringToWasm0(entries_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
41
+ const len0 = WASM_VECTOR_LEN;
42
+ const ret = wasm.wasmroom_ack(this.__wbg_ptr, ptr0, len0);
43
+ var ptr2 = ret[0];
44
+ var len2 = ret[1];
45
+ if (ret[3]) {
46
+ ptr2 = 0; len2 = 0;
47
+ throw takeFromExternrefTable0(ret[2]);
48
+ }
49
+ deferred3_0 = ptr2;
50
+ deferred3_1 = len2;
51
+ return getStringFromWasm0(ptr2, len2);
52
+ } finally {
53
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
54
+ }
55
+ }
56
+ /**
57
+ * The ledger row's current value for `clientID` (0 if none) — what the wire has
58
+ * confirmed.
59
+ * @param {string} client_id
60
+ * @returns {number}
61
+ */
62
+ ackedLmid(client_id) {
63
+ const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
64
+ const len0 = WASM_VECTOR_LEN;
65
+ const ret = wasm.wasmroom_ackedLmid(this.__wbg_ptr, ptr0, len0);
66
+ return ret;
67
+ }
68
+ /**
69
+ * The highest mid applied to the head for `clientID` (0 if none) — the dedup
70
+ * watermark; diagnostics and the crash-replay tests read it.
71
+ * @param {string} client_id
72
+ * @returns {number}
73
+ */
74
+ appliedMid(client_id) {
75
+ const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
76
+ const len0 = WASM_VECTOR_LEN;
77
+ const ret = wasm.wasmroom_appliedMid(this.__wbg_ptr, ptr0, len0);
78
+ return ret;
79
+ }
80
+ /**
81
+ * Apply one upstream `nbatch` frame's `batch` object (JSON text). Returns a status
82
+ * object (JSON text): `{applied: "snapshot", rows}` | `{applied: "live", ops}` |
83
+ * `{applied: "duplicate"}` | `{applied: "staleEpoch", expected, got}`. Throws when
84
+ * the frame is garbage or the apply poisons the store — in both cases the host
85
+ * tears down and re-subscribes under a new epoch (§3.4); there is no repair call.
86
+ *
87
+ * After a `live`/`snapshot` apply, drain the fan-out with
88
+ * [`commitAll`](Self::commit_all).
89
+ * @param {string} batch_json
90
+ * @returns {string}
91
+ */
92
+ apply(batch_json) {
93
+ let deferred3_0;
94
+ let deferred3_1;
95
+ try {
96
+ const ptr0 = passStringToWasm0(batch_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
97
+ const len0 = WASM_VECTOR_LEN;
98
+ const ret = wasm.wasmroom_apply(this.__wbg_ptr, ptr0, len0);
99
+ var ptr2 = ret[0];
100
+ var len2 = ret[1];
101
+ if (ret[3]) {
102
+ ptr2 = 0; len2 = 0;
103
+ throw takeFromExternrefTable0(ret[2]);
104
+ }
105
+ deferred3_0 = ptr2;
106
+ deferred3_1 = len2;
107
+ return getStringFromWasm0(ptr2, len2);
108
+ } finally {
109
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
110
+ }
111
+ }
112
+ /**
113
+ * Build the §5.3 net-effect batch from the dirty entries + ledger co-edits.
114
+ * Returns `undefined` when there is nothing to flush, else JSON text
115
+ * `{changes, batchHash, lmids}`: `changes` is the `/apply-row-change-txn`
116
+ * `changes[]` array (ingest shape, old-images = the CAS base chain), `batchHash`
117
+ * the batch identity computed over its canonical bytes, `lmids` the
118
+ * `{clientID, mid}` advances the batch covers. At most one flush may be in
119
+ * flight — resolve with [`flushOk`](Self::flush_ok) or
120
+ * [`flushConflict`](Self::flush_conflict); retries resubmit the SAME journaled
121
+ * body, never a rebuilt one.
122
+ * @returns {string | undefined}
123
+ */
124
+ beginFlush() {
125
+ const ret = wasm.wasmroom_beginFlush(this.__wbg_ptr);
126
+ if (ret[3]) {
127
+ throw takeFromExternrefTable0(ret[2]);
128
+ }
129
+ let v1;
130
+ if (ret[0] !== 0) {
131
+ v1 = getStringFromWasm0(ret[0], ret[1]).slice();
132
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
133
+ }
134
+ return v1;
135
+ }
136
+ /**
137
+ * Open the transaction for `(clientID, mid)`. Returns `{"begin": "tx"}` (run the
138
+ * mutator, then [`commitMutation`](Self::commit_mutation) or
139
+ * [`rejectMutation`](Self::reject_mutation)) or `{"begin": "dedup"}` (an absorbed
140
+ * redelivery — send nothing). Throws on a mid gap with the exact
141
+ * `mutation gap for …` message the client's recovery keys on — forward it on an
142
+ * `error` frame. At most one transaction may be open.
143
+ *
144
+ * `name`/`args_json` (optional, Slice I-ii) are the wire envelope's mutator name
145
+ * and JSON-text args: should this mid end non-applied, its durable outcome row
146
+ * echoes them on a DEOPT (self-contained re-invoke, mirroring the H-iv-b frame).
147
+ * Omitting them degrades deopt rows to NULL name/args, nothing else.
148
+ * @param {string} client_id
149
+ * @param {number} mid
150
+ * @param {string | null} [name]
151
+ * @param {string | null} [args_json]
152
+ * @returns {string}
153
+ */
154
+ beginMutation(client_id, mid, name, args_json) {
155
+ let deferred5_0;
156
+ let deferred5_1;
157
+ try {
158
+ const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
159
+ const len0 = WASM_VECTOR_LEN;
160
+ var ptr1 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
161
+ var len1 = WASM_VECTOR_LEN;
162
+ var ptr2 = isLikeNone(args_json) ? 0 : passStringToWasm0(args_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
163
+ var len2 = WASM_VECTOR_LEN;
164
+ const ret = wasm.wasmroom_beginMutation(this.__wbg_ptr, ptr0, len0, mid, ptr1, len1, ptr2, len2);
165
+ var ptr4 = ret[0];
166
+ var len4 = ret[1];
167
+ if (ret[3]) {
168
+ ptr4 = 0; len4 = 0;
169
+ throw takeFromExternrefTable0(ret[2]);
170
+ }
171
+ deferred5_0 = ptr4;
172
+ deferred5_1 = len4;
173
+ return getStringFromWasm0(ptr4, len4);
174
+ } finally {
175
+ wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
176
+ }
177
+ }
178
+ /**
179
+ * Drain every materialized query once and return the fan-out as JSON text:
180
+ * `[{sub, batch}, …]` — one entry per attached subscriber per query with a
181
+ * non-empty net delta, each `batch` stamped with that subscriber's own epoch/seq.
182
+ * Empty array when nothing changed (or the store is no longer live — a dead
183
+ * incarnation must not ship a torn frame).
184
+ * @returns {string}
185
+ */
186
+ commitAll() {
187
+ let deferred1_0;
188
+ let deferred1_1;
189
+ try {
190
+ const ret = wasm.wasmroom_commitAll(this.__wbg_ptr);
191
+ deferred1_0 = ret[0];
192
+ deferred1_1 = ret[1];
193
+ return getStringFromWasm0(ret[0], ret[1]);
194
+ } finally {
195
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
196
+ }
197
+ }
198
+ /**
199
+ * Apply the open transaction to the head as one local commit: dirty entries are
200
+ * captured, the applied watermark advances, and every attached query sees the ops.
201
+ * Returns `{"headCv": n}` — drain [`commitAll`](Self::commit_all) and fan out NOW
202
+ * (§5.1 step 2: data fanout is never gated on durability), then journal the
203
+ * envelope and [`ack`](Self::ack) once the append commits. Throws only when the
204
+ * commit tears the head (store poisoned — tear down).
205
+ *
206
+ * Under [`enableWritesV2`](Self::enable_writes_v2) the §3.3 commit gate runs
207
+ * first; a containment violation returns `{"deopt": {reason, table, pk, …}}`
208
+ * instead (`reason`: `"writeOutOfScope"` (+ `op`) | `"joinKeyChanged"`
209
+ * (+ `column`) | `"absentReadUnproven"`): **nothing was applied**, the tx is
210
+ * consumed and the mid burnt exactly like [`rejectMutation`](Self::reject_mutation)
211
+ * (do NOT call it too) — journal the envelope as rejected and [`ack`](Self::ack)
212
+ * as usual, answering the client with a deopt. Under the v1 enable the return is
213
+ * always `{"headCv": n}`, byte-identical to before.
214
+ * @returns {string}
215
+ */
216
+ commitMutation() {
217
+ let deferred2_0;
218
+ let deferred2_1;
219
+ try {
220
+ const ret = wasm.wasmroom_commitMutation(this.__wbg_ptr);
221
+ var ptr1 = ret[0];
222
+ var len1 = ret[1];
223
+ if (ret[3]) {
224
+ ptr1 = 0; len1 = 0;
225
+ throw takeFromExternrefTable0(ret[2]);
226
+ }
227
+ deferred2_0 = ptr1;
228
+ deferred2_1 = len1;
229
+ return getStringFromWasm0(ptr1, len1);
230
+ } finally {
231
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
232
+ }
233
+ }
234
+ /**
235
+ * The last-applied upstream commit version (`undefined` before the seq-0 snapshot).
236
+ * This is the journal cursor's `cv` half — persist `(epoch, cv)` to resume (§3.3).
237
+ * @returns {number | undefined}
238
+ */
239
+ cv() {
240
+ const ret = wasm.wasmroom_cv(this.__wbg_ptr);
241
+ return ret[0] === 0 ? undefined : ret[1];
242
+ }
243
+ /**
244
+ * How many `(table, pk)` keys are dirty (§5.3 — P3's flush input).
245
+ * @returns {number}
246
+ */
247
+ dirtyLen() {
248
+ const ret = wasm.wasmroom_dirtyLen(this.__wbg_ptr);
249
+ return ret;
250
+ }
251
+ /**
252
+ * The highest mid the write authority has committed for `clientID` (0 if none) —
253
+ * §8.1's `durable` level.
254
+ * @param {string} client_id
255
+ * @returns {number}
256
+ */
257
+ durableLmid(client_id) {
258
+ const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
259
+ const len0 = WASM_VECTOR_LEN;
260
+ const ret = wasm.wasmroom_durableLmid(this.__wbg_ptr, ptr0, len0);
261
+ return ret;
262
+ }
263
+ /**
264
+ * Enable the §5.1 write plane over a live store: `owned_json` is a JSON array of
265
+ * the tables mutators may write (§3.2's owned set — must all be in the upstream
266
+ * hello). Registers the `_rindle_client_mutations` ledger; call once, right after
267
+ * the seq-0 snapshot applies and before serving. Idempotence is deliberate-ly NOT
268
+ * provided: enabling twice is a shell bug and throws.
269
+ * @param {string} owned_json
270
+ */
271
+ enableWrites(owned_json) {
272
+ const ptr0 = passStringToWasm0(owned_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
273
+ const len0 = WASM_VECTOR_LEN;
274
+ const ret = wasm.wasmroom_enableWrites(this.__wbg_ptr, ptr0, len0);
275
+ if (ret[1]) {
276
+ throw takeFromExternrefTable0(ret[0]);
277
+ }
278
+ }
279
+ /**
280
+ * Enable the write plane with per-table **scope specs** — the §3.3 room commit
281
+ * gate (H-iv-a). `specs_json` is a JSON array of
282
+ * `{ table, footprintWhere?, writable }` where `writable` is the lease block's
283
+ * `RoomTableSpec.writable` shape (`{kind:"none"}` for a context table,
284
+ * `{kind:"predicate", where?, joinKeyCols}` for a writable one) and
285
+ * `footprintWhere` is the footprint's row-local wire `Condition` for the table
286
+ * (drives the absent-read proof). Predicates compile NOW, loudly — a malformed or
287
+ * non-row-local spec (e.g. a `correlatedSubquery`) throws and nothing is enabled.
288
+ * With the gate armed, [`commitMutation`](Self::commit_mutation) can return a
289
+ * `{"deopt": …}` verdict. Same once-only/live-store rules as
290
+ * [`enableWrites`](Self::enable_writes), which remains the legacy table-granular
291
+ * entry (its gate proves nothing and never deopts).
292
+ * @param {string} specs_json
293
+ */
294
+ enableWritesV2(specs_json) {
295
+ const ptr0 = passStringToWasm0(specs_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
296
+ const len0 = WASM_VECTOR_LEN;
297
+ const ret = wasm.wasmroom_enableWritesV2(this.__wbg_ptr, ptr0, len0);
298
+ if (ret[1]) {
299
+ throw takeFromExternrefTable0(ret[0]);
300
+ }
301
+ }
302
+ /**
303
+ * The upstream subscription epoch this store was opened under.
304
+ * @returns {number}
305
+ */
306
+ epoch() {
307
+ const ret = wasm.wasmroom_epoch(this.__wbg_ptr);
308
+ return ret;
309
+ }
310
+ /**
311
+ * The authority rejected the in-flight batch on CAS (§5.4 `flush_conflict`):
312
+ * `conflicts_json` is its `409` body's `conflicts` array —
313
+ * `[{table, pk, current}]`, `current: null` for an absent row. Each conflicted
314
+ * key converges to the authority's image (the local net effect is dropped);
315
+ * everything else stays dirty and retries next flush. Returns
316
+ * `{"headCv": n | null}` — drain [`commitAll`](Self::commit_all) after a
317
+ * non-null cv to ship the corrective frames.
318
+ * @param {string} conflicts_json
319
+ * @returns {string}
320
+ */
321
+ flushConflict(conflicts_json) {
322
+ let deferred3_0;
323
+ let deferred3_1;
324
+ try {
325
+ const ptr0 = passStringToWasm0(conflicts_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
326
+ const len0 = WASM_VECTOR_LEN;
327
+ const ret = wasm.wasmroom_flushConflict(this.__wbg_ptr, ptr0, len0);
328
+ var ptr2 = ret[0];
329
+ var len2 = ret[1];
330
+ if (ret[3]) {
331
+ ptr2 = 0; len2 = 0;
332
+ throw takeFromExternrefTable0(ret[2]);
333
+ }
334
+ deferred3_0 = ptr2;
335
+ deferred3_1 = len2;
336
+ return getStringFromWasm0(ptr2, len2);
337
+ } finally {
338
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
339
+ }
340
+ }
341
+ /**
342
+ * Whether a §5.3 flush is in flight (diagnostics; the shell also guards).
343
+ * @returns {boolean}
344
+ */
345
+ flushInFlight() {
346
+ const ret = wasm.wasmroom_flushInFlight(this.__wbg_ptr);
347
+ return ret !== 0;
348
+ }
349
+ /**
350
+ * The authority committed the in-flight batch (§5.3 step 6): consumed entries
351
+ * retire (or re-base onto the image just written, if re-dirtied mid-flight),
352
+ * durable watermarks advance, `pending ≤` them retires. Returns
353
+ * `{"retired": n, "dirty": n}` — a non-zero `dirty` means writes landed during
354
+ * the flight; schedule the next flush.
355
+ * @returns {string}
356
+ */
357
+ flushOk() {
358
+ let deferred2_0;
359
+ let deferred2_1;
360
+ try {
361
+ const ret = wasm.wasmroom_flushOk(this.__wbg_ptr);
362
+ var ptr1 = ret[0];
363
+ var len1 = ret[1];
364
+ if (ret[3]) {
365
+ ptr1 = 0; len1 = 0;
366
+ throw takeFromExternrefTable0(ret[2]);
367
+ }
368
+ deferred2_0 = ptr1;
369
+ deferred2_1 = len1;
370
+ return getStringFromWasm0(ptr1, len1);
371
+ } finally {
372
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
373
+ }
374
+ }
375
+ /**
376
+ * The room's own commit order — what downstream frames are stamped with and what
377
+ * the shell's `progress {cvMin}` release points are computed from. Advances on
378
+ * every upstream apply and every local commit (see `RoomStore::head_cv`).
379
+ * @returns {number}
380
+ */
381
+ headCv() {
382
+ const ret = wasm.wasmroom_headCv(this.__wbg_ptr);
383
+ return ret;
384
+ }
385
+ /**
386
+ * Baseline present and not poisoned — the store is serving.
387
+ * @returns {boolean}
388
+ */
389
+ isLive() {
390
+ const ret = wasm.wasmroom_isLive(this.__wbg_ptr);
391
+ return ret !== 0;
392
+ }
393
+ /**
394
+ * A failed apply left this incarnation dead (§3.4): tear down, re-subscribe.
395
+ * @returns {boolean}
396
+ */
397
+ isPoisoned() {
398
+ const ret = wasm.wasmroom_isPoisoned(this.__wbg_ptr);
399
+ return ret !== 0;
400
+ }
401
+ /**
402
+ * Subscribe `sub` to the reserved per-client lmid query (`_rindle/clientLmid`):
403
+ * the room composes the `_rindle_client_mutations WHERE client_id = <clientID>`
404
+ * AST itself — identity comes from the connection's `init`, never client args.
405
+ * Same return shape and envelope rules as [`subscribe`](Self::subscribe).
406
+ * @param {string} sub
407
+ * @param {number} epoch
408
+ * @param {string} client_id
409
+ * @param {number} now_ms
410
+ * @returns {string}
411
+ */
412
+ lmidSubscribe(sub, epoch, client_id, now_ms) {
413
+ let deferred4_0;
414
+ let deferred4_1;
415
+ try {
416
+ const ptr0 = passStringToWasm0(sub, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
417
+ const len0 = WASM_VECTOR_LEN;
418
+ const ptr1 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
419
+ const len1 = WASM_VECTOR_LEN;
420
+ const ret = wasm.wasmroom_lmidSubscribe(this.__wbg_ptr, ptr0, len0, epoch, ptr1, len1, now_ms);
421
+ var ptr3 = ret[0];
422
+ var len3 = ret[1];
423
+ if (ret[3]) {
424
+ ptr3 = 0; len3 = 0;
425
+ throw takeFromExternrefTable0(ret[2]);
426
+ }
427
+ deferred4_0 = ptr3;
428
+ deferred4_1 = len3;
429
+ return getStringFromWasm0(ptr3, len3);
430
+ } finally {
431
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
432
+ }
433
+ }
434
+ /**
435
+ * How many downstream queries are currently materialized (post-dedup).
436
+ * @returns {number}
437
+ */
438
+ materializationCount() {
439
+ const ret = wasm.wasmroom_materializationCount(this.__wbg_ptr);
440
+ return ret;
441
+ }
442
+ /**
443
+ * Open the room's base store from the upstream `nhello` frame's `hello` object
444
+ * (JSON text). `idle_ttl_ms` is the downstream retention grace: a materialized
445
+ * query with no subscribers for that long is reclaimed by [`sweep`](Self::sweep).
446
+ * Rejects malformed hellos loudly — nothing is constructed.
447
+ * @param {string} hello_json
448
+ * @param {number} idle_ttl_ms
449
+ * @returns {WasmRoom}
450
+ */
451
+ static open(hello_json, idle_ttl_ms) {
452
+ const ptr0 = passStringToWasm0(hello_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
453
+ const len0 = WASM_VECTOR_LEN;
454
+ const ret = wasm.wasmroom_open(ptr0, len0, idle_ttl_ms);
455
+ if (ret[2]) {
456
+ throw takeFromExternrefTable0(ret[1]);
457
+ }
458
+ return WasmRoom.__wrap(ret[0]);
459
+ }
460
+ /**
461
+ * Applied-but-not-retired mutations (everything, until P3's write-behind).
462
+ * @returns {number}
463
+ */
464
+ pendingLen() {
465
+ const ret = wasm.wasmroom_pendingLen(this.__wbg_ptr);
466
+ return ret;
467
+ }
468
+ /**
469
+ * Drop the open transaction's staged ops and consume its mid anyway — the reject
470
+ * path (unknown mutator, mutator threw, staging refusal, a replayed non-applied
471
+ * journal entry). The stream stays contiguous; the eventual [`ack`](Self::ack)
472
+ * advances the ledger with no effects, snapping the author's prediction back.
473
+ *
474
+ * `kind` (`"rejected"` (default) | `"deopt"`) + `reason` are the shell's H-iv-b
475
+ * classification of the verdict: the outcome is RECORDED (Slice I-ii) and its
476
+ * durable row rides the next flush beside the covering lmid co-edit — one
477
+ * authority transaction, so a post-downgrade client resolving through the daemon
478
+ * never reads a burnt non-applied mid as applied. A deopt row echoes the
479
+ * [`beginMutation`](Self::begin_mutation) envelope's `name`/`args`.
480
+ * @param {string | null} [kind]
481
+ * @param {string | null} [reason]
482
+ */
483
+ rejectMutation(kind, reason) {
484
+ var ptr0 = isLikeNone(kind) ? 0 : passStringToWasm0(kind, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
485
+ var len0 = WASM_VECTOR_LEN;
486
+ var ptr1 = isLikeNone(reason) ? 0 : passStringToWasm0(reason, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
487
+ var len1 = WASM_VECTOR_LEN;
488
+ const ret = wasm.wasmroom_rejectMutation(this.__wbg_ptr, ptr0, len0, ptr1, len1);
489
+ if (ret[1]) {
490
+ throw takeFromExternrefTable0(ret[0]);
491
+ }
492
+ }
493
+ /**
494
+ * Seed the durable watermarks from the write authority's ledger — the boot probe
495
+ * (§3.3; T2's committed-before-crash row). Call after [`enableWrites`] and
496
+ * **before** the journal replay: seeded mids replay as dedup instead of
497
+ * re-invoking. `seeds_json` is a JSON array of `{clientID, lmid}`. Returns
498
+ * `{"headCv": n | null}` — the ledger rows ride a local commit so the client's
499
+ * lmid slice confirms them.
500
+ *
501
+ * [`enableWrites`]: Self::enable_writes
502
+ * @param {string} seeds_json
503
+ * @returns {string}
504
+ */
505
+ seedDurable(seeds_json) {
506
+ let deferred3_0;
507
+ let deferred3_1;
508
+ try {
509
+ const ptr0 = passStringToWasm0(seeds_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
510
+ const len0 = WASM_VECTOR_LEN;
511
+ const ret = wasm.wasmroom_seedDurable(this.__wbg_ptr, ptr0, len0);
512
+ var ptr2 = ret[0];
513
+ var len2 = ret[1];
514
+ if (ret[3]) {
515
+ ptr2 = 0; len2 = 0;
516
+ throw takeFromExternrefTable0(ret[2]);
517
+ }
518
+ deferred3_0 = ptr2;
519
+ deferred3_1 = len2;
520
+ return getStringFromWasm0(ptr2, len2);
521
+ } finally {
522
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
523
+ }
524
+ }
525
+ /**
526
+ * Materialize-on-presentation (§10.1): attach subscriber `sub` (the host's opaque
527
+ * routing key) at `epoch` to the query for this approved wire `Ast` (JSON text) —
528
+ * reusing the pipeline on a `QueryKey` hit. Returns
529
+ * `{queryKey, reused, hello, snapshot}` (JSON text): send `nhello(hello)` then
530
+ * `nbatch(snapshot)` (its `seq` is 0), then this subscriber's entries from each
531
+ * [`commitAll`](Self::commit_all). Re-subscribing an existing `sub` replaces its
532
+ * envelope — pass the bumped `epoch`, exactly as before.
533
+ * @param {string} sub
534
+ * @param {number} epoch
535
+ * @param {string} ast_json
536
+ * @param {number} now_ms
537
+ * @returns {string}
538
+ */
539
+ subscribe(sub, epoch, ast_json, now_ms) {
540
+ let deferred4_0;
541
+ let deferred4_1;
542
+ try {
543
+ const ptr0 = passStringToWasm0(sub, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
544
+ const len0 = WASM_VECTOR_LEN;
545
+ const ptr1 = passStringToWasm0(ast_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
546
+ const len1 = WASM_VECTOR_LEN;
547
+ const ret = wasm.wasmroom_subscribe(this.__wbg_ptr, ptr0, len0, epoch, ptr1, len1, now_ms);
548
+ var ptr3 = ret[0];
549
+ var len3 = ret[1];
550
+ if (ret[3]) {
551
+ ptr3 = 0; len3 = 0;
552
+ throw takeFromExternrefTable0(ret[2]);
553
+ }
554
+ deferred4_0 = ptr3;
555
+ deferred4_1 = len3;
556
+ return getStringFromWasm0(ptr3, len3);
557
+ } finally {
558
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
559
+ }
560
+ }
561
+ /**
562
+ * How many downstream subscribers are currently attached.
563
+ * @returns {number}
564
+ */
565
+ subscriberCount() {
566
+ const ret = wasm.wasmroom_subscriberCount(this.__wbg_ptr);
567
+ return ret;
568
+ }
569
+ /**
570
+ * Reclaim downstream queries idle past their grace window, on the host's clock.
571
+ * Returns how many were destroyed.
572
+ * @param {number} now_ms
573
+ * @returns {number}
574
+ */
575
+ sweep(now_ms) {
576
+ const ret = wasm.wasmroom_sweep(this.__wbg_ptr, now_ms);
577
+ if (ret[2]) {
578
+ throw takeFromExternrefTable0(ret[1]);
579
+ }
580
+ return ret[0];
581
+ }
582
+ /**
583
+ * Stage an add of a full-width row (JSON-array text). Clean refusal (throw, head
584
+ * untouched) when the key exists, the table is not owned, or the width is wrong —
585
+ * catch it and reject the mutation.
586
+ * @param {string} table
587
+ * @param {string} row_json
588
+ */
589
+ txAdd(table, row_json) {
590
+ const ptr0 = passStringToWasm0(table, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
591
+ const len0 = WASM_VECTOR_LEN;
592
+ const ptr1 = passStringToWasm0(row_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
593
+ const len1 = WASM_VECTOR_LEN;
594
+ const ret = wasm.wasmroom_txAdd(this.__wbg_ptr, ptr0, len0, ptr1, len1);
595
+ if (ret[1]) {
596
+ throw takeFromExternrefTable0(ret[0]);
597
+ }
598
+ }
599
+ /**
600
+ * Stage an edit to a full-width row (JSON-array text) keyed by its pk cells. The
601
+ * shell resolves partial updates against [`txGet`](Self::tx_get) first — only
602
+ * concrete cells cross this boundary (JSON has no `undefined`). The pk must not
603
+ * change; the row must exist.
604
+ * @param {string} table
605
+ * @param {string} row_json
606
+ */
607
+ txEdit(table, row_json) {
608
+ const ptr0 = passStringToWasm0(table, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
609
+ const len0 = WASM_VECTOR_LEN;
610
+ const ptr1 = passStringToWasm0(row_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
611
+ const len1 = WASM_VECTOR_LEN;
612
+ const ret = wasm.wasmroom_txEdit(this.__wbg_ptr, ptr0, len0, ptr1, len1);
613
+ if (ret[1]) {
614
+ throw takeFromExternrefTable0(ret[0]);
615
+ }
616
+ }
617
+ /**
618
+ * The effective row for `pk_json` (a JSON array of pk cells, `primaryKey` order):
619
+ * the live head under this transaction's own staged writes — read-your-writes for
620
+ * read-dependent mutators, and what the keyed `update`/`delete`/`upsert` layers
621
+ * probe before composing their writes. Returns the row as JSON-array text, or
622
+ * `undefined` when absent.
623
+ * @param {string} table
624
+ * @param {string} pk_json
625
+ * @returns {string | undefined}
626
+ */
627
+ txGet(table, pk_json) {
628
+ const ptr0 = passStringToWasm0(table, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
629
+ const len0 = WASM_VECTOR_LEN;
630
+ const ptr1 = passStringToWasm0(pk_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
631
+ const len1 = WASM_VECTOR_LEN;
632
+ const ret = wasm.wasmroom_txGet(this.__wbg_ptr, ptr0, len0, ptr1, len1);
633
+ if (ret[3]) {
634
+ throw takeFromExternrefTable0(ret[2]);
635
+ }
636
+ let v3;
637
+ if (ret[0] !== 0) {
638
+ v3 = getStringFromWasm0(ret[0], ret[1]).slice();
639
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
640
+ }
641
+ return v3;
642
+ }
643
+ /**
644
+ * Stage a remove of the row keyed `pk_json` (JSON array of pk cells). The change
645
+ * is composed from the effective row; a missing key is a clean refusal (the keyed
646
+ * `delete` layer no-ops before calling this).
647
+ * @param {string} table
648
+ * @param {string} pk_json
649
+ */
650
+ txRemove(table, pk_json) {
651
+ const ptr0 = passStringToWasm0(table, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
652
+ const len0 = WASM_VECTOR_LEN;
653
+ const ptr1 = passStringToWasm0(pk_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
654
+ const len1 = WASM_VECTOR_LEN;
655
+ const ret = wasm.wasmroom_txRemove(this.__wbg_ptr, ptr0, len0, ptr1, len1);
656
+ if (ret[1]) {
657
+ throw takeFromExternrefTable0(ret[0]);
658
+ }
659
+ }
660
+ /**
661
+ * Detach subscriber `sub` (unsubscribe, socket close, lease expiry, revocation —
662
+ * the host decides why). Idempotent: returns whether it was attached. Its query
663
+ * stays materialized for `idle_ttl_ms` (a quick re-subscribe is cheap), then
664
+ * [`sweep`](Self::sweep) reclaims it.
665
+ * @param {string} sub
666
+ * @param {number} now_ms
667
+ * @returns {boolean}
668
+ */
669
+ unsubscribe(sub, now_ms) {
670
+ const ptr0 = passStringToWasm0(sub, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
671
+ const len0 = WASM_VECTOR_LEN;
672
+ const ret = wasm.wasmroom_unsubscribe(this.__wbg_ptr, ptr0, len0, now_ms);
673
+ if (ret[2]) {
674
+ throw takeFromExternrefTable0(ret[1]);
675
+ }
676
+ return ret[0] !== 0;
677
+ }
678
+ }
679
+ if (Symbol.dispose) WasmRoom.prototype[Symbol.dispose] = WasmRoom.prototype.free;
680
+
681
+ export function __rindle_room_wasm_start() {
682
+ wasm.__rindle_room_wasm_start();
683
+ }
684
+ function __wbg_get_imports() {
685
+ const import0 = {
686
+ __proto__: null,
687
+ __wbg_Error_ef53bc310eb298a0: function(arg0, arg1) {
688
+ const ret = Error(getStringFromWasm0(arg0, arg1));
689
+ return ret;
690
+ },
691
+ __wbg___wbindgen_throw_1506f2235d1bdba0: function(arg0, arg1) {
692
+ throw new Error(getStringFromWasm0(arg0, arg1));
693
+ },
694
+ __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {
695
+ let deferred0_0;
696
+ let deferred0_1;
697
+ try {
698
+ deferred0_0 = arg0;
699
+ deferred0_1 = arg1;
700
+ console.error(getStringFromWasm0(arg0, arg1));
701
+ } finally {
702
+ wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
703
+ }
704
+ },
705
+ __wbg_new_227d7c05414eb861: function() {
706
+ const ret = new Error();
707
+ return ret;
708
+ },
709
+ __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
710
+ const ret = arg1.stack;
711
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
712
+ const len1 = WASM_VECTOR_LEN;
713
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
714
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
715
+ },
716
+ __wbindgen_init_externref_table: function() {
717
+ const table = wasm.__wbindgen_externrefs;
718
+ const offset = table.grow(4);
719
+ table.set(0, undefined);
720
+ table.set(offset + 0, undefined);
721
+ table.set(offset + 1, null);
722
+ table.set(offset + 2, true);
723
+ table.set(offset + 3, false);
724
+ },
725
+ };
726
+ return {
727
+ __proto__: null,
728
+ "./rindle_room_bg.js": import0,
729
+ };
730
+ }
731
+
732
+ const WasmRoomFinalization = (typeof FinalizationRegistry === 'undefined')
733
+ ? { register: () => {}, unregister: () => {} }
734
+ : new FinalizationRegistry(ptr => wasm.__wbg_wasmroom_free(ptr, 1));
735
+
736
+ let cachedDataViewMemory0 = null;
737
+ function getDataViewMemory0() {
738
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
739
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
740
+ }
741
+ return cachedDataViewMemory0;
742
+ }
743
+
744
+ function getStringFromWasm0(ptr, len) {
745
+ return decodeText(ptr >>> 0, len);
746
+ }
747
+
748
+ let cachedUint8ArrayMemory0 = null;
749
+ function getUint8ArrayMemory0() {
750
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
751
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
752
+ }
753
+ return cachedUint8ArrayMemory0;
754
+ }
755
+
756
+ function isLikeNone(x) {
757
+ return x === undefined || x === null;
758
+ }
759
+
760
+ function passStringToWasm0(arg, malloc, realloc) {
761
+ if (realloc === undefined) {
762
+ const buf = cachedTextEncoder.encode(arg);
763
+ const ptr = malloc(buf.length, 1) >>> 0;
764
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
765
+ WASM_VECTOR_LEN = buf.length;
766
+ return ptr;
767
+ }
768
+
769
+ let len = arg.length;
770
+ let ptr = malloc(len, 1) >>> 0;
771
+
772
+ const mem = getUint8ArrayMemory0();
773
+
774
+ let offset = 0;
775
+
776
+ for (; offset < len; offset++) {
777
+ const code = arg.charCodeAt(offset);
778
+ if (code > 0x7F) break;
779
+ mem[ptr + offset] = code;
780
+ }
781
+ if (offset !== len) {
782
+ if (offset !== 0) {
783
+ arg = arg.slice(offset);
784
+ }
785
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
786
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
787
+ const ret = cachedTextEncoder.encodeInto(arg, view);
788
+
789
+ offset += ret.written;
790
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
791
+ }
792
+
793
+ WASM_VECTOR_LEN = offset;
794
+ return ptr;
795
+ }
796
+
797
+ function takeFromExternrefTable0(idx) {
798
+ const value = wasm.__wbindgen_externrefs.get(idx);
799
+ wasm.__externref_table_dealloc(idx);
800
+ return value;
801
+ }
802
+
803
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
804
+ cachedTextDecoder.decode();
805
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
806
+ let numBytesDecoded = 0;
807
+ function decodeText(ptr, len) {
808
+ numBytesDecoded += len;
809
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
810
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
811
+ cachedTextDecoder.decode();
812
+ numBytesDecoded = len;
813
+ }
814
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
815
+ }
816
+
817
+ const cachedTextEncoder = new TextEncoder();
818
+
819
+ if (!('encodeInto' in cachedTextEncoder)) {
820
+ cachedTextEncoder.encodeInto = function (arg, view) {
821
+ const buf = cachedTextEncoder.encode(arg);
822
+ view.set(buf);
823
+ return {
824
+ read: arg.length,
825
+ written: buf.length
826
+ };
827
+ };
828
+ }
829
+
830
+ let WASM_VECTOR_LEN = 0;
831
+
832
+ let wasmModule, wasmInstance, wasm;
833
+ function __wbg_finalize_init(instance, module) {
834
+ wasmInstance = instance;
835
+ wasm = instance.exports;
836
+ wasmModule = module;
837
+ cachedDataViewMemory0 = null;
838
+ cachedUint8ArrayMemory0 = null;
839
+ wasm.__wbindgen_start();
840
+ return wasm;
841
+ }
842
+
843
+ async function __wbg_load(module, imports) {
844
+ if (typeof Response === 'function' && module instanceof Response) {
845
+ if (typeof WebAssembly.instantiateStreaming === 'function') {
846
+ try {
847
+ return await WebAssembly.instantiateStreaming(module, imports);
848
+ } catch (e) {
849
+ const validResponse = module.ok && expectedResponseType(module.type);
850
+
851
+ if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
852
+ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
853
+
854
+ } else { throw e; }
855
+ }
856
+ }
857
+
858
+ const bytes = await module.arrayBuffer();
859
+ return await WebAssembly.instantiate(bytes, imports);
860
+ } else {
861
+ const instance = await WebAssembly.instantiate(module, imports);
862
+
863
+ if (instance instanceof WebAssembly.Instance) {
864
+ return { instance, module };
865
+ } else {
866
+ return instance;
867
+ }
868
+ }
869
+
870
+ function expectedResponseType(type) {
871
+ switch (type) {
872
+ case 'basic': case 'cors': case 'default': return true;
873
+ }
874
+ return false;
875
+ }
876
+ }
877
+
878
+ function initSync(module) {
879
+ if (wasm !== undefined) return wasm;
880
+
881
+
882
+ if (module !== undefined) {
883
+ if (Object.getPrototypeOf(module) === Object.prototype) {
884
+ ({module} = module)
885
+ } else {
886
+ console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
887
+ }
888
+ }
889
+
890
+ const imports = __wbg_get_imports();
891
+ if (!(module instanceof WebAssembly.Module)) {
892
+ module = new WebAssembly.Module(module);
893
+ }
894
+ const instance = new WebAssembly.Instance(module, imports);
895
+ return __wbg_finalize_init(instance, module);
896
+ }
897
+
898
+ async function __wbg_init(module_or_path) {
899
+ if (wasm !== undefined) return wasm;
900
+
901
+
902
+ if (module_or_path !== undefined) {
903
+ if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
904
+ ({module_or_path} = module_or_path)
905
+ } else {
906
+ console.warn('using deprecated parameters for the initialization function; pass a single object instead')
907
+ }
908
+ }
909
+
910
+ if (module_or_path === undefined) {
911
+ module_or_path = new URL('rindle_room_bg.wasm', import.meta.url);
912
+ }
913
+ const imports = __wbg_get_imports();
914
+
915
+ if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
916
+ module_or_path = fetch(module_or_path);
917
+ }
918
+
919
+ const { instance, module } = await __wbg_load(await module_or_path, imports);
920
+
921
+ return __wbg_finalize_init(instance, module);
922
+ }
923
+
924
+ export { initSync, __wbg_init as default };