@tanstack/db-sqlite-persistence-core 0.4.3 → 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.
@@ -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 | `rpc:applyLocalMutations:req`\n | `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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"}
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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"}
@@ -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, InvalidPersistedCollectionCoordinatorError, InvalidSyncConfigError, InvalidPersistedStorageKeyError, InvalidPersistedStorageKeyEncodingError, PersistedCollectionDurabilityError, InvalidPersistenceAdapterError } from "./errors.js";
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
- async waitForAppliedReceiptsAfter(cursor) {
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 > cursor ? receipt : void 0
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(startup.appliedCursor);
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
- if (applied !== true) await applied;
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?.({ immediate: true });
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
- if (applied !== true) await applied;
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?.({ immediate: true });
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?.({ immediate: true });
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 (applied !== true) {
1454
- this.sourcePublicationWaitDepth++;
1455
- try {
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?.({ immediate: true });
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
- if (applied !== true) {
1647
- await applied;
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?.({ immediate: true });
2028
+ this.syncControls.begin?.();
2037
2029
  this.syncControls.truncate?.();
2038
2030
  return this.syncControls.commit?.() ?? true;
2039
2031
  });
2040
- if (applied !== true) await applied;
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?.({ immediate: true });
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
- if (applied !== true) await applied;
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
- if (applied !== true) await applied;
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
- if (applied === true) {
2451
- removePendingPublicationTransaction(transaction);
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: (options) => {
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 && !openTransaction.internal && openTransaction.beginOptions?.immediate;
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 && !currentTransaction.internal && currentTransaction.beginOptions?.immediate) {
2970
+ if (currentTransaction?.reservesCommitTurn) {
2976
2971
  await waitForPublicationAdmission(
2977
2972
  currentTransaction,
2978
2973
  options,