@moyodb/sdk 1.3.0 → 1.4.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.
Files changed (37) hide show
  1. package/CONTRIBUTING.md +46 -0
  2. package/README.md +4 -2
  3. package/dist/assets/browser-worker-Bj2ErRvC.js +4 -0
  4. package/dist/assets/browser-worker-Bj2ErRvC.js.map +1 -0
  5. package/dist/assets/shared-worker-CMeTcusa.js +2 -0
  6. package/dist/assets/shared-worker-CMeTcusa.js.map +1 -0
  7. package/dist/chunks/{indexing-CKtbpaZn.js → indexing-B0duqlUs.js} +43 -117
  8. package/dist/chunks/indexing-B0duqlUs.js.map +1 -0
  9. package/dist/demo.d.ts.map +1 -1
  10. package/dist/engine/README.md +4 -2
  11. package/dist/engine/moyodb_engine.d.ts +4 -2
  12. package/dist/engine/moyodb_engine.js +45 -22
  13. package/dist/engine/moyodb_engine_bg.wasm +0 -0
  14. package/dist/engine/moyodb_engine_bg.wasm.d.ts +3 -2
  15. package/dist/engine/package.json +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/indexing.d.ts.map +1 -1
  18. package/dist/moyodb-sdk.js +648 -653
  19. package/dist/moyodb-sdk.js.map +1 -1
  20. package/dist/node-engine.js +30 -35
  21. package/dist/node-engine.js.map +1 -1
  22. package/dist/node.js +23 -31
  23. package/dist/node.js.map +1 -1
  24. package/dist/registry.d.ts.map +1 -1
  25. package/dist/worker-api.d.ts +2 -5
  26. package/dist/worker-api.d.ts.map +1 -1
  27. package/dist/worker-protocol.d.ts +7 -2
  28. package/dist/worker-protocol.d.ts.map +1 -1
  29. package/dist/worker.d.ts +2 -2
  30. package/dist/worker.d.ts.map +1 -1
  31. package/package.json +4 -3
  32. package/dist/assets/browser-worker-DBt51gsS.js +0 -4
  33. package/dist/assets/browser-worker-DBt51gsS.js.map +0 -1
  34. package/dist/assets/shared-worker-NdniRuEL.js +0 -2
  35. package/dist/assets/shared-worker-NdniRuEL.js.map +0 -1
  36. package/dist/chunks/indexing-CKtbpaZn.js.map +0 -1
  37. /package/dist/engine/snippets/{moyodb-engine-54a406e33b0fb849 → moyodb-engine-1d53039816cbc2f7}/js/opfs_shim.js +0 -0
@@ -1,4 +1,4 @@
1
- import { At as packedBinaryListBytes, Bt as unpackPackedOptionalValues, Et as isWorkerProtocolRequestMessage, F as utf8Encode, Ft as serializeWorkerError, Gt as isRecord, Ht as workerProtocolError, It as unpackPackedBatchOpKeys, Lt as unpackPackedBatchOps, Mt as packedScanRows, Pt as prepareWorkerResponsePayload, Rt as unpackPackedBinaryList, S as toPublicIndexDefinitions, St as isWorkerProtocolEnvelope, Tt as isWorkerProtocolRequestBatchMessage, Ut as clampTimerDelayMs, Vt as unpackPackedScanRows, _ as indexRangeToPhysicalRange, _t as decodeWorkerCommandPayload, a as createIndexKeyExtractor, b as normalizeIndexDefinitions, bt as isAutocommitCommand, c as decodeIndexedDocument, d as encodeIndexMetadataValue, dt as WORKER_PROTOCOL_READY, f as extractLogicalIndexKey, g as indexKeyExactRange, gt as captureWorkerPayload, ht as WORKER_PROTOCOL_RESPONSE_BATCH, i as compareNormalizedIndexDefinitions, jt as packedOptionalValues, kt as packedBatchOpsBytes, l as encodeIndexEntryKey, m as findIndexDefinition, mt as WORKER_PROTOCOL_RESPONSE, o as decodeIndexEntryKey, p as extractLogicalIndexKeyFromDocument, r as cloneNormalizedIndexDefinitions, s as decodeIndexMetadataValue, t as INDEX_METADATA_STORE, u as encodeIndexMetadataKey, xt as isWorkerCommand, y as isInternalStoreName, zt as unpackPackedBinaryPairKeys } from "./chunks/indexing-CKtbpaZn.js";
1
+ import { At as packedBinaryListBytes, Bt as unpackPackedOptionalValues, Et as isWorkerProtocolRequestMessage, F as utf8Encode, Ft as serializeWorkerError, Gt as isRecord, Ht as workerProtocolError, It as unpackPackedBatchOpKeys, Lt as unpackPackedBatchOps, Mt as packedScanRows, Pt as prepareWorkerResponsePayload, Rt as unpackPackedBinaryList, S as toPublicIndexDefinitions, St as isWorkerProtocolEnvelope, Tt as isWorkerProtocolRequestBatchMessage, Ut as clampTimerDelayMs, Vt as unpackPackedScanRows, _ as indexRangeToPhysicalRange, _t as decodeWorkerCommandPayload, a as createIndexKeyExtractor, b as normalizeIndexDefinitions, bt as isAutocommitCommand, c as decodeIndexedDocument, d as encodeIndexMetadataValue, dt as WORKER_PROTOCOL_READY, f as extractLogicalIndexKey, g as indexKeyExactRange, gt as captureWorkerPayload, ht as WORKER_PROTOCOL_RESPONSE_BATCH, i as compareNormalizedIndexDefinitions, jt as packedOptionalValues, kt as packedBatchOpsBytes, l as encodeIndexEntryKey, m as findIndexDefinition, mt as WORKER_PROTOCOL_RESPONSE, o as decodeIndexEntryKey, p as extractLogicalIndexKeyFromDocument, r as cloneNormalizedIndexDefinitions, s as decodeIndexMetadataValue, t as INDEX_METADATA_STORE, u as encodeIndexMetadataKey, xt as isWorkerCommand, y as isInternalStoreName, zt as unpackPackedBinaryPairKeys } from "./chunks/indexing-B0duqlUs.js";
2
2
  //#region src/worker-server.ts
3
3
  /** The first argument identifies the transaction lane. */
4
4
  var TRANSACTION_COMMANDS = /* @__PURE__ */ new Set([
@@ -759,7 +759,9 @@ function toWasmU64(value) {
759
759
  return BigInt(value);
760
760
  }
761
761
  function fromWasmU64(value) {
762
- return typeof value === "bigint" ? Number(value) : value;
762
+ const number = typeof value === "bigint" ? Number(value) : value;
763
+ if (!Number.isSafeInteger(number) || number < 0) throw remoteError("SerializationError", "WASM integer exceeds the JavaScript safe integer range");
764
+ return number;
763
765
  }
764
766
  function fromOptionalWasmU64(value) {
765
767
  return value === null || value === void 0 ? null : fromWasmU64(value);
@@ -1348,7 +1350,7 @@ var DbWorker = class {
1348
1350
  this.recordPutChanges(txId, store, entries, partial);
1349
1351
  throw error;
1350
1352
  }
1351
- if (baselines.length !== entries.length) throw remoteError("InternalError", `put_many outcome count mismatch: ${baselines.length} != ${entries.length}`);
1353
+ if (baselines.length !== entries.length) throw outcomeCountMismatch("put_many", baselines.length, entries.length);
1352
1354
  this.recordPutChanges(txId, store, entries, baselines);
1353
1355
  return;
1354
1356
  }
@@ -1380,7 +1382,7 @@ var DbWorker = class {
1380
1382
  this.recordPutKeyChanges(txId, store, keys, partial);
1381
1383
  throw error;
1382
1384
  }
1383
- if (baselines.length !== keys.length) throw remoteError("InternalError", `put_many_packed outcome count mismatch: ${baselines.length} != ${keys.length}`);
1385
+ if (baselines.length !== keys.length) throw outcomeCountMismatch("put_many_packed", baselines.length, keys.length);
1384
1386
  this.recordPutKeyChanges(txId, store, keys, baselines);
1385
1387
  }
1386
1388
  async delete(txId, store, key) {
@@ -1410,7 +1412,7 @@ var DbWorker = class {
1410
1412
  for (let i = 0; i < partial.length && i < keys.length; i += 1) this.recordDeleteChange(txId, store, keys[i], partial[i]);
1411
1413
  throw error;
1412
1414
  }
1413
- if (deleted.length !== keys.length) throw remoteError("InternalError", `delete_many outcome count mismatch: ${deleted.length} != ${keys.length}`);
1415
+ if (deleted.length !== keys.length) throw outcomeCountMismatch("delete_many", deleted.length, keys.length);
1414
1416
  for (let i = 0; i < keys.length; i += 1) this.recordDeleteChange(txId, store, keys[i], deleted[i]);
1415
1417
  return;
1416
1418
  }
@@ -1432,7 +1434,7 @@ var DbWorker = class {
1432
1434
  for (let i = 0; i < partial.length && i < keys.length; i += 1) this.recordDeleteChange(txId, store, keys[i], partial[i]);
1433
1435
  throw error;
1434
1436
  }
1435
- if (deleted.length !== keys.length) throw remoteError("InternalError", `delete_many_packed outcome count mismatch: ${deleted.length} != ${keys.length}`);
1437
+ if (deleted.length !== keys.length) throw outcomeCountMismatch("delete_many_packed", deleted.length, keys.length);
1436
1438
  for (let i = 0; i < keys.length; i += 1) this.recordDeleteChange(txId, store, keys[i], deleted[i] === 1);
1437
1439
  }
1438
1440
  async applyBatch(txId, store, ops) {
@@ -1446,7 +1448,7 @@ var DbWorker = class {
1446
1448
  this.recordBatchOutcomes(txId, store, ops, partialBatchOutcomes(error));
1447
1449
  throw error;
1448
1450
  }
1449
- if (outcomes.length !== ops.length) throw remoteError("InternalError", `apply_batch outcome count mismatch: ${outcomes.length} != ${ops.length}`);
1451
+ if (outcomes.length !== ops.length) throw outcomeCountMismatch("apply_batch", outcomes.length, ops.length);
1450
1452
  this.recordBatchOutcomes(txId, store, ops, outcomes);
1451
1453
  return;
1452
1454
  }
@@ -1466,10 +1468,10 @@ var DbWorker = class {
1466
1468
  try {
1467
1469
  flags = this.withEngine((engine) => engine.apply_batch_packed(toWasmU64(txId), store, packedOps));
1468
1470
  } catch (error) {
1469
- this.recordBatchKeyOutcomes(txId, store, ops, partialBatchOutcomes(error));
1471
+ this.recordBatchOutcomes(txId, store, ops, partialBatchOutcomes(error));
1470
1472
  throw error;
1471
1473
  }
1472
- if (flags.length !== ops.length) throw remoteError("InternalError", `apply_batch_packed outcome count mismatch: ${flags.length} != ${ops.length}`);
1474
+ if (flags.length !== ops.length) throw outcomeCountMismatch("apply_batch_packed", flags.length, ops.length);
1473
1475
  for (let i = 0; i < ops.length; i += 1) {
1474
1476
  const op = ops[i];
1475
1477
  if (op.kind === "put") this.recordPutChange(txId, store, op.key, flags[i] === 1);
@@ -1605,7 +1607,7 @@ var DbWorker = class {
1605
1607
  let rows;
1606
1608
  if (sourceRows !== null) {
1607
1609
  const visible = this.withEngine((engine) => engine.has_many(toWasmU64(txId), def.store, sourceRows.map((row) => row.key)));
1608
- if (visible.length !== sourceRows.length) throw remoteError("InternalError", `has_many outcome count mismatch: ${visible.length} != ${sourceRows.length}`);
1610
+ if (visible.length !== sourceRows.length) throw outcomeCountMismatch("has_many", visible.length, sourceRows.length);
1609
1611
  rows = sourceRows.filter((_row, index) => visible[index]);
1610
1612
  } else {
1611
1613
  rows = await this.readStoreScan(txId, def.store, EMPTY_RANGE);
@@ -1697,12 +1699,9 @@ var DbWorker = class {
1697
1699
  return await wrapSnapshotWithCompression(wrapSnapshotWithIndexDefinitions(normalizeWasmBytes(this.withEngine((engine) => engine.export_snapshot())), defs), options.compression ?? false);
1698
1700
  }
1699
1701
  async importSnapshot(data) {
1700
- this.rollbackAllTransactions();
1702
+ this.ensureNotInMaintenance();
1701
1703
  const parsed = unwrapSnapshotWithIndexDefinitions(await unwrapSnapshotCompression(data));
1702
- this.withEngine((engine) => engine.import_snapshot(parsed.snapshot));
1703
- this.committedIndexes = [];
1704
- this.committedStoreCompression = null;
1705
- await this.applyCommittedIndexSchema(parsed.indexes);
1704
+ await this.runGenerationOperation("import", parsed);
1706
1705
  }
1707
1706
  async reset() {
1708
1707
  const dbName = this.dbName;
@@ -1730,16 +1729,16 @@ var DbWorker = class {
1730
1729
  }
1731
1730
  }
1732
1731
  async compact() {
1733
- return this.runCompactionOperation("compact");
1732
+ return this.runGenerationOperation("compact");
1734
1733
  }
1735
1734
  async rebuild() {
1736
- return this.runCompactionOperation("rebuild");
1735
+ return this.runGenerationOperation("rebuild");
1737
1736
  }
1738
1737
  stats() {
1739
1738
  const stats = this.withEngine((engine) => engine.stats());
1740
1739
  return Promise.resolve({
1741
1740
  ...stats,
1742
- db_id: fromWasmU64(stats.db_id),
1741
+ db_id: typeof stats.db_id === "bigint" ? Number(stats.db_id) : stats.db_id,
1743
1742
  catalog_root_page_id: fromWasmU64(stats.catalog_root_page_id),
1744
1743
  next_page_id: fromWasmU64(stats.next_page_id),
1745
1744
  last_committed_txid: fromWasmU64(stats.last_committed_txid),
@@ -1800,7 +1799,7 @@ var DbWorker = class {
1800
1799
  });
1801
1800
  try {
1802
1801
  await this.reconcileIndexes(txId, toPublicIndexDefinitions(normalized));
1803
- this.withEngine((engine) => engine.commit_tx(toWasmU64(txId)), { allowDuringMaintenance: true });
1802
+ fromWasmU64(this.withEngine((engine) => engine.commit_tx(toWasmU64(txId)), { allowDuringMaintenance: true }));
1804
1803
  this.committedIndexes = cloneNormalizedIndexDefinitions(normalized);
1805
1804
  } catch (error) {
1806
1805
  try {
@@ -1816,18 +1815,19 @@ var DbWorker = class {
1816
1815
  * A failed swap may have reached storage; read the control file before cleanup.
1817
1816
  * After publication, abandon the old engine to avoid a checkpoint into inactive files.
1818
1817
  */
1819
- async runCompactionOperation(operation) {
1818
+ async runGenerationOperation(operation, imported) {
1820
1819
  const dbName = this.requireDbName();
1821
1820
  if (this.maintenanceOperation) throw remoteError("DatabaseBusyError", `database ${dbName} is busy: ${this.maintenanceOperation} in progress`);
1822
1821
  this.maintenanceOperation = operation;
1823
1822
  const start = performance.now();
1824
- const wasm = await this.loadWasm();
1823
+ let wasm = null;
1825
1824
  let rebuiltEngine = null;
1826
1825
  let generationName = null;
1827
1826
  let published = false;
1828
1827
  try {
1828
+ wasm = await this.loadWasm();
1829
1829
  const sizeBefore = await wasm.dbDirectorySize(dbName);
1830
- const defs = cloneNormalizedIndexDefinitions(this.loadCommittedIndexSchema());
1830
+ const defs = cloneNormalizedIndexDefinitions(imported?.indexes ?? this.loadCommittedIndexSchema());
1831
1831
  this.rollbackAllTransactions({ allowDuringMaintenance: true });
1832
1832
  const expectedGeneration = await wasm.readActiveGeneration(dbName);
1833
1833
  generationName = (await wasm.prepareRebuildTarget(dbName)).generationName;
@@ -1837,8 +1837,8 @@ var DbWorker = class {
1837
1837
  cache_pages: this.currentCachePages()
1838
1838
  });
1839
1839
  const target = rebuiltEngine;
1840
- this.withEngine((engine) => operation === "rebuild" ? engine.compact_into_skipping_stores(target, [...defs.map((def) => def.internalStore), INDEX_METADATA_STORE]) : engine.compact_into(target), { allowDuringMaintenance: true });
1841
- if (operation === "rebuild" && defs.length > 0) {
1840
+ this.withEngine((engine) => imported ? fromWasmU64(engine.import_snapshot_into(target, imported.snapshot)) : operation === "rebuild" ? engine.compact_into_skipping_stores(target, [...defs.map((def) => def.internalStore), INDEX_METADATA_STORE]) : engine.compact_into(target), { allowDuringMaintenance: true });
1841
+ if ((operation === "rebuild" || imported) && defs.length > 0) {
1842
1842
  const previousEngine = this.engine;
1843
1843
  const previousMaintenance = this.maintenanceOperation;
1844
1844
  this.engine = target;
@@ -1871,7 +1871,7 @@ var DbWorker = class {
1871
1871
  try {
1872
1872
  await wasm.cleanupInactiveEntries(dbName);
1873
1873
  } catch {}
1874
- const sizeAfter = await wasm.dbDirectorySize(dbName);
1874
+ const sizeAfter = imported ? sizeBefore : await wasm.dbDirectorySize(dbName);
1875
1875
  return {
1876
1876
  sizeBefore,
1877
1877
  sizeAfter,
@@ -1885,7 +1885,7 @@ var DbWorker = class {
1885
1885
  try {
1886
1886
  rebuiltEngine?.abandon();
1887
1887
  } catch {}
1888
- if (generationName !== null) {
1888
+ if (generationName !== null && wasm !== null) {
1889
1889
  const active = await readActiveGenerationOrNull(wasm, dbName);
1890
1890
  if (active !== void 0 && active !== generationName) try {
1891
1891
  await wasm.cleanupInactiveEntries(dbName);
@@ -1995,14 +1995,6 @@ var DbWorker = class {
1995
1995
  else if (op.kind === "delete" && outcome.kind === "delete") this.recordDeleteChange(txId, store, op.key, outcome.deleted);
1996
1996
  }
1997
1997
  }
1998
- recordBatchKeyOutcomes(txId, store, ops, outcomes) {
1999
- for (let i = 0; i < outcomes.length && i < ops.length; i += 1) {
2000
- const op = ops[i];
2001
- const outcome = outcomes[i];
2002
- if (op.kind === "put" && outcome.kind === "put") this.recordPutChange(txId, store, op.key, outcome.baselineExists);
2003
- else if (op.kind === "delete" && outcome.kind === "delete") this.recordDeleteChange(txId, store, op.key, outcome.deleted);
2004
- }
2005
- }
2006
1998
  finalizeTrackedChanges(tracked) {
2007
1999
  const stores = [];
2008
2000
  for (const [store, trackedStore] of tracked) {
@@ -2646,7 +2638,7 @@ var DbWorker = class {
2646
2638
  } catch {
2647
2639
  return null;
2648
2640
  }
2649
- if (loaded.length !== selectedIndices.length) throw remoteError("InternalError", `get_many outcome count mismatch: ${loaded.length} != ${selectedIndices.length}`);
2641
+ if (loaded.length !== selectedIndices.length) throw outcomeCountMismatch("get_many", loaded.length, selectedIndices.length);
2650
2642
  for (let index = 0; index < loaded.length; index += 1) {
2651
2643
  values[selectedIndices[index]] = loaded[index];
2652
2644
  loaded[index] = null;
@@ -2808,6 +2800,9 @@ function normalizeEngineHealth(health) {
2808
2800
  };
2809
2801
  return { state: health.state };
2810
2802
  }
2803
+ function outcomeCountMismatch(operation, actual, expected) {
2804
+ return remoteError("InternalError", `${operation} outcome count mismatch: ${actual} != ${expected}`);
2805
+ }
2811
2806
  function partialBooleanOutcomes(error) {
2812
2807
  if (!isRecord(error) || !Array.isArray(error.partial)) return [];
2813
2808
  return error.partial.filter((value) => typeof value === "boolean");