@tanstack/db-sqlite-persistence-core 0.4.1 → 0.4.4
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/errors.cjs.map +1 -1
- package/dist/cjs/persisted.cjs +47 -52
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/cjs/remote-subset-wire.cjs.map +1 -1
- package/dist/cjs/sqlite-core-adapter.cjs +303 -162
- package/dist/cjs/sqlite-core-adapter.cjs.map +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/persisted.js +49 -54
- package/dist/esm/persisted.js.map +1 -1
- package/dist/esm/remote-subset-wire.js.map +1 -1
- package/dist/esm/sqlite-core-adapter.js +304 -163
- package/dist/esm/sqlite-core-adapter.js.map +1 -1
- package/package.json +2 -2
- package/src/errors.ts +1 -2
- package/src/persisted.ts +80 -75
- package/src/remote-subset-wire.ts +1 -6
- package/src/sqlite-core-adapter.ts +478 -214
package/dist/cjs/errors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","sources":["../../src/errors.ts"],"sourcesContent":["import { TanStackDBError } from '@tanstack/db'\n\nexport class PersistedCollectionCoreError extends TanStackDBError {\n constructor(message: string) {\n super(message)\n this.name = `PersistedCollectionCoreError`\n }\n}\n\nexport class InvalidPersistedCollectionConfigError extends PersistedCollectionCoreError {\n constructor(message: string) {\n super(message)\n this.name = `InvalidPersistedCollectionConfigError`\n }\n}\n\nexport class InvalidSyncConfigError extends InvalidPersistedCollectionConfigError {\n constructor(details?: string) {\n super(\n details\n ? `Invalid sync config: ${details}`\n : `Invalid sync config: expected an object with a callable sync function`,\n )\n this.name = `InvalidSyncConfigError`\n }\n}\n\nexport class InvalidPersistedCollectionCoordinatorError extends InvalidPersistedCollectionConfigError {\n constructor(methodName: string) {\n super(\n `Invalid persisted collection coordinator: missing required \"${methodName}\" method`,\n )\n this.name = `InvalidPersistedCollectionCoordinatorError`\n }\n}\n\nexport class InvalidPersistenceAdapterError extends InvalidPersistedCollectionConfigError {\n constructor(methodName: string) {\n super(\n `Invalid persistence adapter: missing required \"${methodName}\" method`,\n )\n this.name = `InvalidPersistenceAdapterError`\n }\n}\n\nexport type PersistedCollectionDurabilityErrorOptions = {\n cause?: unknown\n code?: unknown\n path?: unknown\n}\n\nexport class PersistedCollectionDurabilityError extends PersistedCollectionCoreError {\n override readonly cause: unknown\n readonly code: unknown\n readonly path: unknown\n\n constructor(\n message: string,\n options: PersistedCollectionDurabilityErrorOptions = {},\n ) {\n super(message)\n this.name = `PersistedCollectionDurabilityError`\n this.cause = options.cause\n this.code = options.code\n this.path = options.path\n }\n}\n\nexport function toPersistedCollectionDurabilityError(\n collectionId: string,\n cause: unknown,\n): PersistedCollectionDurabilityError {\n if (cause instanceof PersistedCollectionDurabilityError) {\n return cause\n }\n\n const details =\n typeof cause === `object` && cause !== null\n ? (cause as Record<string, unknown>)\n : undefined\n const message = cause instanceof Error ? cause.message : String(cause)\n return new PersistedCollectionDurabilityError(\n `Failed to durably persist collection \"${collectionId}\": ${message}`,\n {\n cause,\n code: details?.code,\n path: details?.path,\n },\n )\n}\n\nexport type IndeterminateCommitRequestType =\n
|
|
1
|
+
{"version":3,"file":"errors.cjs","sources":["../../src/errors.ts"],"sourcesContent":["import { TanStackDBError } from '@tanstack/db'\n\nexport class PersistedCollectionCoreError extends TanStackDBError {\n constructor(message: string) {\n super(message)\n this.name = `PersistedCollectionCoreError`\n }\n}\n\nexport class InvalidPersistedCollectionConfigError extends PersistedCollectionCoreError {\n constructor(message: string) {\n super(message)\n this.name = `InvalidPersistedCollectionConfigError`\n }\n}\n\nexport class InvalidSyncConfigError extends InvalidPersistedCollectionConfigError {\n constructor(details?: string) {\n super(\n details\n ? `Invalid sync config: ${details}`\n : `Invalid sync config: expected an object with a callable sync function`,\n )\n this.name = `InvalidSyncConfigError`\n }\n}\n\nexport class InvalidPersistedCollectionCoordinatorError extends InvalidPersistedCollectionConfigError {\n constructor(methodName: string) {\n super(\n `Invalid persisted collection coordinator: missing required \"${methodName}\" method`,\n )\n this.name = `InvalidPersistedCollectionCoordinatorError`\n }\n}\n\nexport class InvalidPersistenceAdapterError extends InvalidPersistedCollectionConfigError {\n constructor(methodName: string) {\n super(\n `Invalid persistence adapter: missing required \"${methodName}\" method`,\n )\n this.name = `InvalidPersistenceAdapterError`\n }\n}\n\nexport type PersistedCollectionDurabilityErrorOptions = {\n cause?: unknown\n code?: unknown\n path?: unknown\n}\n\nexport class PersistedCollectionDurabilityError extends PersistedCollectionCoreError {\n override readonly cause: unknown\n readonly code: unknown\n readonly path: unknown\n\n constructor(\n message: string,\n options: PersistedCollectionDurabilityErrorOptions = {},\n ) {\n super(message)\n this.name = `PersistedCollectionDurabilityError`\n this.cause = options.cause\n this.code = options.code\n this.path = options.path\n }\n}\n\nexport function toPersistedCollectionDurabilityError(\n collectionId: string,\n cause: unknown,\n): PersistedCollectionDurabilityError {\n if (cause instanceof PersistedCollectionDurabilityError) {\n return cause\n }\n\n const details =\n typeof cause === `object` && cause !== null\n ? (cause as Record<string, unknown>)\n : undefined\n const message = cause instanceof Error ? cause.message : String(cause)\n return new PersistedCollectionDurabilityError(\n `Failed to durably persist collection \"${collectionId}\": ${message}`,\n {\n cause,\n code: details?.code,\n path: details?.path,\n },\n )\n}\n\nexport type IndeterminateCommitRequestType =\n `rpc:applyLocalMutations:req` | `rpc:applyCommittedTx:req`\n\nexport type IndeterminateCommitErrorOptions = {\n collectionId: string\n requestType: IndeterminateCommitRequestType\n previousLeaderId: string | null\n previousTerm: number | null\n currentLeaderId: string | null\n currentTerm: number | null\n cause: unknown\n}\n\nexport class IndeterminateCommitError extends PersistedCollectionCoreError {\n readonly code: `INDETERMINATE_COMMIT` = `INDETERMINATE_COMMIT`\n readonly collectionId: string\n readonly requestType: IndeterminateCommitRequestType\n readonly previousLeaderId: string | null\n readonly previousTerm: number | null\n readonly currentLeaderId: string | null\n readonly currentTerm: number | null\n override readonly cause: unknown\n\n constructor(options: IndeterminateCommitErrorOptions) {\n super(\n `Commit outcome is indeterminate for collection \"${options.collectionId}\": ${options.requestType} crossed leadership from ${formatLeader(options.previousLeaderId, options.previousTerm)} to ${formatLeader(options.currentLeaderId, options.currentTerm)}`,\n )\n this.name = `IndeterminateCommitError`\n this.collectionId = options.collectionId\n this.requestType = options.requestType\n this.previousLeaderId = options.previousLeaderId\n this.previousTerm = options.previousTerm\n this.currentLeaderId = options.currentLeaderId\n this.currentTerm = options.currentTerm\n this.cause = options.cause\n }\n}\n\nfunction formatLeader(leaderId: string | null, term: number | null): string {\n return `${leaderId ?? `unknown leader`} (term ${term ?? `unknown`})`\n}\n\nexport class DuplicateRemoteSubsetOwnerError extends PersistedCollectionCoreError {\n readonly collectionId: string\n\n constructor(collectionId: string) {\n super(\n `A remote subset owner is already registered for collection \"${collectionId}\"`,\n )\n this.name = `DuplicateRemoteSubsetOwnerError`\n this.collectionId = collectionId\n }\n}\n\nexport class RetryableRemoteSubsetAcquisitionError extends PersistedCollectionCoreError {\n override readonly cause: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = `RetryableRemoteSubsetAcquisitionError`\n this.cause = cause\n }\n}\n\nexport class InvalidPersistedStorageKeyError extends InvalidPersistedCollectionConfigError {\n constructor(key: string | number) {\n super(\n `Invalid persisted storage key \"${String(key)}\": numeric keys must be finite`,\n )\n this.name = `InvalidPersistedStorageKeyError`\n }\n}\n\nexport class InvalidPersistedStorageKeyEncodingError extends InvalidPersistedCollectionConfigError {\n constructor(encoded: string) {\n super(\n `Invalid persisted storage key encoding \"${encoded}\": expected prefix \"n:\" or \"s:\"`,\n )\n this.name = `InvalidPersistedStorageKeyEncodingError`\n }\n}\n\nexport class SQLiteBigIntOutOfRangeError extends PersistedCollectionCoreError {\n constructor(value: bigint, minimum: bigint, maximum: bigint) {\n super(\n `SQLite BigInt value ${value} is outside the signed 64-bit range [${minimum}, ${maximum}]`,\n )\n this.name = `SQLiteBigIntOutOfRangeError`\n }\n}\n\nexport class PersistenceUnavailableError extends PersistedCollectionCoreError {\n constructor(details?: string) {\n super(\n details\n ? `Persistence unavailable: ${details}`\n : `Persistence unavailable in this runtime`,\n )\n this.name = `PersistenceUnavailableError`\n }\n}\n"],"names":["TanStackDBError"],"mappings":"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"}
|
package/dist/cjs/persisted.cjs
CHANGED
|
@@ -442,7 +442,6 @@ class PersistedCollectionRuntime {
|
|
|
442
442
|
this.resumeGenerationOwner = /* @__PURE__ */ Symbol(`persisted resume generation owner`);
|
|
443
443
|
this.lifecycleGeneration = 0;
|
|
444
444
|
this.internalApplyDepth = 0;
|
|
445
|
-
this.sourcePublicationWaitDepth = 0;
|
|
446
445
|
this.appliedReceiptSequence = 0;
|
|
447
446
|
this.syncErrorReported = false;
|
|
448
447
|
this.pendingAppliedReceipts = /* @__PURE__ */ new Map();
|
|
@@ -501,11 +500,14 @@ class PersistedCollectionRuntime {
|
|
|
501
500
|
void receipt.then(removeReceipt, removeReceipt);
|
|
502
501
|
return receipt;
|
|
503
502
|
}
|
|
504
|
-
|
|
503
|
+
// Startup waits for acceptance: a local mutation's handler can wait for
|
|
504
|
+
// startup, and the rows publish when that mutation settles. Readiness waits
|
|
505
|
+
// for them in core. A subset load waits for visibility.
|
|
506
|
+
async waitForAppliedReceiptsAfter(cursor, until = `visible`) {
|
|
505
507
|
await Promise.all(
|
|
506
508
|
Array.from(
|
|
507
509
|
this.pendingAppliedReceipts,
|
|
508
|
-
([sequence, receipt]) => sequence
|
|
510
|
+
([sequence, receipt]) => sequence <= cursor ? void 0 : until === `accepted` ? db.whenSyncAccepted(receipt) : receipt
|
|
509
511
|
)
|
|
510
512
|
);
|
|
511
513
|
}
|
|
@@ -666,7 +668,10 @@ class PersistedCollectionRuntime {
|
|
|
666
668
|
startup.completedLocalIndexSignatures
|
|
667
669
|
);
|
|
668
670
|
if (startup.appliedCursor !== void 0 && lifecycleGeneration === this.lifecycleGeneration) {
|
|
669
|
-
await this.waitForAppliedReceiptsAfter(
|
|
671
|
+
await this.waitForAppliedReceiptsAfter(
|
|
672
|
+
startup.appliedCursor,
|
|
673
|
+
`accepted`
|
|
674
|
+
);
|
|
670
675
|
}
|
|
671
676
|
}
|
|
672
677
|
if (lifecycleGeneration === this.lifecycleGeneration) {
|
|
@@ -701,7 +706,7 @@ class PersistedCollectionRuntime {
|
|
|
701
706
|
return result;
|
|
702
707
|
});
|
|
703
708
|
if (appliedCursor !== void 0 && lifecycleGeneration === this.lifecycleGeneration) {
|
|
704
|
-
await this.waitForAppliedReceiptsAfter(appliedCursor);
|
|
709
|
+
await this.waitForAppliedReceiptsAfter(appliedCursor, `accepted`);
|
|
705
710
|
}
|
|
706
711
|
})().catch((error) => {
|
|
707
712
|
throw this.markTerminalFailure(error, lifecycleGeneration);
|
|
@@ -790,7 +795,7 @@ class PersistedCollectionRuntime {
|
|
|
790
795
|
const applied = this.replaceCollectionMetadataSnapshot(
|
|
791
796
|
snapshot.collectionMetadata
|
|
792
797
|
);
|
|
793
|
-
|
|
798
|
+
await db.whenSyncAccepted(applied);
|
|
794
799
|
}
|
|
795
800
|
async loadCollectionMetadataSnapshot(adapter) {
|
|
796
801
|
if (!adapter.loadCollectionMetadata) {
|
|
@@ -807,7 +812,7 @@ class PersistedCollectionRuntime {
|
|
|
807
812
|
);
|
|
808
813
|
const currentKeys = this.syncControls.metadata.collection.list().map(({ key }) => key);
|
|
809
814
|
return this.withInternalApply(() => {
|
|
810
|
-
this.syncControls.begin?.(
|
|
815
|
+
this.syncControls.begin?.();
|
|
811
816
|
currentKeys.forEach((key) => {
|
|
812
817
|
if (!nextMetadata.has(key)) {
|
|
813
818
|
this.syncControls.metadata?.collection.delete(key);
|
|
@@ -982,13 +987,6 @@ class PersistedCollectionRuntime {
|
|
|
982
987
|
applyHydrationBufferedTransaction(transaction) {
|
|
983
988
|
const failure = this.getCurrentTerminalFailure();
|
|
984
989
|
if (failure) return Promise.reject(failure.error);
|
|
985
|
-
if (transaction.beginOptions?.immediate && this.sourcePublicationWaitDepth > 0) {
|
|
986
|
-
return Promise.reject(
|
|
987
|
-
new errors.InvalidPersistedCollectionConfigError(
|
|
988
|
-
`immediate persisted source replay cannot enter while an earlier source publication is waiting`
|
|
989
|
-
)
|
|
990
|
-
);
|
|
991
|
-
}
|
|
992
990
|
return this.applyMutex.run(async () => {
|
|
993
991
|
await this.applyBufferedSyncTransactionUnsafe(transaction);
|
|
994
992
|
});
|
|
@@ -1209,7 +1207,7 @@ class PersistedCollectionRuntime {
|
|
|
1209
1207
|
hydrationContext.suppliedRowKeys.add(row.key);
|
|
1210
1208
|
}
|
|
1211
1209
|
const applied = this.applyRowsToCollection(rows);
|
|
1212
|
-
|
|
1210
|
+
await db.whenSyncAccepted(applied);
|
|
1213
1211
|
}
|
|
1214
1212
|
} finally {
|
|
1215
1213
|
if (this.activeHydrationContext === hydrationContext && this.hydratingGeneration === config.lifecycleGeneration) {
|
|
@@ -1352,7 +1350,7 @@ class PersistedCollectionRuntime {
|
|
|
1352
1350
|
return true;
|
|
1353
1351
|
}
|
|
1354
1352
|
return this.withInternalApply(() => {
|
|
1355
|
-
this.syncControls.begin?.(
|
|
1353
|
+
this.syncControls.begin?.();
|
|
1356
1354
|
for (const row of rows) {
|
|
1357
1355
|
if (this.collection?._hasHydratedKey(row.key)) {
|
|
1358
1356
|
continue;
|
|
@@ -1398,7 +1396,7 @@ class PersistedCollectionRuntime {
|
|
|
1398
1396
|
);
|
|
1399
1397
|
const currentKeys = this.syncControls.metadata.collection.list().map(({ key }) => key);
|
|
1400
1398
|
return this.withInternalApply(() => {
|
|
1401
|
-
this.syncControls.begin?.(
|
|
1399
|
+
this.syncControls.begin?.();
|
|
1402
1400
|
this.syncControls.truncate?.();
|
|
1403
1401
|
for (const row of rows) {
|
|
1404
1402
|
this.syncControls.write?.({
|
|
@@ -1452,14 +1450,9 @@ class PersistedCollectionRuntime {
|
|
|
1452
1450
|
const applied = transaction.internal ? this.withInternalApply(transaction.applyToCollection) : transaction.applyToCollection();
|
|
1453
1451
|
applicationReturned = true;
|
|
1454
1452
|
abortedDuringApplication = transaction.signal?.aborted === true;
|
|
1455
|
-
if (
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
await applied;
|
|
1459
|
-
} finally {
|
|
1460
|
-
this.sourcePublicationWaitDepth--;
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1453
|
+
if (transaction.internal) await db.whenSyncAccepted(applied);
|
|
1454
|
+
else if (applied !== true && !this.collection?._state.hasPersistingTransaction())
|
|
1455
|
+
await applied;
|
|
1463
1456
|
this.throwIfLifecycleReplaced(transaction.lifecycleGeneration);
|
|
1464
1457
|
if (!transaction.internal) {
|
|
1465
1458
|
await this.persistAndBroadcastExternalSyncTransactionUnsafe(
|
|
@@ -1629,7 +1622,7 @@ class PersistedCollectionRuntime {
|
|
|
1629
1622
|
return;
|
|
1630
1623
|
}
|
|
1631
1624
|
const applied = this.withInternalApply(() => {
|
|
1632
|
-
this.syncControls.begin?.(
|
|
1625
|
+
this.syncControls.begin?.();
|
|
1633
1626
|
for (const mutation of mutations) {
|
|
1634
1627
|
if (mutation.type === `delete`) {
|
|
1635
1628
|
this.syncControls.write?.({
|
|
@@ -1645,9 +1638,8 @@ class PersistedCollectionRuntime {
|
|
|
1645
1638
|
}
|
|
1646
1639
|
return this.syncControls.commit?.() ?? true;
|
|
1647
1640
|
});
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
}
|
|
1641
|
+
const accepted = db.whenSyncAccepted(applied);
|
|
1642
|
+
if (accepted !== true) await accepted;
|
|
1651
1643
|
}
|
|
1652
1644
|
filterMutationsForCollection(mutations) {
|
|
1653
1645
|
const collection = this.collection;
|
|
@@ -2035,11 +2027,11 @@ class PersistedCollectionRuntime {
|
|
|
2035
2027
|
this.resetSequence++;
|
|
2036
2028
|
if (this.syncControls.begin && this.syncControls.commit) {
|
|
2037
2029
|
const applied = this.withInternalApply(() => {
|
|
2038
|
-
this.syncControls.begin?.(
|
|
2030
|
+
this.syncControls.begin?.();
|
|
2039
2031
|
this.syncControls.truncate?.();
|
|
2040
2032
|
return this.syncControls.commit?.() ?? true;
|
|
2041
2033
|
});
|
|
2042
|
-
|
|
2034
|
+
await db.whenSyncAccepted(applied);
|
|
2043
2035
|
}
|
|
2044
2036
|
if (lifecycleGeneration !== this.lifecycleGeneration) return;
|
|
2045
2037
|
await this.reloadActiveSubsetsUnsafe(adapter);
|
|
@@ -2072,7 +2064,7 @@ class PersistedCollectionRuntime {
|
|
|
2072
2064
|
(opt) => opt.where ? db.compileSingleRowExpression(opt.where) : null
|
|
2073
2065
|
);
|
|
2074
2066
|
const applied = this.withInternalApply(() => {
|
|
2075
|
-
this.syncControls.begin?.(
|
|
2067
|
+
this.syncControls.begin?.();
|
|
2076
2068
|
for (const {
|
|
2077
2069
|
key: changedKey,
|
|
2078
2070
|
value: newValue
|
|
@@ -2112,7 +2104,7 @@ class PersistedCollectionRuntime {
|
|
|
2112
2104
|
});
|
|
2113
2105
|
return this.syncControls.commit?.() ?? true;
|
|
2114
2106
|
});
|
|
2115
|
-
|
|
2107
|
+
await db.whenSyncAccepted(applied);
|
|
2116
2108
|
}
|
|
2117
2109
|
async reloadActiveSubsetsUnsafe(adapter) {
|
|
2118
2110
|
const lifecycleGeneration = this.lifecycleGeneration;
|
|
@@ -2148,7 +2140,7 @@ class PersistedCollectionRuntime {
|
|
|
2148
2140
|
})),
|
|
2149
2141
|
collectionMetadata
|
|
2150
2142
|
);
|
|
2151
|
-
|
|
2143
|
+
await db.whenSyncAccepted(applied);
|
|
2152
2144
|
} finally {
|
|
2153
2145
|
if (this.activeHydrationContext === hydrationContext && this.hydratingGeneration === lifecycleGeneration) {
|
|
2154
2146
|
this.hydratingGeneration = null;
|
|
@@ -2314,6 +2306,14 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2314
2306
|
const settlePendingTransaction = (transaction) => {
|
|
2315
2307
|
removePendingPublicationTransaction(transaction);
|
|
2316
2308
|
};
|
|
2309
|
+
const visibleAfterDurable = (transaction, durable) => {
|
|
2310
|
+
const visible = durable.then(async () => {
|
|
2311
|
+
const receipt = transaction.applicationReceipt;
|
|
2312
|
+
if (receipt !== void 0 && receipt !== true) await receipt;
|
|
2313
|
+
});
|
|
2314
|
+
void visible.catch(() => void 0);
|
|
2315
|
+
return db.withAcceptedReceipt(visible, durable);
|
|
2316
|
+
};
|
|
2317
2317
|
const settleRuntimeTransaction = (transaction, applied) => {
|
|
2318
2318
|
void applied.then(
|
|
2319
2319
|
() => settlePendingTransaction(transaction),
|
|
@@ -2421,9 +2421,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2421
2421
|
}
|
|
2422
2422
|
}
|
|
2423
2423
|
transaction.deferredHydrationMetadataDeleteKeys.clear();
|
|
2424
|
-
params.begin(
|
|
2425
|
-
transaction.queuedBecauseHydrating ? { immediate: true } : transaction.beginOptions
|
|
2426
|
-
);
|
|
2424
|
+
params.begin();
|
|
2427
2425
|
if (transaction.truncate) params.truncate();
|
|
2428
2426
|
for (const operation of transaction.operations) {
|
|
2429
2427
|
if (operation.type === `delete`) {
|
|
@@ -2449,14 +2447,8 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2449
2447
|
}
|
|
2450
2448
|
const applied = params.commit(signal);
|
|
2451
2449
|
transaction.applicationReceipt = applied;
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
} else {
|
|
2455
|
-
void applied.then(
|
|
2456
|
-
() => removePendingPublicationTransaction(transaction),
|
|
2457
|
-
() => removePendingPublicationTransaction(transaction)
|
|
2458
|
-
);
|
|
2459
|
-
}
|
|
2450
|
+
removePendingPublicationTransaction(transaction);
|
|
2451
|
+
if (applied !== true) void applied.catch(() => void 0);
|
|
2460
2452
|
return applied;
|
|
2461
2453
|
} catch (error) {
|
|
2462
2454
|
removePendingPublicationTransaction(transaction);
|
|
@@ -2477,6 +2469,11 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2477
2469
|
const persistenceCapability = {
|
|
2478
2470
|
protocol: db.SYNC_PERSISTENCE_PROTOCOL,
|
|
2479
2471
|
version: db.SYNC_PERSISTENCE_VERSION,
|
|
2472
|
+
reserveCommitTurn: () => {
|
|
2473
|
+
const openTransaction = getOpenTransaction();
|
|
2474
|
+
if (openTransaction && !openTransaction.internal)
|
|
2475
|
+
openTransaction.reservesCommitTurn = true;
|
|
2476
|
+
},
|
|
2480
2477
|
hydrateBaseline: async () => {
|
|
2481
2478
|
if (startupState.cleanedUp) return;
|
|
2482
2479
|
try {
|
|
@@ -2526,7 +2523,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2526
2523
|
params.markReady();
|
|
2527
2524
|
}).catch(() => void 0);
|
|
2528
2525
|
},
|
|
2529
|
-
begin: (
|
|
2526
|
+
begin: () => {
|
|
2530
2527
|
if (startupState.cleanedUp) return void 0;
|
|
2531
2528
|
const terminalFailure = getTerminalFailure();
|
|
2532
2529
|
const internal = runtime.isApplyingInternally();
|
|
@@ -2539,7 +2536,6 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2539
2536
|
truncate: false,
|
|
2540
2537
|
internal,
|
|
2541
2538
|
lifecycleGeneration: runtime.getLifecycleGeneration(),
|
|
2542
|
-
beginOptions: options,
|
|
2543
2539
|
operationKeys: /* @__PURE__ */ new Set(),
|
|
2544
2540
|
hasDependentSuccessor: false,
|
|
2545
2541
|
queuedBecauseHydrating: terminalFailure === void 0 && !internal && runtime.isHydratingNow(),
|
|
@@ -2798,7 +2794,6 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2798
2794
|
truncate: openTransaction.truncate,
|
|
2799
2795
|
internal: false,
|
|
2800
2796
|
lifecycleGeneration: openTransaction.lifecycleGeneration,
|
|
2801
|
-
beginOptions: openTransaction.beginOptions,
|
|
2802
2797
|
expectedResumeGenerationOwner: openTransaction.expectedResumeGenerationOwner,
|
|
2803
2798
|
signal,
|
|
2804
2799
|
prependHydrationRows: (rows) => {
|
|
@@ -2840,7 +2835,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2840
2835
|
});
|
|
2841
2836
|
settlePublicationAdmissionWaiters(openTransaction);
|
|
2842
2837
|
settleRuntimeTransaction(openTransaction, applied2);
|
|
2843
|
-
return applied2;
|
|
2838
|
+
return visibleAfterDurable(openTransaction, applied2);
|
|
2844
2839
|
}
|
|
2845
2840
|
let applied;
|
|
2846
2841
|
try {
|
|
@@ -2851,7 +2846,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2851
2846
|
}
|
|
2852
2847
|
settlePublicationAdmissionWaiters(openTransaction);
|
|
2853
2848
|
settleRuntimeTransaction(openTransaction, applied);
|
|
2854
|
-
return applied;
|
|
2849
|
+
return visibleAfterDurable(openTransaction, applied);
|
|
2855
2850
|
}
|
|
2856
2851
|
};
|
|
2857
2852
|
let sourceResult = {};
|
|
@@ -2959,7 +2954,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2959
2954
|
}
|
|
2960
2955
|
};
|
|
2961
2956
|
const openTransaction = getOpenTransaction();
|
|
2962
|
-
const needsPublicationAdmission = openTransaction
|
|
2957
|
+
const needsPublicationAdmission = openTransaction?.reservesCommitTurn === true;
|
|
2963
2958
|
const hydrated = sourceResultSettled && !needsPublicationAdmission ? runtime.loadHydratedSubset(
|
|
2964
2959
|
options,
|
|
2965
2960
|
(loadOptions) => forwardUpstream(sourceResult, loadOptions)
|
|
@@ -2974,7 +2969,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2974
2969
|
return;
|
|
2975
2970
|
}
|
|
2976
2971
|
const currentTransaction = getOpenTransaction();
|
|
2977
|
-
if (currentTransaction
|
|
2972
|
+
if (currentTransaction?.reservesCommitTurn) {
|
|
2978
2973
|
await waitForPublicationAdmission(
|
|
2979
2974
|
currentTransaction,
|
|
2980
2975
|
options,
|