@tanstack/db-sqlite-persistence-core 0.2.17 → 0.2.18
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/dist/cjs/persisted.cjs +106 -37
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/esm/persisted.js +107 -38
- package/dist/esm/persisted.js.map +1 -1
- package/package.json +2 -2
- package/src/persisted.ts +114 -40
package/dist/cjs/persisted.cjs
CHANGED
|
@@ -233,6 +233,8 @@ class PersistedCollectionRuntime {
|
|
|
233
233
|
this.startupMetadataPromise = null;
|
|
234
234
|
this.startPromise = null;
|
|
235
235
|
this.internalApplyDepth = 0;
|
|
236
|
+
this.appliedReceiptSequence = 0;
|
|
237
|
+
this.pendingAppliedReceipts = /* @__PURE__ */ new Map();
|
|
236
238
|
this.isHydrating = false;
|
|
237
239
|
this.coordinatorUnsubscribe = null;
|
|
238
240
|
this.indexAddedUnsubscribe = null;
|
|
@@ -247,7 +249,29 @@ class PersistedCollectionRuntime {
|
|
|
247
249
|
this.localRowVersion = 0;
|
|
248
250
|
}
|
|
249
251
|
setSyncControls(syncControls) {
|
|
250
|
-
|
|
252
|
+
const commit = syncControls.commit;
|
|
253
|
+
this.syncControls = {
|
|
254
|
+
...syncControls,
|
|
255
|
+
commit: commit ? (signal) => this.trackAppliedReceipt(commit(signal)) : null
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
trackAppliedReceipt(receipt) {
|
|
259
|
+
const sequence = ++this.appliedReceiptSequence;
|
|
260
|
+
if (receipt === true) {
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
this.pendingAppliedReceipts.set(sequence, receipt);
|
|
264
|
+
const removeReceipt = () => this.pendingAppliedReceipts.delete(sequence);
|
|
265
|
+
void receipt.then(removeReceipt, removeReceipt);
|
|
266
|
+
return receipt;
|
|
267
|
+
}
|
|
268
|
+
async waitForAppliedReceiptsAfter(cursor) {
|
|
269
|
+
await Promise.all(
|
|
270
|
+
Array.from(
|
|
271
|
+
this.pendingAppliedReceipts,
|
|
272
|
+
([sequence, receipt]) => sequence > cursor ? receipt : void 0
|
|
273
|
+
)
|
|
274
|
+
);
|
|
251
275
|
}
|
|
252
276
|
clearSyncControls() {
|
|
253
277
|
this.syncControls = {
|
|
@@ -302,9 +326,11 @@ class PersistedCollectionRuntime {
|
|
|
302
326
|
await this.bootstrapPersistedIndexes(indexBootstrapSnapshot);
|
|
303
327
|
if (this.syncMode !== `on-demand`) {
|
|
304
328
|
this.activeSubsets.set(this.getSubsetKey({}), {});
|
|
329
|
+
const appliedCursor = this.appliedReceiptSequence;
|
|
305
330
|
await this.applyMutex.run(
|
|
306
331
|
() => this.hydrateSubsetUnsafe({}, { requestRemoteEnsure: false })
|
|
307
332
|
);
|
|
333
|
+
await this.waitForAppliedReceiptsAfter(appliedCursor);
|
|
308
334
|
}
|
|
309
335
|
}
|
|
310
336
|
async loadStartupMetadataInternal() {
|
|
@@ -353,16 +379,18 @@ class PersistedCollectionRuntime {
|
|
|
353
379
|
}
|
|
354
380
|
async loadSubset(options, upstreamLoadSubset) {
|
|
355
381
|
this.activeSubsets.set(this.getSubsetKey(options), options);
|
|
382
|
+
const appliedCursor = this.appliedReceiptSequence;
|
|
356
383
|
await this.applyMutex.run(
|
|
357
384
|
() => this.hydrateSubsetUnsafe(options, {
|
|
358
385
|
requestRemoteEnsure: this.mode === `sync-present`
|
|
359
386
|
})
|
|
360
387
|
);
|
|
388
|
+
await this.waitForAppliedReceiptsAfter(appliedCursor);
|
|
361
389
|
if (upstreamLoadSubset) {
|
|
362
390
|
try {
|
|
363
391
|
const maybePromise = upstreamLoadSubset(options);
|
|
364
392
|
if (maybePromise instanceof Promise) {
|
|
365
|
-
maybePromise.catch((error) => {
|
|
393
|
+
await maybePromise.catch((error) => {
|
|
366
394
|
console.warn(
|
|
367
395
|
`Failed to load remote subset in persisted wrapper:`,
|
|
368
396
|
error
|
|
@@ -485,6 +513,9 @@ class PersistedCollectionRuntime {
|
|
|
485
513
|
}
|
|
486
514
|
this.pendingRemoteSubsetEnsures.clear();
|
|
487
515
|
this.activeSubsets.clear();
|
|
516
|
+
for (const transaction of this.queuedHydrationTransactions) {
|
|
517
|
+
transaction.rejectApplied?.(new db.SyncTransactionAbortedError());
|
|
518
|
+
}
|
|
488
519
|
this.queuedHydrationTransactions.length = 0;
|
|
489
520
|
this.queuedTxCommitted.length = 0;
|
|
490
521
|
this.clearSyncControls();
|
|
@@ -492,7 +523,7 @@ class PersistedCollectionRuntime {
|
|
|
492
523
|
withInternalApply(task) {
|
|
493
524
|
this.internalApplyDepth++;
|
|
494
525
|
try {
|
|
495
|
-
task();
|
|
526
|
+
return task();
|
|
496
527
|
} finally {
|
|
497
528
|
this.internalApplyDepth--;
|
|
498
529
|
}
|
|
@@ -588,26 +619,41 @@ class PersistedCollectionRuntime {
|
|
|
588
619
|
if (!transaction) {
|
|
589
620
|
continue;
|
|
590
621
|
}
|
|
591
|
-
|
|
622
|
+
try {
|
|
623
|
+
await this.applyBufferedSyncTransactionUnsafe(transaction);
|
|
624
|
+
} catch (error) {
|
|
625
|
+
transaction.rejectApplied?.(error);
|
|
626
|
+
for (const abandoned of this.queuedHydrationTransactions) {
|
|
627
|
+
abandoned.rejectApplied?.(error);
|
|
628
|
+
}
|
|
629
|
+
this.queuedHydrationTransactions.length = 0;
|
|
630
|
+
throw error;
|
|
631
|
+
}
|
|
592
632
|
}
|
|
593
633
|
}
|
|
594
634
|
async applyBufferedSyncTransactionUnsafe(transaction) {
|
|
595
|
-
if (
|
|
635
|
+
if (transaction.signal?.aborted) {
|
|
636
|
+
transaction.rejectApplied?.(new db.SyncTransactionAbortedError());
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const { begin, write, commit, truncate, metadata } = this.syncControls;
|
|
640
|
+
if (!begin || !write || !commit) {
|
|
641
|
+
transaction.rejectApplied?.(new db.SyncTransactionAbortedError());
|
|
596
642
|
return;
|
|
597
643
|
}
|
|
598
644
|
const applyToCollection = () => {
|
|
599
|
-
|
|
645
|
+
begin();
|
|
600
646
|
if (transaction.truncate) {
|
|
601
|
-
|
|
647
|
+
truncate?.();
|
|
602
648
|
}
|
|
603
649
|
for (const operation of transaction.operations) {
|
|
604
650
|
if (operation.type === `delete`) {
|
|
605
|
-
|
|
651
|
+
write({
|
|
606
652
|
type: `delete`,
|
|
607
653
|
key: operation.key
|
|
608
654
|
});
|
|
609
655
|
} else {
|
|
610
|
-
|
|
656
|
+
write({
|
|
611
657
|
type: `update`,
|
|
612
658
|
value: operation.value,
|
|
613
659
|
metadata: operation.metadata
|
|
@@ -616,26 +662,33 @@ class PersistedCollectionRuntime {
|
|
|
616
662
|
}
|
|
617
663
|
for (const [key, metadataWrite] of transaction.rowMetadataWrites) {
|
|
618
664
|
if (metadataWrite.type === `delete`) {
|
|
619
|
-
|
|
665
|
+
metadata?.row.delete(key);
|
|
620
666
|
} else {
|
|
621
|
-
|
|
667
|
+
metadata?.row.set(key, metadataWrite.value);
|
|
622
668
|
}
|
|
623
669
|
}
|
|
624
670
|
for (const [key, metadataWrite] of transaction.collectionMetadataWrites) {
|
|
625
671
|
if (metadataWrite.type === `delete`) {
|
|
626
|
-
|
|
672
|
+
metadata?.collection.delete(key);
|
|
627
673
|
} else {
|
|
628
|
-
|
|
674
|
+
metadata?.collection.set(key, metadataWrite.value);
|
|
629
675
|
}
|
|
630
676
|
}
|
|
631
|
-
|
|
677
|
+
return commit(transaction.signal);
|
|
632
678
|
};
|
|
633
|
-
|
|
634
|
-
this.withInternalApply(applyToCollection);
|
|
635
|
-
|
|
679
|
+
try {
|
|
680
|
+
const applied = transaction.internal ? this.withInternalApply(applyToCollection) : applyToCollection();
|
|
681
|
+
if (applied !== true) {
|
|
682
|
+
await applied;
|
|
683
|
+
}
|
|
684
|
+
if (!transaction.internal) {
|
|
685
|
+
await this.persistAndBroadcastExternalSyncTransactionUnsafe(transaction);
|
|
686
|
+
}
|
|
687
|
+
transaction.resolveApplied?.();
|
|
688
|
+
} catch (error) {
|
|
689
|
+
transaction.rejectApplied?.(error);
|
|
690
|
+
throw error;
|
|
636
691
|
}
|
|
637
|
-
applyToCollection();
|
|
638
|
-
await this.persistAndBroadcastExternalSyncTransactionUnsafe(transaction);
|
|
639
692
|
}
|
|
640
693
|
async persistAndBroadcastExternalSyncTransactionUnsafe(transaction) {
|
|
641
694
|
if (transaction.internal) {
|
|
@@ -1452,37 +1505,53 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime) {
|
|
|
1452
1505
|
params.truncate();
|
|
1453
1506
|
}
|
|
1454
1507
|
},
|
|
1455
|
-
commit: () => {
|
|
1508
|
+
commit: (signal) => {
|
|
1456
1509
|
const openTransaction = transactionStack.pop();
|
|
1457
1510
|
if (!openTransaction) {
|
|
1458
|
-
params.commit();
|
|
1459
|
-
return;
|
|
1511
|
+
return params.commit(signal);
|
|
1460
1512
|
}
|
|
1461
1513
|
if (openTransaction.queuedBecauseHydrating) {
|
|
1514
|
+
if (signal?.aborted) {
|
|
1515
|
+
const aborted = Promise.reject(new db.SyncTransactionAbortedError());
|
|
1516
|
+
void aborted.catch(() => void 0);
|
|
1517
|
+
return aborted;
|
|
1518
|
+
}
|
|
1519
|
+
let resolveApplied;
|
|
1520
|
+
let rejectApplied;
|
|
1521
|
+
const applied2 = new Promise((resolve, reject) => {
|
|
1522
|
+
resolveApplied = resolve;
|
|
1523
|
+
rejectApplied = reject;
|
|
1524
|
+
});
|
|
1525
|
+
void applied2.catch(() => void 0);
|
|
1462
1526
|
runtime.queueHydrationBufferedTransaction({
|
|
1463
1527
|
operations: openTransaction.operations,
|
|
1464
1528
|
rowMetadataWrites: openTransaction.rowMetadataWrites,
|
|
1465
1529
|
collectionMetadataWrites: openTransaction.collectionMetadataWrites,
|
|
1466
1530
|
truncate: openTransaction.truncate,
|
|
1467
|
-
internal: openTransaction.internal
|
|
1531
|
+
internal: openTransaction.internal,
|
|
1532
|
+
signal,
|
|
1533
|
+
resolveApplied,
|
|
1534
|
+
rejectApplied
|
|
1468
1535
|
});
|
|
1469
|
-
return;
|
|
1536
|
+
return applied2;
|
|
1470
1537
|
}
|
|
1471
|
-
params.commit();
|
|
1538
|
+
const applied = params.commit(signal);
|
|
1472
1539
|
if (!openTransaction.internal) {
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1540
|
+
const persistAfterApplication = async () => {
|
|
1541
|
+
if (applied !== true) await applied;
|
|
1542
|
+
await runtime.persistAndBroadcastExternalSyncTransaction({
|
|
1543
|
+
operations: openTransaction.operations,
|
|
1544
|
+
rowMetadataWrites: openTransaction.rowMetadataWrites,
|
|
1545
|
+
collectionMetadataWrites: openTransaction.collectionMetadataWrites,
|
|
1546
|
+
truncate: openTransaction.truncate,
|
|
1547
|
+
internal: false
|
|
1548
|
+
});
|
|
1549
|
+
};
|
|
1550
|
+
const persisted = persistAfterApplication();
|
|
1551
|
+
void persisted.catch(() => void 0);
|
|
1552
|
+
return persisted;
|
|
1485
1553
|
}
|
|
1554
|
+
return applied;
|
|
1486
1555
|
}
|
|
1487
1556
|
};
|
|
1488
1557
|
let sourceResult = {};
|