@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/esm/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","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.js","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":[],"mappings":"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"}
|
package/dist/esm/persisted.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { safeRandomUUID, withCollectionConfigFactory, SyncTransactionAbortedError, getLoadSubsetDemandKey, compileSingleRowExpression, toBooleanPredicate, SYNC_PERSISTENCE_VERSION, SYNC_PERSISTENCE_PROTOCOL, PERSISTED_READINESS, NoPendingSyncTransactionCommitError, NoPendingSyncTransactionWriteError } from "@tanstack/db";
|
|
2
|
-
import { InvalidPersistedCollectionConfigError, DuplicateRemoteSubsetOwnerError, toPersistedCollectionDurabilityError,
|
|
1
|
+
import { safeRandomUUID, withCollectionConfigFactory, whenSyncAccepted, SyncTransactionAbortedError, getLoadSubsetDemandKey, compileSingleRowExpression, toBooleanPredicate, SYNC_PERSISTENCE_VERSION, SYNC_PERSISTENCE_PROTOCOL, PERSISTED_READINESS, NoPendingSyncTransactionCommitError, NoPendingSyncTransactionWriteError, withAcceptedReceipt } from "@tanstack/db";
|
|
2
|
+
import { InvalidPersistedCollectionConfigError, DuplicateRemoteSubsetOwnerError, toPersistedCollectionDurabilityError, InvalidPersistedStorageKeyEncodingError, InvalidPersistedStorageKeyError, InvalidSyncConfigError, InvalidPersistedCollectionCoordinatorError, PersistedCollectionDurabilityError, InvalidPersistenceAdapterError } from "./errors.js";
|
|
3
3
|
import { serializeSQLiteBigInt } from "./sqlite-value.js";
|
|
4
4
|
import { toTransportedLoadSubsetOptions, toProcessLocalLoadSubsetOptions } from "./remote-subset-wire.js";
|
|
5
5
|
import { reportRemoteSubsetOwnerError, unloadRemoteSubsetOwner } from "./remote-subset-owner.js";
|
|
@@ -440,7 +440,6 @@ class PersistedCollectionRuntime {
|
|
|
440
440
|
this.resumeGenerationOwner = /* @__PURE__ */ Symbol(`persisted resume generation owner`);
|
|
441
441
|
this.lifecycleGeneration = 0;
|
|
442
442
|
this.internalApplyDepth = 0;
|
|
443
|
-
this.sourcePublicationWaitDepth = 0;
|
|
444
443
|
this.appliedReceiptSequence = 0;
|
|
445
444
|
this.syncErrorReported = false;
|
|
446
445
|
this.pendingAppliedReceipts = /* @__PURE__ */ new Map();
|
|
@@ -499,11 +498,14 @@ class PersistedCollectionRuntime {
|
|
|
499
498
|
void receipt.then(removeReceipt, removeReceipt);
|
|
500
499
|
return receipt;
|
|
501
500
|
}
|
|
502
|
-
|
|
501
|
+
// Startup waits for acceptance: a local mutation's handler can wait for
|
|
502
|
+
// startup, and the rows publish when that mutation settles. Readiness waits
|
|
503
|
+
// for them in core. A subset load waits for visibility.
|
|
504
|
+
async waitForAppliedReceiptsAfter(cursor, until = `visible`) {
|
|
503
505
|
await Promise.all(
|
|
504
506
|
Array.from(
|
|
505
507
|
this.pendingAppliedReceipts,
|
|
506
|
-
([sequence, receipt]) => sequence
|
|
508
|
+
([sequence, receipt]) => sequence <= cursor ? void 0 : until === `accepted` ? whenSyncAccepted(receipt) : receipt
|
|
507
509
|
)
|
|
508
510
|
);
|
|
509
511
|
}
|
|
@@ -664,7 +666,10 @@ class PersistedCollectionRuntime {
|
|
|
664
666
|
startup.completedLocalIndexSignatures
|
|
665
667
|
);
|
|
666
668
|
if (startup.appliedCursor !== void 0 && lifecycleGeneration === this.lifecycleGeneration) {
|
|
667
|
-
await this.waitForAppliedReceiptsAfter(
|
|
669
|
+
await this.waitForAppliedReceiptsAfter(
|
|
670
|
+
startup.appliedCursor,
|
|
671
|
+
`accepted`
|
|
672
|
+
);
|
|
668
673
|
}
|
|
669
674
|
}
|
|
670
675
|
if (lifecycleGeneration === this.lifecycleGeneration) {
|
|
@@ -699,7 +704,7 @@ class PersistedCollectionRuntime {
|
|
|
699
704
|
return result;
|
|
700
705
|
});
|
|
701
706
|
if (appliedCursor !== void 0 && lifecycleGeneration === this.lifecycleGeneration) {
|
|
702
|
-
await this.waitForAppliedReceiptsAfter(appliedCursor);
|
|
707
|
+
await this.waitForAppliedReceiptsAfter(appliedCursor, `accepted`);
|
|
703
708
|
}
|
|
704
709
|
})().catch((error) => {
|
|
705
710
|
throw this.markTerminalFailure(error, lifecycleGeneration);
|
|
@@ -788,7 +793,7 @@ class PersistedCollectionRuntime {
|
|
|
788
793
|
const applied = this.replaceCollectionMetadataSnapshot(
|
|
789
794
|
snapshot.collectionMetadata
|
|
790
795
|
);
|
|
791
|
-
|
|
796
|
+
await whenSyncAccepted(applied);
|
|
792
797
|
}
|
|
793
798
|
async loadCollectionMetadataSnapshot(adapter) {
|
|
794
799
|
if (!adapter.loadCollectionMetadata) {
|
|
@@ -805,7 +810,7 @@ class PersistedCollectionRuntime {
|
|
|
805
810
|
);
|
|
806
811
|
const currentKeys = this.syncControls.metadata.collection.list().map(({ key }) => key);
|
|
807
812
|
return this.withInternalApply(() => {
|
|
808
|
-
this.syncControls.begin?.(
|
|
813
|
+
this.syncControls.begin?.();
|
|
809
814
|
currentKeys.forEach((key) => {
|
|
810
815
|
if (!nextMetadata.has(key)) {
|
|
811
816
|
this.syncControls.metadata?.collection.delete(key);
|
|
@@ -980,13 +985,6 @@ class PersistedCollectionRuntime {
|
|
|
980
985
|
applyHydrationBufferedTransaction(transaction) {
|
|
981
986
|
const failure = this.getCurrentTerminalFailure();
|
|
982
987
|
if (failure) return Promise.reject(failure.error);
|
|
983
|
-
if (transaction.beginOptions?.immediate && this.sourcePublicationWaitDepth > 0) {
|
|
984
|
-
return Promise.reject(
|
|
985
|
-
new InvalidPersistedCollectionConfigError(
|
|
986
|
-
`immediate persisted source replay cannot enter while an earlier source publication is waiting`
|
|
987
|
-
)
|
|
988
|
-
);
|
|
989
|
-
}
|
|
990
988
|
return this.applyMutex.run(async () => {
|
|
991
989
|
await this.applyBufferedSyncTransactionUnsafe(transaction);
|
|
992
990
|
});
|
|
@@ -1207,7 +1205,7 @@ class PersistedCollectionRuntime {
|
|
|
1207
1205
|
hydrationContext.suppliedRowKeys.add(row.key);
|
|
1208
1206
|
}
|
|
1209
1207
|
const applied = this.applyRowsToCollection(rows);
|
|
1210
|
-
|
|
1208
|
+
await whenSyncAccepted(applied);
|
|
1211
1209
|
}
|
|
1212
1210
|
} finally {
|
|
1213
1211
|
if (this.activeHydrationContext === hydrationContext && this.hydratingGeneration === config.lifecycleGeneration) {
|
|
@@ -1350,7 +1348,7 @@ class PersistedCollectionRuntime {
|
|
|
1350
1348
|
return true;
|
|
1351
1349
|
}
|
|
1352
1350
|
return this.withInternalApply(() => {
|
|
1353
|
-
this.syncControls.begin?.(
|
|
1351
|
+
this.syncControls.begin?.();
|
|
1354
1352
|
for (const row of rows) {
|
|
1355
1353
|
if (this.collection?._hasHydratedKey(row.key)) {
|
|
1356
1354
|
continue;
|
|
@@ -1396,7 +1394,7 @@ class PersistedCollectionRuntime {
|
|
|
1396
1394
|
);
|
|
1397
1395
|
const currentKeys = this.syncControls.metadata.collection.list().map(({ key }) => key);
|
|
1398
1396
|
return this.withInternalApply(() => {
|
|
1399
|
-
this.syncControls.begin?.(
|
|
1397
|
+
this.syncControls.begin?.();
|
|
1400
1398
|
this.syncControls.truncate?.();
|
|
1401
1399
|
for (const row of rows) {
|
|
1402
1400
|
this.syncControls.write?.({
|
|
@@ -1450,14 +1448,9 @@ class PersistedCollectionRuntime {
|
|
|
1450
1448
|
const applied = transaction.internal ? this.withInternalApply(transaction.applyToCollection) : transaction.applyToCollection();
|
|
1451
1449
|
applicationReturned = true;
|
|
1452
1450
|
abortedDuringApplication = transaction.signal?.aborted === true;
|
|
1453
|
-
if (
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
await applied;
|
|
1457
|
-
} finally {
|
|
1458
|
-
this.sourcePublicationWaitDepth--;
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1451
|
+
if (transaction.internal) await whenSyncAccepted(applied);
|
|
1452
|
+
else if (applied !== true && !this.collection?._state.hasPersistingTransaction())
|
|
1453
|
+
await applied;
|
|
1461
1454
|
this.throwIfLifecycleReplaced(transaction.lifecycleGeneration);
|
|
1462
1455
|
if (!transaction.internal) {
|
|
1463
1456
|
await this.persistAndBroadcastExternalSyncTransactionUnsafe(
|
|
@@ -1627,7 +1620,7 @@ class PersistedCollectionRuntime {
|
|
|
1627
1620
|
return;
|
|
1628
1621
|
}
|
|
1629
1622
|
const applied = this.withInternalApply(() => {
|
|
1630
|
-
this.syncControls.begin?.(
|
|
1623
|
+
this.syncControls.begin?.();
|
|
1631
1624
|
for (const mutation of mutations) {
|
|
1632
1625
|
if (mutation.type === `delete`) {
|
|
1633
1626
|
this.syncControls.write?.({
|
|
@@ -1643,9 +1636,8 @@ class PersistedCollectionRuntime {
|
|
|
1643
1636
|
}
|
|
1644
1637
|
return this.syncControls.commit?.() ?? true;
|
|
1645
1638
|
});
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
}
|
|
1639
|
+
const accepted = whenSyncAccepted(applied);
|
|
1640
|
+
if (accepted !== true) await accepted;
|
|
1649
1641
|
}
|
|
1650
1642
|
filterMutationsForCollection(mutations) {
|
|
1651
1643
|
const collection = this.collection;
|
|
@@ -2033,11 +2025,11 @@ class PersistedCollectionRuntime {
|
|
|
2033
2025
|
this.resetSequence++;
|
|
2034
2026
|
if (this.syncControls.begin && this.syncControls.commit) {
|
|
2035
2027
|
const applied = this.withInternalApply(() => {
|
|
2036
|
-
this.syncControls.begin?.(
|
|
2028
|
+
this.syncControls.begin?.();
|
|
2037
2029
|
this.syncControls.truncate?.();
|
|
2038
2030
|
return this.syncControls.commit?.() ?? true;
|
|
2039
2031
|
});
|
|
2040
|
-
|
|
2032
|
+
await whenSyncAccepted(applied);
|
|
2041
2033
|
}
|
|
2042
2034
|
if (lifecycleGeneration !== this.lifecycleGeneration) return;
|
|
2043
2035
|
await this.reloadActiveSubsetsUnsafe(adapter);
|
|
@@ -2070,7 +2062,7 @@ class PersistedCollectionRuntime {
|
|
|
2070
2062
|
(opt) => opt.where ? compileSingleRowExpression(opt.where) : null
|
|
2071
2063
|
);
|
|
2072
2064
|
const applied = this.withInternalApply(() => {
|
|
2073
|
-
this.syncControls.begin?.(
|
|
2065
|
+
this.syncControls.begin?.();
|
|
2074
2066
|
for (const {
|
|
2075
2067
|
key: changedKey,
|
|
2076
2068
|
value: newValue
|
|
@@ -2110,7 +2102,7 @@ class PersistedCollectionRuntime {
|
|
|
2110
2102
|
});
|
|
2111
2103
|
return this.syncControls.commit?.() ?? true;
|
|
2112
2104
|
});
|
|
2113
|
-
|
|
2105
|
+
await whenSyncAccepted(applied);
|
|
2114
2106
|
}
|
|
2115
2107
|
async reloadActiveSubsetsUnsafe(adapter) {
|
|
2116
2108
|
const lifecycleGeneration = this.lifecycleGeneration;
|
|
@@ -2146,7 +2138,7 @@ class PersistedCollectionRuntime {
|
|
|
2146
2138
|
})),
|
|
2147
2139
|
collectionMetadata
|
|
2148
2140
|
);
|
|
2149
|
-
|
|
2141
|
+
await whenSyncAccepted(applied);
|
|
2150
2142
|
} finally {
|
|
2151
2143
|
if (this.activeHydrationContext === hydrationContext && this.hydratingGeneration === lifecycleGeneration) {
|
|
2152
2144
|
this.hydratingGeneration = null;
|
|
@@ -2312,6 +2304,14 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2312
2304
|
const settlePendingTransaction = (transaction) => {
|
|
2313
2305
|
removePendingPublicationTransaction(transaction);
|
|
2314
2306
|
};
|
|
2307
|
+
const visibleAfterDurable = (transaction, durable) => {
|
|
2308
|
+
const visible = durable.then(async () => {
|
|
2309
|
+
const receipt = transaction.applicationReceipt;
|
|
2310
|
+
if (receipt !== void 0 && receipt !== true) await receipt;
|
|
2311
|
+
});
|
|
2312
|
+
void visible.catch(() => void 0);
|
|
2313
|
+
return withAcceptedReceipt(visible, durable);
|
|
2314
|
+
};
|
|
2315
2315
|
const settleRuntimeTransaction = (transaction, applied) => {
|
|
2316
2316
|
void applied.then(
|
|
2317
2317
|
() => settlePendingTransaction(transaction),
|
|
@@ -2419,9 +2419,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2419
2419
|
}
|
|
2420
2420
|
}
|
|
2421
2421
|
transaction.deferredHydrationMetadataDeleteKeys.clear();
|
|
2422
|
-
params.begin(
|
|
2423
|
-
transaction.queuedBecauseHydrating ? { immediate: true } : transaction.beginOptions
|
|
2424
|
-
);
|
|
2422
|
+
params.begin();
|
|
2425
2423
|
if (transaction.truncate) params.truncate();
|
|
2426
2424
|
for (const operation of transaction.operations) {
|
|
2427
2425
|
if (operation.type === `delete`) {
|
|
@@ -2447,14 +2445,8 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2447
2445
|
}
|
|
2448
2446
|
const applied = params.commit(signal);
|
|
2449
2447
|
transaction.applicationReceipt = applied;
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
} else {
|
|
2453
|
-
void applied.then(
|
|
2454
|
-
() => removePendingPublicationTransaction(transaction),
|
|
2455
|
-
() => removePendingPublicationTransaction(transaction)
|
|
2456
|
-
);
|
|
2457
|
-
}
|
|
2448
|
+
removePendingPublicationTransaction(transaction);
|
|
2449
|
+
if (applied !== true) void applied.catch(() => void 0);
|
|
2458
2450
|
return applied;
|
|
2459
2451
|
} catch (error) {
|
|
2460
2452
|
removePendingPublicationTransaction(transaction);
|
|
@@ -2475,6 +2467,11 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2475
2467
|
const persistenceCapability = {
|
|
2476
2468
|
protocol: SYNC_PERSISTENCE_PROTOCOL,
|
|
2477
2469
|
version: SYNC_PERSISTENCE_VERSION,
|
|
2470
|
+
reserveCommitTurn: () => {
|
|
2471
|
+
const openTransaction = getOpenTransaction();
|
|
2472
|
+
if (openTransaction && !openTransaction.internal)
|
|
2473
|
+
openTransaction.reservesCommitTurn = true;
|
|
2474
|
+
},
|
|
2478
2475
|
hydrateBaseline: async () => {
|
|
2479
2476
|
if (startupState.cleanedUp) return;
|
|
2480
2477
|
try {
|
|
@@ -2524,7 +2521,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2524
2521
|
params.markReady();
|
|
2525
2522
|
}).catch(() => void 0);
|
|
2526
2523
|
},
|
|
2527
|
-
begin: (
|
|
2524
|
+
begin: () => {
|
|
2528
2525
|
if (startupState.cleanedUp) return void 0;
|
|
2529
2526
|
const terminalFailure = getTerminalFailure();
|
|
2530
2527
|
const internal = runtime.isApplyingInternally();
|
|
@@ -2537,7 +2534,6 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2537
2534
|
truncate: false,
|
|
2538
2535
|
internal,
|
|
2539
2536
|
lifecycleGeneration: runtime.getLifecycleGeneration(),
|
|
2540
|
-
beginOptions: options,
|
|
2541
2537
|
operationKeys: /* @__PURE__ */ new Set(),
|
|
2542
2538
|
hasDependentSuccessor: false,
|
|
2543
2539
|
queuedBecauseHydrating: terminalFailure === void 0 && !internal && runtime.isHydratingNow(),
|
|
@@ -2796,7 +2792,6 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2796
2792
|
truncate: openTransaction.truncate,
|
|
2797
2793
|
internal: false,
|
|
2798
2794
|
lifecycleGeneration: openTransaction.lifecycleGeneration,
|
|
2799
|
-
beginOptions: openTransaction.beginOptions,
|
|
2800
2795
|
expectedResumeGenerationOwner: openTransaction.expectedResumeGenerationOwner,
|
|
2801
2796
|
signal,
|
|
2802
2797
|
prependHydrationRows: (rows) => {
|
|
@@ -2838,7 +2833,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2838
2833
|
});
|
|
2839
2834
|
settlePublicationAdmissionWaiters(openTransaction);
|
|
2840
2835
|
settleRuntimeTransaction(openTransaction, applied2);
|
|
2841
|
-
return applied2;
|
|
2836
|
+
return visibleAfterDurable(openTransaction, applied2);
|
|
2842
2837
|
}
|
|
2843
2838
|
let applied;
|
|
2844
2839
|
try {
|
|
@@ -2849,7 +2844,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2849
2844
|
}
|
|
2850
2845
|
settlePublicationAdmissionWaiters(openTransaction);
|
|
2851
2846
|
settleRuntimeTransaction(openTransaction, applied);
|
|
2852
|
-
return applied;
|
|
2847
|
+
return visibleAfterDurable(openTransaction, applied);
|
|
2853
2848
|
}
|
|
2854
2849
|
};
|
|
2855
2850
|
let sourceResult = {};
|
|
@@ -2957,7 +2952,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2957
2952
|
}
|
|
2958
2953
|
};
|
|
2959
2954
|
const openTransaction = getOpenTransaction();
|
|
2960
|
-
const needsPublicationAdmission = openTransaction
|
|
2955
|
+
const needsPublicationAdmission = openTransaction?.reservesCommitTurn === true;
|
|
2961
2956
|
const hydrated = sourceResultSettled && !needsPublicationAdmission ? runtime.loadHydratedSubset(
|
|
2962
2957
|
options,
|
|
2963
2958
|
(loadOptions) => forwardUpstream(sourceResult, loadOptions)
|
|
@@ -2972,7 +2967,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
|
|
|
2972
2967
|
return;
|
|
2973
2968
|
}
|
|
2974
2969
|
const currentTransaction = getOpenTransaction();
|
|
2975
|
-
if (currentTransaction
|
|
2970
|
+
if (currentTransaction?.reservesCommitTurn) {
|
|
2976
2971
|
await waitForPublicationAdmission(
|
|
2977
2972
|
currentTransaction,
|
|
2978
2973
|
options,
|