@korajs/store 1.0.0-beta.1 → 1.0.0-beta.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.
Files changed (37) hide show
  1. package/dist/adapters/indexeddb.cjs +39 -5
  2. package/dist/adapters/indexeddb.cjs.map +1 -1
  3. package/dist/adapters/indexeddb.js +13 -6
  4. package/dist/adapters/indexeddb.js.map +1 -1
  5. package/dist/adapters/sqlite-wasm-worker.cjs +25 -3
  6. package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
  7. package/dist/adapters/sqlite-wasm-worker.js +25 -3
  8. package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
  9. package/dist/adapters/sqlite-wasm.cjs +29 -0
  10. package/dist/adapters/sqlite-wasm.cjs.map +1 -1
  11. package/dist/adapters/sqlite-wasm.d.cts +16 -1
  12. package/dist/adapters/sqlite-wasm.d.ts +16 -1
  13. package/dist/adapters/sqlite-wasm.js +1 -1
  14. package/dist/{backup-ZV4Y424B.js → backup-IQE4QC7Q.js} +2 -2
  15. package/dist/{chunk-ZLWAYQEQ.js → chunk-2VRPF25R.js} +31 -27
  16. package/dist/chunk-2VRPF25R.js.map +1 -0
  17. package/dist/{chunk-X57MWW35.js → chunk-OCOGQRHW.js} +12 -9
  18. package/dist/chunk-OCOGQRHW.js.map +1 -0
  19. package/dist/{chunk-RBPVEAVM.js → chunk-QUJGXSZ6.js} +30 -1
  20. package/dist/chunk-QUJGXSZ6.js.map +1 -0
  21. package/dist/{chunk-FFYA7J5H.js → chunk-RCTG3IJG.js} +3 -2
  22. package/dist/chunk-RCTG3IJG.js.map +1 -0
  23. package/dist/{export-audit-AJ7RORNK.js → export-audit-MT2LTMIN.js} +2 -2
  24. package/dist/index.cjs +155 -141
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.js +48 -40
  27. package/dist/index.js.map +1 -1
  28. package/dist/internal.cjs +45 -40
  29. package/dist/internal.cjs.map +1 -1
  30. package/dist/internal.js +1 -1
  31. package/package.json +2 -2
  32. package/dist/chunk-FFYA7J5H.js.map +0 -1
  33. package/dist/chunk-RBPVEAVM.js.map +0 -1
  34. package/dist/chunk-X57MWW35.js.map +0 -1
  35. package/dist/chunk-ZLWAYQEQ.js.map +0 -1
  36. /package/dist/{backup-ZV4Y424B.js.map → backup-IQE4QC7Q.js.map} +0 -0
  37. /package/dist/{export-audit-AJ7RORNK.js.map → export-audit-MT2LTMIN.js.map} +0 -0
package/dist/index.js CHANGED
@@ -3,12 +3,12 @@ import {
3
3
  readBackupManifest,
4
4
  restoreBackup,
5
5
  verifyBackupChecksum
6
- } from "./chunk-X57MWW35.js";
6
+ } from "./chunk-OCOGQRHW.js";
7
7
  import {
8
8
  decodeAuditExport,
9
9
  readAuditExportManifest,
10
10
  verifyAuditExportChecksum
11
- } from "./chunk-FFYA7J5H.js";
11
+ } from "./chunk-RCTG3IJG.js";
12
12
  import {
13
13
  persistedAuditTraceFromEvent
14
14
  } from "./chunk-MYSJN3DF.js";
@@ -39,7 +39,7 @@ import {
39
39
  serializeRowVersion,
40
40
  validateStateTransition,
41
41
  validateUpdateStateMachine
42
- } from "./chunk-ZLWAYQEQ.js";
42
+ } from "./chunk-2VRPF25R.js";
43
43
  import {
44
44
  decodeRichtext,
45
45
  decodeRichtextFieldsFromOpData,
@@ -67,7 +67,7 @@ import {
67
67
  var COMPACTION_BASELINE_META_KEY = "compaction_baseline_at";
68
68
 
69
69
  // src/compaction/compact-operation-log.ts
70
- import { HybridLogicalClock, createVersionVector } from "@korajs/core";
70
+ import { HybridLogicalClock, createVersionVector, quoteIdent } from "@korajs/core";
71
71
  function computeAckCompactionWatermark(serverVector) {
72
72
  const watermark = createVersionVector();
73
73
  for (const [nodeId, seq] of serverVector) {
@@ -95,7 +95,7 @@ async function compactOperationLog(adapter, schema, strategy, serverVector) {
95
95
  const collectionNames = Object.keys(schema.collections);
96
96
  await adapter.transaction(async (tx) => {
97
97
  for (const collectionName of collectionNames) {
98
- const table = `_kora_ops_${collectionName}`;
98
+ const table = quoteIdent(`_kora_ops_${collectionName}`);
99
99
  for (const [nodeId, maxSeq] of watermark) {
100
100
  if (maxSeq <= 0) continue;
101
101
  const countSql = buildCountSql(table, ageCutoffSerialized !== null);
@@ -209,10 +209,12 @@ import {
209
209
  HybridLogicalClock as HybridLogicalClock3,
210
210
  createVersionVector as createVersionVector3,
211
211
  generateUUIDv7 as generateUUIDv73,
212
- migrationStepsToSQL
212
+ migrationStepsToSQL,
213
+ quoteIdent as quoteIdent7
213
214
  } from "@korajs/core";
214
215
 
215
216
  // src/collection/collection.ts
217
+ import { quoteIdent as quoteIdent2 } from "@korajs/core";
216
218
  var Collection = class {
217
219
  constructor(name, definition, schema, adapter, clock, nodeId, allocateSequenceNumber, onMutation, relationEnforcer, mutationHandler, causalTracker, secretKeyProvider) {
218
220
  this.name = name;
@@ -264,7 +266,7 @@ var Collection = class {
264
266
  }
265
267
  async findById(id) {
266
268
  const rows = await this.adapter.query(
267
- `SELECT * FROM ${this.name} WHERE id = ? AND _deleted = 0`,
269
+ `SELECT * FROM ${quoteIdent2(this.name)} WHERE id = ? AND _deleted = 0`,
268
270
  [id]
269
271
  );
270
272
  const row = rows[0];
@@ -296,6 +298,9 @@ var Collection = class {
296
298
  }
297
299
  };
298
300
 
301
+ // src/query/query-builder.ts
302
+ import { quoteIdent as quoteIdent3 } from "@korajs/core";
303
+
299
304
  // src/query/pluralize.ts
300
305
  function isVowel(char) {
301
306
  if (!char) return false;
@@ -525,7 +530,7 @@ var QueryBuilder = class _QueryBuilder {
525
530
  const relatedDef = this.schema?.collections[relatedCollection];
526
531
  if (!relatedDef) return;
527
532
  const placeholders = uniqueFks.map(() => "?").join(", ");
528
- const sql = `SELECT * FROM ${relatedCollection} WHERE id IN (${placeholders}) AND _deleted = 0`;
533
+ const sql = `SELECT * FROM ${quoteIdent3(relatedCollection)} WHERE id IN (${placeholders}) AND _deleted = 0`;
529
534
  const rows = await this.adapter.query(sql, uniqueFks);
530
535
  const relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields));
531
536
  const lookup = /* @__PURE__ */ new Map();
@@ -548,7 +553,7 @@ var QueryBuilder = class _QueryBuilder {
548
553
  if (!relatedDef) return;
549
554
  const fkField = relation.field;
550
555
  const placeholders = primaryIds.map(() => "?").join(", ");
551
- const sql = `SELECT * FROM ${relatedCollection} WHERE ${fkField} IN (${placeholders}) AND _deleted = 0`;
556
+ const sql = `SELECT * FROM ${quoteIdent3(relatedCollection)} WHERE ${quoteIdent3(fkField)} IN (${placeholders}) AND _deleted = 0`;
552
557
  const rows = await this.adapter.query(sql, primaryIds);
553
558
  const relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields));
554
559
  const grouped = /* @__PURE__ */ new Map();
@@ -590,7 +595,7 @@ var QueryError2 = class extends Error {
590
595
  };
591
596
 
592
597
  // src/relations/relation-enforcer.ts
593
- import { KoraError, createOperation } from "@korajs/core";
598
+ import { KoraError, createOperation, quoteIdent as quoteIdent4 } from "@korajs/core";
594
599
 
595
600
  // src/relations/relation-lookup.ts
596
601
  function buildRelationLookup(schema) {
@@ -693,7 +698,7 @@ var RelationEnforcer = class {
693
698
  async enforceCascade(incoming, deletedRecordId, tx, causalDeps) {
694
699
  const { sourceCollection, foreignKeyField } = incoming;
695
700
  const referencingRows = await tx.query(
696
- `SELECT id FROM ${sourceCollection} WHERE ${foreignKeyField} = ? AND _deleted = 0`,
701
+ `SELECT id FROM ${quoteIdent4(sourceCollection)} WHERE ${quoteIdent4(foreignKeyField)} = ? AND _deleted = 0`,
697
702
  [deletedRecordId]
698
703
  );
699
704
  if (referencingRows.length === 0) {
@@ -740,7 +745,7 @@ var RelationEnforcer = class {
740
745
  return [];
741
746
  }
742
747
  const referencingRows = await tx.query(
743
- `SELECT id FROM ${sourceCollection} WHERE ${foreignKeyField} = ? AND _deleted = 0`,
748
+ `SELECT id FROM ${quoteIdent4(sourceCollection)} WHERE ${quoteIdent4(foreignKeyField)} = ? AND _deleted = 0`,
744
749
  [deletedRecordId]
745
750
  );
746
751
  if (referencingRows.length === 0) {
@@ -788,7 +793,7 @@ var RelationEnforcer = class {
788
793
  async enforceRestrict(incoming, deletedRecordId, tx) {
789
794
  const { sourceCollection, foreignKeyField, relationName } = incoming;
790
795
  const countRows = await tx.query(
791
- `SELECT COUNT(*) as cnt FROM ${sourceCollection} WHERE ${foreignKeyField} = ? AND _deleted = 0`,
796
+ `SELECT COUNT(*) as cnt FROM ${quoteIdent4(sourceCollection)} WHERE ${quoteIdent4(foreignKeyField)} = ? AND _deleted = 0`,
792
797
  [deletedRecordId]
793
798
  );
794
799
  const count = countRows[0]?.cnt ?? 0;
@@ -1476,7 +1481,7 @@ var SubscriptionManager = class {
1476
1481
  };
1477
1482
 
1478
1483
  // src/sync/rebase-unsynced-operations.ts
1479
- import { HybridLogicalClock as HybridLogicalClock2, MAX_LOGICAL } from "@korajs/core";
1484
+ import { HybridLogicalClock as HybridLogicalClock2, MAX_LOGICAL, quoteIdent as quoteIdent5 } from "@korajs/core";
1480
1485
  import { computeOperationId } from "@korajs/core/internal";
1481
1486
  var LOGICAL_COUNTER_LIMIT = MAX_LOGICAL + 1;
1482
1487
  function emptyResult() {
@@ -1490,7 +1495,9 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
1490
1495
  const rebased = [];
1491
1496
  let maxOtherSerializedTs = null;
1492
1497
  for (const collectionName of Object.keys(schema.collections)) {
1493
- const rows = await adapter.query(`SELECT * FROM _kora_ops_${collectionName}`);
1498
+ const rows = await adapter.query(
1499
+ `SELECT * FROM ${quoteIdent5(`_kora_ops_${collectionName}`)}`
1500
+ );
1494
1501
  for (const row of rows) {
1495
1502
  if (rebaseIds.has(row.id)) {
1496
1503
  rebased.push(deserializeOperationWithCollection(row, collectionName));
@@ -1559,7 +1566,7 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
1559
1566
  continue;
1560
1567
  }
1561
1568
  const opsTable = `_kora_ops_${oldOp.collection}`;
1562
- await tx.execute(`DELETE FROM ${opsTable} WHERE id = ?`, [oldOp.id]);
1569
+ await tx.execute(`DELETE FROM ${quoteIdent5(opsTable)} WHERE id = ?`, [oldOp.id]);
1563
1570
  const opInsert = buildInsertQuery(
1564
1571
  opsTable,
1565
1572
  serializeOperation(newOp)
@@ -1568,11 +1575,11 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
1568
1575
  const oldVersion = serializeRowVersion(oldOp.timestamp);
1569
1576
  const newVersion = serializeRowVersion(newOp.timestamp);
1570
1577
  await tx.execute(
1571
- `UPDATE ${oldOp.collection} SET _version = ?, _updated_at = ? WHERE id = ? AND _version = ?`,
1578
+ `UPDATE ${quoteIdent5(oldOp.collection)} SET _version = ?, _updated_at = ? WHERE id = ? AND _version = ?`,
1572
1579
  [newVersion, newOp.timestamp.wallTime, oldOp.recordId, oldVersion]
1573
1580
  );
1574
1581
  const rows = await tx.query(
1575
- `SELECT _field_versions FROM ${oldOp.collection} WHERE id = ?`,
1582
+ `SELECT _field_versions FROM ${quoteIdent5(oldOp.collection)} WHERE id = ?`,
1576
1583
  [oldOp.recordId]
1577
1584
  );
1578
1585
  const fieldVersions = parseFieldVersions(rows[0]?._field_versions);
@@ -1584,14 +1591,14 @@ async function rebaseUnsyncedOperationsInLog(adapter, schema, unsyncedOpIds, cor
1584
1591
  }
1585
1592
  }
1586
1593
  if (changed) {
1587
- await tx.execute(`UPDATE ${oldOp.collection} SET _field_versions = ? WHERE id = ?`, [
1588
- serializeFieldVersions(fieldVersions),
1589
- oldOp.recordId
1590
- ]);
1594
+ await tx.execute(
1595
+ `UPDATE ${quoteIdent5(oldOp.collection)} SET _field_versions = ? WHERE id = ?`,
1596
+ [serializeFieldVersions(fieldVersions), oldOp.recordId]
1597
+ );
1591
1598
  }
1592
1599
  if (oldOp.type === "insert") {
1593
1600
  await tx.execute(
1594
- `UPDATE ${oldOp.collection} SET _created_at = ? WHERE id = ? AND _created_at = ?`,
1601
+ `UPDATE ${quoteIdent5(oldOp.collection)} SET _created_at = ? WHERE id = ? AND _created_at = ?`,
1595
1602
  [newOp.timestamp.wallTime, oldOp.recordId, oldOp.timestamp.wallTime]
1596
1603
  );
1597
1604
  }
@@ -1611,6 +1618,7 @@ import {
1611
1618
  createOperation as createOperation2,
1612
1619
  generateUUIDv7,
1613
1620
  isAtomicOp,
1621
+ quoteIdent as quoteIdent6,
1614
1622
  resolveAtomicOp,
1615
1623
  toAtomicOp,
1616
1624
  validateRecord
@@ -1927,7 +1935,7 @@ var TransactionContext = class {
1927
1935
  }
1928
1936
  }
1929
1937
  const rows = await this.config.adapter.query(
1930
- `SELECT * FROM ${collectionName} WHERE id = ? AND _deleted = 0`,
1938
+ `SELECT * FROM ${quoteIdent6(collectionName)} WHERE id = ? AND _deleted = 0`,
1931
1939
  [id]
1932
1940
  );
1933
1941
  let record = rows[0] ? deserializeRecord(rows[0], definition.fields) : null;
@@ -2162,7 +2170,7 @@ var Store = class {
2162
2170
  return "skipped";
2163
2171
  }
2164
2172
  const existing = await this.adapter.query(
2165
- `SELECT id FROM _kora_ops_${collection} WHERE id = ?`,
2173
+ `SELECT id FROM ${quoteIdent7(`_kora_ops_${collection}`)} WHERE id = ?`,
2166
2174
  [op.id]
2167
2175
  );
2168
2176
  if (existing.length > 0) {
@@ -2267,7 +2275,7 @@ var Store = class {
2267
2275
  const serializedChanges = serializeRecord(materializeSource, definition.fields);
2268
2276
  const changedFields = Object.keys(serializedChanges);
2269
2277
  const currentRows = await tx.query(
2270
- `SELECT _version, _field_versions FROM ${collection} WHERE id = ?`,
2278
+ `SELECT _version, _field_versions FROM ${quoteIdent7(collection)} WHERE id = ?`,
2271
2279
  [op.recordId]
2272
2280
  );
2273
2281
  const currentRow = currentRows[0];
@@ -2363,7 +2371,7 @@ var Store = class {
2363
2371
  */
2364
2372
  async foldOrphanedOperations(tx, collection, definition, recordId) {
2365
2373
  const orphanRows = await tx.query(
2366
- `SELECT * FROM _kora_ops_${collection} WHERE record_id = ? AND type IN ('update', 'delete')`,
2374
+ `SELECT * FROM ${quoteIdent7(`_kora_ops_${collection}`)} WHERE record_id = ? AND type IN ('update', 'delete')`,
2367
2375
  [recordId]
2368
2376
  );
2369
2377
  if (orphanRows.length === 0) {
@@ -2376,7 +2384,7 @@ var Store = class {
2376
2384
  if (orphan.type === "update" && orphan.data) {
2377
2385
  const orphanChanges = serializeRecord(orphan.data, definition.fields);
2378
2386
  const rows = await tx.query(
2379
- `SELECT _version, _field_versions FROM ${collection} WHERE id = ?`,
2387
+ `SELECT _version, _field_versions FROM ${quoteIdent7(collection)} WHERE id = ?`,
2380
2388
  [recordId]
2381
2389
  );
2382
2390
  const current = rows[0];
@@ -2426,7 +2434,7 @@ var Store = class {
2426
2434
  const allOps = [];
2427
2435
  for (const collectionName of Object.keys(this.schema.collections)) {
2428
2436
  const rows = await this.adapter.query(
2429
- `SELECT * FROM _kora_ops_${collectionName} WHERE node_id = ? AND sequence_number >= ? AND sequence_number <= ? ORDER BY sequence_number ASC`,
2437
+ `SELECT * FROM ${quoteIdent7(`_kora_ops_${collectionName}`)} WHERE node_id = ? AND sequence_number >= ? AND sequence_number <= ? ORDER BY sequence_number ASC`,
2430
2438
  [nodeId, fromSeq, toSeq]
2431
2439
  );
2432
2440
  for (const row of rows) {
@@ -2445,7 +2453,7 @@ var Store = class {
2445
2453
  const allOps = [];
2446
2454
  for (const collectionName of Object.keys(this.schema.collections)) {
2447
2455
  const rows = await this.adapter.query(
2448
- `SELECT * FROM _kora_ops_${collectionName} ORDER BY sequence_number ASC`
2456
+ `SELECT * FROM ${quoteIdent7(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`
2449
2457
  );
2450
2458
  for (const row of rows) {
2451
2459
  allOps.push(deserializeOperationWithCollection(row, collectionName));
@@ -2496,7 +2504,7 @@ var Store = class {
2496
2504
  */
2497
2505
  async exportAudit(options) {
2498
2506
  this.ensureOpen();
2499
- const { exportAudit: doExport } = await import("./export-audit-AJ7RORNK.js");
2507
+ const { exportAudit: doExport } = await import("./export-audit-MT2LTMIN.js");
2500
2508
  return doExport(this.adapter, this.schema, this.nodeId, this.schema.version, options);
2501
2509
  }
2502
2510
  /**
@@ -2555,7 +2563,7 @@ var Store = class {
2555
2563
  return null;
2556
2564
  }
2557
2565
  const rows = await this.adapter.query(
2558
- `SELECT * FROM ${collection} WHERE id = ?`,
2566
+ `SELECT * FROM ${quoteIdent7(collection)} WHERE id = ?`,
2559
2567
  [recordId]
2560
2568
  );
2561
2569
  const row = rows[0];
@@ -2580,7 +2588,7 @@ var Store = class {
2580
2588
  return null;
2581
2589
  }
2582
2590
  const rows = await this.adapter.query(
2583
- `SELECT _version, _field_versions FROM ${collection} WHERE id = ?`,
2591
+ `SELECT _version, _field_versions FROM ${quoteIdent7(collection)} WHERE id = ?`,
2584
2592
  [recordId]
2585
2593
  );
2586
2594
  const row = rows[0];
@@ -2686,7 +2694,7 @@ var Store = class {
2686
2694
  async getLatestLocalOperationForRecord(collection, recordId) {
2687
2695
  this.ensureOpen();
2688
2696
  const rows = await this.adapter.query(
2689
- `SELECT * FROM _kora_ops_${collection} WHERE node_id = ? AND record_id = ? ORDER BY sequence_number DESC LIMIT 1`,
2697
+ `SELECT * FROM ${quoteIdent7(`_kora_ops_${collection}`)} WHERE node_id = ? AND record_id = ? ORDER BY sequence_number DESC LIMIT 1`,
2690
2698
  [this.nodeId, recordId]
2691
2699
  );
2692
2700
  const row = rows[0];
@@ -2701,7 +2709,7 @@ var Store = class {
2701
2709
  async getLatestOperationForRecord(collection, recordId) {
2702
2710
  this.ensureOpen();
2703
2711
  const rows = await this.adapter.query(
2704
- `SELECT * FROM _kora_ops_${collection} WHERE record_id = ?`,
2712
+ `SELECT * FROM ${quoteIdent7(`_kora_ops_${collection}`)} WHERE record_id = ?`,
2705
2713
  [recordId]
2706
2714
  );
2707
2715
  let latest = null;
@@ -2791,7 +2799,7 @@ var Store = class {
2791
2799
  */
2792
2800
  async exportBackup(options) {
2793
2801
  this.ensureOpen();
2794
- const { exportBackup: doExport } = await import("./backup-ZV4Y424B.js");
2802
+ const { exportBackup: doExport } = await import("./backup-IQE4QC7Q.js");
2795
2803
  return doExport(this.adapter, this.schema, this.nodeId, this.schema.version, options);
2796
2804
  }
2797
2805
  /**
@@ -2803,7 +2811,7 @@ var Store = class {
2803
2811
  */
2804
2812
  async importBackup(data, options) {
2805
2813
  this.ensureOpen();
2806
- const { restoreBackup: doRestore } = await import("./backup-ZV4Y424B.js");
2814
+ const { restoreBackup: doRestore } = await import("./backup-IQE4QC7Q.js");
2807
2815
  return doRestore(this.adapter, this.schema, data, options);
2808
2816
  }
2809
2817
  /**
@@ -2888,14 +2896,14 @@ var Store = class {
2888
2896
  */
2889
2897
  async runBackfill(collection, transform) {
2890
2898
  const rows = await this.adapter.query(
2891
- `SELECT * FROM ${collection} WHERE _deleted = 0`
2899
+ `SELECT * FROM ${quoteIdent7(collection)} WHERE _deleted = 0`
2892
2900
  );
2893
2901
  await this.adapter.transaction(async (tx) => {
2894
2902
  for (const row of rows) {
2895
2903
  const updates = transform(row);
2896
2904
  const fields = Object.keys(updates);
2897
2905
  if (fields.length === 0) continue;
2898
- const setClauses = fields.map((f) => `${f} = ?`).join(", ");
2906
+ const setClauses = fields.map((f) => `${quoteIdent7(f)} = ?`).join(", ");
2899
2907
  const values = fields.map((f) => {
2900
2908
  const val = updates[f];
2901
2909
  if (typeof val === "boolean") return val ? 1 : 0;
@@ -2905,7 +2913,7 @@ var Store = class {
2905
2913
  return val;
2906
2914
  });
2907
2915
  values.push(row.id);
2908
- await tx.execute(`UPDATE ${collection} SET ${setClauses} WHERE id = ?`, values);
2916
+ await tx.execute(`UPDATE ${quoteIdent7(collection)} SET ${setClauses} WHERE id = ?`, values);
2909
2917
  }
2910
2918
  });
2911
2919
  }