@tanstack/db-sqlite-persistence-core 0.4.4 → 0.4.7

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/README.md CHANGED
@@ -260,12 +260,20 @@ source publication and its durable suffix. A source may mark a transaction
260
260
  optimistic layer. The wrapper still gives that transaction one FIFO turn and
261
261
  writes its durable suffix before admitting the next source turn.
262
262
 
263
- The wrapper deliberately rejects schedules that would require a second
264
- ordering mechanism. An `immediate` source transaction cannot enter while an
265
- earlier normal source publication is waiting, and a source transaction cannot
266
- cross a hydration cycle. These cases throw
267
- `InvalidPersistedCollectionConfigError` instead of reordering data or waiting
268
- in a dependency cycle.
263
+ Persisted rows establish a baseline for newer changes from the sync adapter.
264
+ Once an ordinary sync transaction is accepted at `commit()`, queued reads of
265
+ that baseline cannot revoke acceptance. This includes subset reads and rereads
266
+ requested by coordinator reset or full-reload notifications. This rule assumes
267
+ a compatible baseline; it does not authorize using an invalidated resume point.
268
+ A truncate replay replaces earlier source rows in the same sync run. Sync
269
+ transactions ordered after that replacement apply to the replacement.
270
+
271
+ An `immediate` sync transaction cannot enter while an earlier normal source
272
+ publication is waiting. The wrapper also currently rejects a sync transaction
273
+ that remains open across another persistence read. These admission restrictions
274
+ throw `InvalidPersistedCollectionConfigError`; an internal wait after accepted
275
+ `commit()` is not an admission failure. The open-transaction restriction is
276
+ separate from the accepted-transaction precedence rule.
269
277
 
270
278
  ### Atomic resume snapshots
271
279
 
@@ -37,10 +37,15 @@ exports.PERSISTED_VALUE_TAG = sqliteValue.PERSISTED_VALUE_TAG;
37
37
  exports.SQLITE_BIGINT_MAX = sqliteValue.SQLITE_BIGINT_MAX;
38
38
  exports.SQLITE_BIGINT_MIN = sqliteValue.SQLITE_BIGINT_MIN;
39
39
  exports.assertSQLiteBigIntInRange = sqliteValue.assertSQLiteBigIntInRange;
40
+ exports.reviveSQLiteTemporal = sqliteValue.reviveSQLiteTemporal;
40
41
  exports.serializeSQLiteBigInt = sqliteValue.serializeSQLiteBigInt;
42
+ exports.serializeSQLiteTemporal = sqliteValue.serializeSQLiteTemporal;
43
+ exports.sqliteTemporalIdentity = sqliteValue.sqliteTemporalIdentity;
44
+ exports.sqliteTemporalKind = sqliteValue.sqliteTemporalKind;
41
45
  exports.RemoteSubsetWireValueError = remoteSubsetWire.RemoteSubsetWireValueError;
42
46
  exports.toProcessLocalLoadSubsetOptions = remoteSubsetWire.toProcessLocalLoadSubsetOptions;
43
47
  exports.toTransportedLoadSubsetOptions = remoteSubsetWire.toTransportedLoadSubsetOptions;
48
+ exports.validateRemoteSubsetOptions = remoteSubsetWire.validateRemoteSubsetOptions;
44
49
  Object.defineProperty(exports, "safeRandomUUID", {
45
50
  enumerable: true,
46
51
  get: () => db.safeRandomUUID
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -178,8 +178,8 @@ class SingleProcessCoordinator {
178
178
  setAdapterForCollection(collectionId, adapter) {
179
179
  this.collectionAdapters.set(collectionId, adapter);
180
180
  }
181
- async requestApplyCommittedTx(collectionId, tx) {
182
- const adapter = this.collectionAdapters.get(collectionId);
181
+ async requestApplyCommittedTx(collectionId, tx, scopedAdapter) {
182
+ const adapter = scopedAdapter ?? this.collectionAdapters.get(collectionId);
183
183
  if (!adapter) {
184
184
  throw new errors.InvalidPersistedCollectionConfigError(
185
185
  `SingleProcessCoordinator has no persistence adapter configured for collection "${collectionId}"`
@@ -335,6 +335,8 @@ function toStableSerializable(value) {
335
335
  case `undefined`:
336
336
  return void 0;
337
337
  }
338
+ const temporal = sqliteValue.serializeSQLiteTemporal(value);
339
+ if (temporal) return temporal;
338
340
  if (value instanceof Date) {
339
341
  return value.toISOString();
340
342
  }
@@ -747,7 +749,6 @@ class PersistedCollectionRuntime {
747
749
  await this.hydrateSubsetUnsafe(
748
750
  baseline,
749
751
  {
750
- requestRemoteEnsure: false,
751
752
  lifecycleGeneration,
752
753
  bindKeySetEvidence: true
753
754
  },
@@ -830,6 +831,7 @@ class PersistedCollectionRuntime {
830
831
  const subsetKey = this.getSubsetKey(options);
831
832
  const truncateGeneration = this.sourceTruncateGeneration;
832
833
  const routeRemoteDemandDuringHydration = this.canRouteRemoteDemandThroughCoordinator();
834
+ if (routeRemoteDemandDuringHydration) remoteSubsetWire.validateRemoteSubsetOptions(options);
833
835
  this.activeSubsets.set(subsetKey, options);
834
836
  const appliedCursor = this.appliedReceiptSequence;
835
837
  try {
@@ -839,7 +841,6 @@ class PersistedCollectionRuntime {
839
841
  (adapter) => this.hydrateSubsetUnsafe(
840
842
  options,
841
843
  {
842
- requestRemoteEnsure: this.mode === `sync-present` && !routeRemoteDemandDuringHydration,
843
844
  lifecycleGeneration,
844
845
  requestLocalLoadFailure: true,
845
846
  rejectBufferedReplayFailure: true
@@ -855,6 +856,9 @@ class PersistedCollectionRuntime {
855
856
  });
856
857
  if (lifecycleGeneration !== this.lifecycleGeneration) return;
857
858
  await this.waitForAppliedReceiptsAfter(appliedCursor);
859
+ if (!routeRemoteDemandDuringHydration && this.canRouteRemoteDemandThroughCoordinator()) {
860
+ remoteSubsetWire.validateRemoteSubsetOptions(options);
861
+ }
858
862
  } catch (error) {
859
863
  if (this.activeSubsets.get(subsetKey) === options) {
860
864
  this.activeSubsets.delete(subsetKey);
@@ -964,7 +968,6 @@ class PersistedCollectionRuntime {
964
968
  (adapter) => this.hydrateSubsetUnsafe(
965
969
  options,
966
970
  {
967
- requestRemoteEnsure: false,
968
971
  lifecycleGeneration,
969
972
  rejectBufferedReplayFailure: true
970
973
  },
@@ -1217,9 +1220,6 @@ class PersistedCollectionRuntime {
1217
1220
  if (config.lifecycleGeneration !== this.lifecycleGeneration) return;
1218
1221
  replayFailure = await this.flushQueuedHydrationTransactionsUnsafe(adapter);
1219
1222
  if (config.lifecycleGeneration !== this.lifecycleGeneration) return;
1220
- if (config.requestRemoteEnsure && !replayFailure) {
1221
- this.queueRemoteSubsetEnsure(options);
1222
- }
1223
1223
  } catch (error) {
1224
1224
  if (config.requestLocalLoadFailure && !rowsLoaded) {
1225
1225
  this.hydratingGeneration = config.lifecycleGeneration;
@@ -1812,6 +1812,7 @@ class PersistedCollectionRuntime {
1812
1812
  }
1813
1813
  const subsetKey = this.getSubsetKey(options);
1814
1814
  if (this.activeSubsets.get(subsetKey) !== options) return;
1815
+ remoteSubsetWire.validateRemoteSubsetOptions(options);
1815
1816
  this.pendingRemoteSubsetEnsures.set(subsetKey, options);
1816
1817
  void this.flushPendingRemoteSubsetEnsures();
1817
1818
  }
@@ -2214,8 +2215,8 @@ class PersistedCollectionRuntime {
2214
2215
  await this.requestCoordinatorPersistedIndex(indexMetadata, completedLocally);
2215
2216
  }
2216
2217
  async ensureLocalPersistedIndex(indexMetadata, adapter) {
2217
- const spec = this.buildPersistedIndexSpec(indexMetadata);
2218
2218
  try {
2219
+ const spec = this.buildPersistedIndexSpec(indexMetadata);
2219
2220
  await adapter.ensureIndex(
2220
2221
  this.collectionId,
2221
2222
  indexMetadata.signature,
@@ -2228,8 +2229,8 @@ class PersistedCollectionRuntime {
2228
2229
  }
2229
2230
  }
2230
2231
  async requestCoordinatorPersistedIndex(indexMetadata, completedLocally) {
2231
- const spec = this.buildPersistedIndexSpec(indexMetadata);
2232
2232
  try {
2233
+ const spec = this.buildPersistedIndexSpec(indexMetadata);
2233
2234
  await this.persistence.coordinator.requestEnsurePersistedIndex(
2234
2235
  this.collectionId,
2235
2236
  indexMetadata.signature,
@@ -2837,6 +2838,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
2837
2838
  settleRuntimeTransaction(openTransaction, applied2);
2838
2839
  return visibleAfterDurable(openTransaction, applied2);
2839
2840
  }
2841
+ openTransaction.hydrationSequence = void 0;
2840
2842
  let applied;
2841
2843
  try {
2842
2844
  applied = runtime.applyHydrationBufferedTransaction(transaction);