@taladb/web 0.9.1 → 0.9.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taladb/web",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "TalaDB WASM bindings — document queries and vector search in the browser",
5
5
  "main": "pkg/taladb_web.js",
6
6
  "types": "pkg/taladb_web.d.ts",
package/pkg/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "thinkgrid-labs"
6
6
  ],
7
7
  "description": "TalaDB browser WASM bindings (wasm-bindgen + OPFS) and Cloudflare Workers",
8
- "version": "0.9.1",
8
+ "version": "0.9.2",
9
9
  "license": "MIT",
10
10
  "files": [
11
11
  "taladb_web_bg.wasm",
@@ -142,6 +142,16 @@ export class TalaDBWasm {
142
142
  * ```
143
143
  */
144
144
  static openWithSnapshot(snapshot?: Uint8Array | null): TalaDBWasm;
145
+ /**
146
+ * Persist the application migration version. Called after each migration's
147
+ * body succeeds so a crash mid-run resumes from the last applied version.
148
+ */
149
+ setUserVersion(version: number): void;
150
+ /**
151
+ * Read the current application migration version (0 if never set). Backs
152
+ * the `openDB({ migrations })` runner, which advances it per migration.
153
+ */
154
+ userVersion(): number;
145
155
  }
146
156
 
147
157
  export class WorkerDB {
@@ -246,6 +256,11 @@ export class WorkerDB {
246
256
  * Find one document. Returns a JSON object or `"null"`.
247
257
  */
248
258
  findOne(collection: string, filter_json: string): string;
259
+ /**
260
+ * Force batched (eventual) OPFS writes to durable storage. No-op under the
261
+ * default immediate durability. Backs `db.flush()`.
262
+ */
263
+ flush(): void;
249
264
  /**
250
265
  * Import a remote changeset and merge it into the local database using
251
266
  * Last-Write-Wins conflict resolution.
@@ -259,6 +274,13 @@ export class WorkerDB {
259
274
  * ```
260
275
  */
261
276
  importChangeset(changeset_json: string): number;
277
+ /**
278
+ * Import a remote changeset through a tolerant structural validator built
279
+ * from `schemas_json` (`{ "<collection>": { version, required, types,
280
+ * defaults } }`). Returns a JSON `{ applied, skipped, quarantined }`.
281
+ * Rejected documents are set aside (see `quarantined`), never dropped.
282
+ */
283
+ importChangesetValidated(changeset_json: string, schemas_json: string): string;
262
284
  /**
263
285
  * Insert a document. Returns the new ULID as a string.
264
286
  */
@@ -328,6 +350,22 @@ export class WorkerDB {
328
350
  * ```
329
351
  */
330
352
  static openWithSnapshot(data?: Uint8Array | null): WorkerDB;
353
+ /**
354
+ * Documents set aside in `collection`'s quarantine table, as a JSON array
355
+ * of `{ document, reason, changedAt }`.
356
+ */
357
+ quarantined(collection: string): string;
358
+ /**
359
+ * Set write durability: `eventual = true` batches OPFS fsyncs for
360
+ * throughput (call `flush()` to force), `false` (default) fsyncs each
361
+ * commit. Derived from `durability.flush_every_write` by the worker.
362
+ */
363
+ setDurability(eventual: boolean): void;
364
+ /**
365
+ * Persist the application migration version. Called after each migration's
366
+ * body succeeds so a crash mid-run resumes from the last applied version.
367
+ */
368
+ setUserVersion(version: number): void;
331
369
  syncPending(): bigint;
332
370
  syncStatus(): string;
333
371
  /**
@@ -345,6 +383,11 @@ export class WorkerDB {
345
383
  * No-op when the `vector-hnsw` feature is disabled or the index is flat-only.
346
384
  */
347
385
  upgradeVectorIndex(collection: string, field: string): void;
386
+ /**
387
+ * Read the current application migration version (0 if never set). Backs
388
+ * the `openDB({ migrations })` runner, which advances it per migration.
389
+ */
390
+ userVersion(): number;
348
391
  }
349
392
 
350
393
  /**
@@ -420,7 +463,9 @@ export interface InitOutput {
420
463
  readonly workerdb_find: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
421
464
  readonly workerdb_findNearest: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => [number, number, number, number];
422
465
  readonly workerdb_findOne: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
466
+ readonly workerdb_flush: (a: number) => [number, number];
423
467
  readonly workerdb_importChangeset: (a: number, b: number, c: number) => [number, number, number];
468
+ readonly workerdb_importChangesetValidated: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
424
469
  readonly workerdb_insert: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
425
470
  readonly workerdb_insertMany: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
426
471
  readonly workerdb_listCollections: (a: number) => [number, number, number, number];
@@ -430,11 +475,15 @@ export interface InitOutput {
430
475
  readonly workerdb_openWithConfigAndSnapshot: (a: number, b: number, c: number, d: number) => [number, number, number];
431
476
  readonly workerdb_openWithOpfs: (a: any) => [number, number, number];
432
477
  readonly workerdb_openWithSnapshot: (a: number, b: number) => [number, number, number];
478
+ readonly workerdb_quarantined: (a: number, b: number, c: number) => [number, number, number, number];
479
+ readonly workerdb_setDurability: (a: number, b: number) => void;
480
+ readonly workerdb_setUserVersion: (a: number, b: number) => [number, number];
433
481
  readonly workerdb_syncPending: (a: number) => bigint;
434
482
  readonly workerdb_syncStatus: (a: number) => [number, number];
435
483
  readonly workerdb_updateMany: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
436
484
  readonly workerdb_updateOne: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
437
485
  readonly workerdb_upgradeVectorIndex: (a: number, b: number, c: number, d: number, e: number) => [number, number];
486
+ readonly workerdb_userVersion: (a: number) => [number, number, number];
438
487
  readonly __wbg_collectionwasm_free: (a: number, b: number) => void;
439
488
  readonly __wbg_taladbwasm_free: (a: number, b: number) => void;
440
489
  readonly collectionwasm_aggregate: (a: number, b: any) => [number, number, number];
@@ -462,17 +511,19 @@ export interface InitOutput {
462
511
  readonly taladbwasm_listCollectionNames: (a: number) => [number, number, number, number];
463
512
  readonly taladbwasm_openInMemory: () => [number, number, number];
464
513
  readonly taladbwasm_openWithSnapshot: (a: number, b: number) => [number, number, number];
514
+ readonly taladbwasm_setUserVersion: (a: number, b: number) => [number, number];
515
+ readonly taladbwasm_userVersion: (a: number) => [number, number, number];
465
516
  readonly init: () => void;
466
517
  readonly opfs_open_backend: (a: number, b: number) => any;
518
+ readonly idb_load_snapshot: (a: number, b: number) => any;
519
+ readonly idb_save_snapshot: (a: number, b: number, c: number, d: number) => any;
467
520
  readonly is_opfs_available: () => any;
468
521
  readonly opfs_delete_snapshot: (a: number, b: number) => any;
469
522
  readonly opfs_flush_snapshot: (a: number, b: number, c: number, d: number) => any;
470
523
  readonly opfs_load_snapshot: (a: number, b: number) => any;
471
- readonly idb_load_snapshot: (a: number, b: number) => any;
472
- readonly idb_save_snapshot: (a: number, b: number, c: number, d: number) => any;
524
+ readonly wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output_______: (a: number, b: number) => void;
473
525
  readonly wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut_____Output_______: (a: number, b: number) => void;
474
526
  readonly wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output___core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___: (a: number, b: number) => void;
475
- readonly wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output_______: (a: number, b: number) => void;
476
527
  readonly wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue__core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___true_: (a: number, b: number, c: any) => [number, number];
477
528
  readonly wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___js_sys_517e1093b71f55ec___Function_fn_wasm_bindgen_60ce93de3f474933___JsValue_____wasm_bindgen_60ce93de3f474933___sys__Undefined___js_sys_517e1093b71f55ec___Function_fn_wasm_bindgen_60ce93de3f474933___JsValue_____wasm_bindgen_60ce93de3f474933___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
478
529
  readonly wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue______true_: (a: number, b: number, c: any) => void;
package/pkg/taladb_web.js CHANGED
@@ -420,6 +420,29 @@ export class TalaDBWasm {
420
420
  }
421
421
  return TalaDBWasm.__wrap(ret[0]);
422
422
  }
423
+ /**
424
+ * Persist the application migration version. Called after each migration's
425
+ * body succeeds so a crash mid-run resumes from the last applied version.
426
+ * @param {number} version
427
+ */
428
+ setUserVersion(version) {
429
+ const ret = wasm.taladbwasm_setUserVersion(this.__wbg_ptr, version);
430
+ if (ret[1]) {
431
+ throw takeFromExternrefTable0(ret[0]);
432
+ }
433
+ }
434
+ /**
435
+ * Read the current application migration version (0 if never set). Backs
436
+ * the `openDB({ migrations })` runner, which advances it per migration.
437
+ * @returns {number}
438
+ */
439
+ userVersion() {
440
+ const ret = wasm.taladbwasm_userVersion(this.__wbg_ptr);
441
+ if (ret[2]) {
442
+ throw takeFromExternrefTable0(ret[1]);
443
+ }
444
+ return ret[0] >>> 0;
445
+ }
423
446
  }
424
447
  if (Symbol.dispose) TalaDBWasm.prototype[Symbol.dispose] = TalaDBWasm.prototype.free;
425
448
 
@@ -833,6 +856,16 @@ export class WorkerDB {
833
856
  wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
834
857
  }
835
858
  }
859
+ /**
860
+ * Force batched (eventual) OPFS writes to durable storage. No-op under the
861
+ * default immediate durability. Backs `db.flush()`.
862
+ */
863
+ flush() {
864
+ const ret = wasm.workerdb_flush(this.__wbg_ptr);
865
+ if (ret[1]) {
866
+ throw takeFromExternrefTable0(ret[0]);
867
+ }
868
+ }
836
869
  /**
837
870
  * Import a remote changeset and merge it into the local database using
838
871
  * Last-Write-Wins conflict resolution.
@@ -856,6 +889,37 @@ export class WorkerDB {
856
889
  }
857
890
  return ret[0] >>> 0;
858
891
  }
892
+ /**
893
+ * Import a remote changeset through a tolerant structural validator built
894
+ * from `schemas_json` (`{ "<collection>": { version, required, types,
895
+ * defaults } }`). Returns a JSON `{ applied, skipped, quarantined }`.
896
+ * Rejected documents are set aside (see `quarantined`), never dropped.
897
+ * @param {string} changeset_json
898
+ * @param {string} schemas_json
899
+ * @returns {string}
900
+ */
901
+ importChangesetValidated(changeset_json, schemas_json) {
902
+ let deferred4_0;
903
+ let deferred4_1;
904
+ try {
905
+ const ptr0 = passStringToWasm0(changeset_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
906
+ const len0 = WASM_VECTOR_LEN;
907
+ const ptr1 = passStringToWasm0(schemas_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
908
+ const len1 = WASM_VECTOR_LEN;
909
+ const ret = wasm.workerdb_importChangesetValidated(this.__wbg_ptr, ptr0, len0, ptr1, len1);
910
+ var ptr3 = ret[0];
911
+ var len3 = ret[1];
912
+ if (ret[3]) {
913
+ ptr3 = 0; len3 = 0;
914
+ throw takeFromExternrefTable0(ret[2]);
915
+ }
916
+ deferred4_0 = ptr3;
917
+ deferred4_1 = len3;
918
+ return getStringFromWasm0(ptr3, len3);
919
+ } finally {
920
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
921
+ }
922
+ }
859
923
  /**
860
924
  * Insert a document. Returns the new ULID as a string.
861
925
  * @param {string} collection
@@ -1067,6 +1131,52 @@ export class WorkerDB {
1067
1131
  }
1068
1132
  return WorkerDB.__wrap(ret[0]);
1069
1133
  }
1134
+ /**
1135
+ * Documents set aside in `collection`'s quarantine table, as a JSON array
1136
+ * of `{ document, reason, changedAt }`.
1137
+ * @param {string} collection
1138
+ * @returns {string}
1139
+ */
1140
+ quarantined(collection) {
1141
+ let deferred3_0;
1142
+ let deferred3_1;
1143
+ try {
1144
+ const ptr0 = passStringToWasm0(collection, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1145
+ const len0 = WASM_VECTOR_LEN;
1146
+ const ret = wasm.workerdb_quarantined(this.__wbg_ptr, ptr0, len0);
1147
+ var ptr2 = ret[0];
1148
+ var len2 = ret[1];
1149
+ if (ret[3]) {
1150
+ ptr2 = 0; len2 = 0;
1151
+ throw takeFromExternrefTable0(ret[2]);
1152
+ }
1153
+ deferred3_0 = ptr2;
1154
+ deferred3_1 = len2;
1155
+ return getStringFromWasm0(ptr2, len2);
1156
+ } finally {
1157
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1158
+ }
1159
+ }
1160
+ /**
1161
+ * Set write durability: `eventual = true` batches OPFS fsyncs for
1162
+ * throughput (call `flush()` to force), `false` (default) fsyncs each
1163
+ * commit. Derived from `durability.flush_every_write` by the worker.
1164
+ * @param {boolean} eventual
1165
+ */
1166
+ setDurability(eventual) {
1167
+ wasm.workerdb_setDurability(this.__wbg_ptr, eventual);
1168
+ }
1169
+ /**
1170
+ * Persist the application migration version. Called after each migration's
1171
+ * body succeeds so a crash mid-run resumes from the last applied version.
1172
+ * @param {number} version
1173
+ */
1174
+ setUserVersion(version) {
1175
+ const ret = wasm.workerdb_setUserVersion(this.__wbg_ptr, version);
1176
+ if (ret[1]) {
1177
+ throw takeFromExternrefTable0(ret[0]);
1178
+ }
1179
+ }
1070
1180
  /**
1071
1181
  * @returns {bigint}
1072
1182
  */
@@ -1147,6 +1257,18 @@ export class WorkerDB {
1147
1257
  throw takeFromExternrefTable0(ret[0]);
1148
1258
  }
1149
1259
  }
1260
+ /**
1261
+ * Read the current application migration version (0 if never set). Backs
1262
+ * the `openDB({ migrations })` runner, which advances it per migration.
1263
+ * @returns {number}
1264
+ */
1265
+ userVersion() {
1266
+ const ret = wasm.workerdb_userVersion(this.__wbg_ptr);
1267
+ if (ret[2]) {
1268
+ throw takeFromExternrefTable0(ret[1]);
1269
+ }
1270
+ return ret[0] >>> 0;
1271
+ }
1150
1272
  }
1151
1273
  if (Symbol.dispose) WorkerDB.prototype[Symbol.dispose] = WorkerDB.prototype.free;
1152
1274
 
@@ -1850,18 +1972,18 @@ function __wbg_get_imports() {
1850
1972
  return ret;
1851
1973
  },
1852
1974
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
1853
- // Cast intrinsic for `Closure(Closure { dtor_idx: 215, function: Function { arguments: [], shim_idx: 216, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1854
- const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut_____Output_______, wasm_bindgen_60ce93de3f474933___convert__closures_____invoke_______true_);
1975
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 144, function: Function { arguments: [Externref], shim_idx: 145, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1976
+ const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output_______, wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue______true_);
1855
1977
  return ret;
1856
1978
  },
1857
1979
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
1858
- // Cast intrinsic for `Closure(Closure { dtor_idx: 692, function: Function { arguments: [Externref], shim_idx: 693, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
1859
- const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output___core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___, wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue__core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___true_);
1980
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 224, function: Function { arguments: [], shim_idx: 225, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1981
+ const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut_____Output_______, wasm_bindgen_60ce93de3f474933___convert__closures_____invoke_______true_);
1860
1982
  return ret;
1861
1983
  },
1862
1984
  __wbindgen_cast_0000000000000003: function(arg0, arg1) {
1863
- // Cast intrinsic for `Closure(Closure { dtor_idx: 71, function: Function { arguments: [Externref], shim_idx: 72, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1864
- const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output_______, wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue______true_);
1985
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 707, function: Function { arguments: [Externref], shim_idx: 708, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
1986
+ const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output___core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___, wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue__core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___true_);
1865
1987
  return ret;
1866
1988
  },
1867
1989
  __wbindgen_cast_0000000000000004: function(arg0) {
Binary file
@@ -21,7 +21,9 @@ export const workerdb_exportSnapshot: (a: number) => [number, number, number, nu
21
21
  export const workerdb_find: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
22
22
  export const workerdb_findNearest: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => [number, number, number, number];
23
23
  export const workerdb_findOne: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
24
+ export const workerdb_flush: (a: number) => [number, number];
24
25
  export const workerdb_importChangeset: (a: number, b: number, c: number) => [number, number, number];
26
+ export const workerdb_importChangesetValidated: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
25
27
  export const workerdb_insert: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
26
28
  export const workerdb_insertMany: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
27
29
  export const workerdb_listCollections: (a: number) => [number, number, number, number];
@@ -31,11 +33,15 @@ export const workerdb_openWithConfigAndOpfs: (a: any, b: number, c: number, d: n
31
33
  export const workerdb_openWithConfigAndSnapshot: (a: number, b: number, c: number, d: number) => [number, number, number];
32
34
  export const workerdb_openWithOpfs: (a: any) => [number, number, number];
33
35
  export const workerdb_openWithSnapshot: (a: number, b: number) => [number, number, number];
36
+ export const workerdb_quarantined: (a: number, b: number, c: number) => [number, number, number, number];
37
+ export const workerdb_setDurability: (a: number, b: number) => void;
38
+ export const workerdb_setUserVersion: (a: number, b: number) => [number, number];
34
39
  export const workerdb_syncPending: (a: number) => bigint;
35
40
  export const workerdb_syncStatus: (a: number) => [number, number];
36
41
  export const workerdb_updateMany: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
37
42
  export const workerdb_updateOne: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
38
43
  export const workerdb_upgradeVectorIndex: (a: number, b: number, c: number, d: number, e: number) => [number, number];
44
+ export const workerdb_userVersion: (a: number) => [number, number, number];
39
45
  export const __wbg_collectionwasm_free: (a: number, b: number) => void;
40
46
  export const __wbg_taladbwasm_free: (a: number, b: number) => void;
41
47
  export const collectionwasm_aggregate: (a: number, b: any) => [number, number, number];
@@ -63,17 +69,19 @@ export const taladbwasm_importChanges: (a: number, b: number, c: number) => [num
63
69
  export const taladbwasm_listCollectionNames: (a: number) => [number, number, number, number];
64
70
  export const taladbwasm_openInMemory: () => [number, number, number];
65
71
  export const taladbwasm_openWithSnapshot: (a: number, b: number) => [number, number, number];
72
+ export const taladbwasm_setUserVersion: (a: number, b: number) => [number, number];
73
+ export const taladbwasm_userVersion: (a: number) => [number, number, number];
66
74
  export const init: () => void;
67
75
  export const opfs_open_backend: (a: number, b: number) => any;
76
+ export const idb_load_snapshot: (a: number, b: number) => any;
77
+ export const idb_save_snapshot: (a: number, b: number, c: number, d: number) => any;
68
78
  export const is_opfs_available: () => any;
69
79
  export const opfs_delete_snapshot: (a: number, b: number) => any;
70
80
  export const opfs_flush_snapshot: (a: number, b: number, c: number, d: number) => any;
71
81
  export const opfs_load_snapshot: (a: number, b: number) => any;
72
- export const idb_load_snapshot: (a: number, b: number) => any;
73
- export const idb_save_snapshot: (a: number, b: number, c: number, d: number) => any;
82
+ export const wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output_______: (a: number, b: number) => void;
74
83
  export const wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut_____Output_______: (a: number, b: number) => void;
75
84
  export const wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output___core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___: (a: number, b: number) => void;
76
- export const wasm_bindgen_60ce93de3f474933___closure__destroy___dyn_core_7d5f0a2ba6a62c33___ops__function__FnMut__wasm_bindgen_60ce93de3f474933___JsValue____Output_______: (a: number, b: number) => void;
77
85
  export const wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue__core_7d5f0a2ba6a62c33___result__Result_____wasm_bindgen_60ce93de3f474933___JsError___true_: (a: number, b: number, c: any) => [number, number];
78
86
  export const wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___js_sys_517e1093b71f55ec___Function_fn_wasm_bindgen_60ce93de3f474933___JsValue_____wasm_bindgen_60ce93de3f474933___sys__Undefined___js_sys_517e1093b71f55ec___Function_fn_wasm_bindgen_60ce93de3f474933___JsValue_____wasm_bindgen_60ce93de3f474933___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
79
87
  export const wasm_bindgen_60ce93de3f474933___convert__closures_____invoke___wasm_bindgen_60ce93de3f474933___JsValue______true_: (a: number, b: number, c: any) => void;
@@ -258,7 +258,9 @@ async function idbSaveSnapshot(dbName, bytes) {
258
258
  * per document. A max-interval cap ensures data is never more than 5 s stale
259
259
  * in IDB even under continuous write load.
260
260
  */
261
- const SNAPSHOT_DEBOUNCE_MS = 500;
261
+ /** IDB snapshot debounce, in ms. Overridable via config `durability.flush_ms`
262
+ * at init (the OPFS/redb path uses `durability.flush_every_write` instead). */
263
+ let snapshotDebounceMs = 500;
262
264
  const SNAPSHOT_MAX_INTERVAL_MS = 5000;
263
265
 
264
266
  /** setTimeout handle for the pending debounced flush. */
@@ -285,7 +287,7 @@ async function flushSnapshot() {
285
287
  * Schedule (or immediately trigger) an IDB snapshot write.
286
288
  *
287
289
  * - If the last flush was more than SNAPSHOT_MAX_INTERVAL_MS ago, flush now.
288
- * - Otherwise debounce: reset the timer to fire SNAPSHOT_DEBOUNCE_MS from now.
290
+ * - Otherwise debounce: reset the timer to fire snapshotDebounceMs from now.
289
291
  */
290
292
  function scheduleSnapshot() {
291
293
  const now = Date.now();
@@ -295,7 +297,23 @@ function scheduleSnapshot() {
295
297
  return;
296
298
  }
297
299
  clearTimeout(snapshotTimer);
298
- snapshotTimer = setTimeout(() => { flushSnapshot().catch(() => {}); }, SNAPSHOT_DEBOUNCE_MS);
300
+ snapshotTimer = setTimeout(() => { flushSnapshot().catch(() => {}); }, snapshotDebounceMs);
301
+ }
302
+
303
+ /** Apply `durability` config to a freshly-opened WorkerDB instance: OPFS/redb
304
+ * durability from `flush_every_write`, and the IDB-fallback debounce from
305
+ * `flush_ms`. Returns the instance for chaining. */
306
+ function applyDurability(inst) {
307
+ let flushEveryWrite = true;
308
+ try {
309
+ const d = activeConfigJson ? JSON.parse(activeConfigJson)?.durability : null;
310
+ if (d) {
311
+ if (typeof d.flush_every_write === 'boolean') flushEveryWrite = d.flush_every_write;
312
+ if (typeof d.flush_ms === 'number' && d.flush_ms >= 0) snapshotDebounceMs = d.flush_ms;
313
+ }
314
+ } catch { /* ignore malformed config */ }
315
+ inst?.setDurability?.(!flushEveryWrite); // feature-detect (older WASM lacks it)
316
+ return inst;
299
317
  }
300
318
 
301
319
  /**
@@ -514,6 +532,13 @@ async function dispatch(op, args) {
514
532
  db.compact();
515
533
  return null;
516
534
 
535
+ case 'flush':
536
+ // "Save now": force batched OPFS writes durable (no-op under immediate
537
+ // durability) and write the IDB fallback snapshot immediately.
538
+ db.flush?.();
539
+ await flushSnapshot();
540
+ return null;
541
+
517
542
  case 'syncStatus':
518
543
  return db.syncStatus();
519
544
 
@@ -543,6 +568,31 @@ async function dispatch(op, args) {
543
568
  return applied;
544
569
  }
545
570
 
571
+ case 'importChangesetValidated': {
572
+ // Tolerant validated import: normalize/skip/quarantine per schema, LWW.
573
+ // Returns a JSON string { applied, skipped, quarantined }.
574
+ const reportJson = db.importChangesetValidated(args.changesetJson, args.schemasJson);
575
+ const report = JSON.parse(reportJson);
576
+ // Quarantined documents are written to the quarantine table, so a batch
577
+ // that only quarantines still dirties the database. Without this, the IDB
578
+ // fallback would never snapshot them and they would be lost on reload —
579
+ // the opposite of the "never dropped on the floor" guarantee.
580
+ if ((report.applied ?? 0) > 0 || (report.quarantined ?? 0) > 0) onWriteCommitted();
581
+ return reportJson;
582
+ }
583
+
584
+ case 'quarantined':
585
+ // JSON array of documents set aside by a validated import.
586
+ return db.quarantined(args.collection);
587
+
588
+ case 'userVersion':
589
+ // Current application migration version (backs openDB({ migrations })).
590
+ return db.userVersion();
591
+
592
+ case 'setUserVersion':
593
+ db.setUserVersion(args.version);
594
+ return null;
595
+
546
596
  case 'close':
547
597
  // Give accepted HTTP push events a bounded opportunity to finish.
548
598
  {
@@ -661,15 +711,19 @@ async function doInit(dbName, configJson, passphrase = null) {
661
711
  // Uses the config-aware constructors when configJson is provided so that
662
712
  // HTTP push sync is wired up from the first write.
663
713
  function openWithSnapshot(snapshot) {
664
- if (configJson) return WorkerDB.openWithConfigAndSnapshot(snapshot, configJson);
665
- return WorkerDB.openWithSnapshot(snapshot);
714
+ const inst = configJson
715
+ ? WorkerDB.openWithConfigAndSnapshot(snapshot, configJson)
716
+ : WorkerDB.openWithSnapshot(snapshot);
717
+ return applyDurability(inst);
666
718
  }
667
719
  // Salt for key derivation, loaded/created in an OPFS sidecar (encrypted mode
668
720
  // only). Passed to the WASM open so the derived key is stable across opens.
669
721
  let salt = null;
670
722
  function openWithOpfs(syncHandle) {
671
723
  // openWithConfigAndOpfs(handle, configJson, passphrase?, salt?)
672
- return WorkerDB.openWithConfigAndOpfs(syncHandle, configJson ?? null, passphrase, salt);
724
+ return applyDurability(
725
+ WorkerDB.openWithConfigAndOpfs(syncHandle, configJson ?? null, passphrase, salt),
726
+ );
673
727
  }
674
728
 
675
729
  const opfsAvailable = await checkOpfs();