@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.
@@ -22,10 +22,61 @@ function serializeSQLiteBigInt(value) {
22
22
  [PERSISTED_VALUE_TAG]: value.toString()
23
23
  };
24
24
  }
25
+ function sqliteTemporalKind(value) {
26
+ if (value === null || typeof value !== `object`) return;
27
+ const tag = value[Symbol.toStringTag];
28
+ if (tag === `Temporal.Instant` || tag === `Temporal.PlainDate`) return tag;
29
+ return void 0;
30
+ }
31
+ function requireSQLiteTemporalConstructor(kind) {
32
+ const name = kind.slice(`Temporal.`.length);
33
+ const constructor = globalThis.Temporal?.[name];
34
+ if (typeof constructor?.from !== `function` || typeof constructor.prototype.toString !== `function`) {
35
+ throw new errors.InvalidPersistedCollectionConfigError(
36
+ `Missing global ${kind} constructor for SQLite persistence`
37
+ );
38
+ }
39
+ return constructor;
40
+ }
41
+ function reviveSQLiteTemporal(kind, value) {
42
+ return requireSQLiteTemporalConstructor(kind).from(value);
43
+ }
44
+ function serializeSQLiteTemporal(value) {
45
+ if (value === null || typeof value !== `object`) return;
46
+ const prototype = Object.getPrototypeOf(value);
47
+ if (prototype === null || prototype === Object.prototype) return;
48
+ const tag = value[Symbol.toStringTag];
49
+ if (typeof tag !== `string` || !tag.startsWith(`Temporal.`)) return;
50
+ const kind = sqliteTemporalKind(value);
51
+ if (!kind)
52
+ throw new errors.InvalidPersistedCollectionConfigError(
53
+ `Unsupported ${tag} value for SQLite persistence`
54
+ );
55
+ const constructor = requireSQLiteTemporalConstructor(kind);
56
+ let text;
57
+ try {
58
+ text = constructor.prototype.toString.call(value);
59
+ } catch {
60
+ throw new errors.InvalidPersistedCollectionConfigError(
61
+ `Invalid ${kind} value for the registered global constructor`
62
+ );
63
+ }
64
+ const native = constructor.from(text);
65
+ const iso = kind === `Temporal.PlainDate` ? native.withCalendar(`iso8601`) : void 0;
66
+ const order = iso ? `${String(iso.year + 1e6).padStart(7, `0`)}${String(iso.month).padStart(2, `0`)}${String(iso.day).padStart(2, `0`)}` : (native.epochNanoseconds + 10000000000000000000000n).toString().padStart(23, `0`);
67
+ return { [PERSISTED_TYPE_TAG]: kind, [PERSISTED_VALUE_TAG]: text, order };
68
+ }
69
+ function sqliteTemporalIdentity(value) {
70
+ return `${value[PERSISTED_TYPE_TAG]}:${value[PERSISTED_VALUE_TAG]}`;
71
+ }
25
72
  exports.PERSISTED_TYPE_TAG = PERSISTED_TYPE_TAG;
26
73
  exports.PERSISTED_VALUE_TAG = PERSISTED_VALUE_TAG;
27
74
  exports.SQLITE_BIGINT_MAX = SQLITE_BIGINT_MAX;
28
75
  exports.SQLITE_BIGINT_MIN = SQLITE_BIGINT_MIN;
29
76
  exports.assertSQLiteBigIntInRange = assertSQLiteBigIntInRange;
77
+ exports.reviveSQLiteTemporal = reviveSQLiteTemporal;
30
78
  exports.serializeSQLiteBigInt = serializeSQLiteBigInt;
79
+ exports.serializeSQLiteTemporal = serializeSQLiteTemporal;
80
+ exports.sqliteTemporalIdentity = sqliteTemporalIdentity;
81
+ exports.sqliteTemporalKind = sqliteTemporalKind;
31
82
  //# sourceMappingURL=sqlite-value.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-value.cjs","sources":["../../src/sqlite-value.ts"],"sourcesContent":["import { SQLiteBigIntOutOfRangeError } from './errors'\n\nexport const SQLITE_BIGINT_MIN = -9_223_372_036_854_775_808n\nexport const SQLITE_BIGINT_MAX = 9_223_372_036_854_775_807n\nexport const PERSISTED_TYPE_TAG = `__tanstack_db_persisted_type__`\nexport const PERSISTED_VALUE_TAG = `value`\n\nexport type SerializedSQLiteBigInt = {\n [PERSISTED_TYPE_TAG]: `bigint`\n [PERSISTED_VALUE_TAG]: string\n}\n\nexport function assertSQLiteBigIntInRange(value: bigint): bigint {\n if (value < SQLITE_BIGINT_MIN || value > SQLITE_BIGINT_MAX) {\n throw new SQLiteBigIntOutOfRangeError(\n value,\n SQLITE_BIGINT_MIN,\n SQLITE_BIGINT_MAX,\n )\n }\n return value\n}\n\nexport function serializeSQLiteBigInt(value: bigint): SerializedSQLiteBigInt {\n assertSQLiteBigIntInRange(value)\n return {\n [PERSISTED_TYPE_TAG]: `bigint`,\n [PERSISTED_VALUE_TAG]: value.toString(),\n }\n}\n"],"names":["SQLiteBigIntOutOfRangeError"],"mappings":";;;AAEO,MAAM,oBAAoB,CAAC;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAO5B,SAAS,0BAA0B,OAAuB;AAC/D,MAAI,QAAQ,qBAAqB,QAAQ,mBAAmB;AAC1D,UAAM,IAAIA,OAAAA;AAAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAuC;AAC3E,4BAA0B,KAAK;AAC/B,SAAO;AAAA,IACL,CAAC,kBAAkB,GAAG;AAAA,IACtB,CAAC,mBAAmB,GAAG,MAAM,SAAA;AAAA,EAAS;AAE1C;;;;;;;"}
1
+ {"version":3,"file":"sqlite-value.cjs","sources":["../../src/sqlite-value.ts"],"sourcesContent":["import {\n InvalidPersistedCollectionConfigError,\n SQLiteBigIntOutOfRangeError,\n} from './errors'\n\nexport const SQLITE_BIGINT_MIN = -9_223_372_036_854_775_808n\nexport const SQLITE_BIGINT_MAX = 9_223_372_036_854_775_807n\nexport const PERSISTED_TYPE_TAG = `__tanstack_db_persisted_type__`\nexport const PERSISTED_VALUE_TAG = `value`\n\nexport type SerializedSQLiteBigInt = {\n [PERSISTED_TYPE_TAG]: `bigint`\n [PERSISTED_VALUE_TAG]: string\n}\n\nexport function assertSQLiteBigIntInRange(value: bigint): bigint {\n if (value < SQLITE_BIGINT_MIN || value > SQLITE_BIGINT_MAX) {\n throw new SQLiteBigIntOutOfRangeError(\n value,\n SQLITE_BIGINT_MIN,\n SQLITE_BIGINT_MAX,\n )\n }\n return value\n}\n\nexport function serializeSQLiteBigInt(value: bigint): SerializedSQLiteBigInt {\n assertSQLiteBigIntInRange(value)\n return {\n [PERSISTED_TYPE_TAG]: `bigint`,\n [PERSISTED_VALUE_TAG]: value.toString(),\n }\n}\n\ntype SQLiteTemporalKind = `Temporal.Instant` | `Temporal.PlainDate`\ntype SQLiteTemporal = {\n epochNanoseconds: bigint\n year: number\n month: number\n day: number\n withCalendar: (calendar: string) => SQLiteTemporal\n}\ntype TemporalConstructor = {\n from: (value: string) => SQLiteTemporal\n prototype: { toString: () => string }\n}\n\nexport type SerializedSQLiteTemporal = {\n [PERSISTED_TYPE_TAG]: SQLiteTemporalKind\n [PERSISTED_VALUE_TAG]: string\n order: string\n}\n\nexport function sqliteTemporalKind(\n value: unknown,\n): SQLiteTemporalKind | undefined {\n if (value === null || typeof value !== `object`) return\n const tag = (value as { [Symbol.toStringTag]?: unknown })[Symbol.toStringTag]\n if (tag === `Temporal.Instant` || tag === `Temporal.PlainDate`) return tag\n return undefined\n}\n\nfunction requireSQLiteTemporalConstructor(\n kind: SQLiteTemporalKind,\n): TemporalConstructor {\n const name = kind.slice(`Temporal.`.length)\n const constructor = (\n globalThis as { Temporal?: Record<string, TemporalConstructor> }\n ).Temporal?.[name]\n if (\n typeof constructor?.from !== `function` ||\n typeof constructor.prototype.toString !== `function`\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Missing global ${kind} constructor for SQLite persistence`,\n )\n }\n return constructor\n}\n\nexport function reviveSQLiteTemporal(\n kind: SQLiteTemporalKind,\n value: string,\n): unknown {\n return requireSQLiteTemporalConstructor(kind).from(value)\n}\n\n/** Registered prototype methods validate the brand; user toString is ignored. */\nexport function serializeSQLiteTemporal(\n value: unknown,\n): SerializedSQLiteTemporal | undefined {\n if (value === null || typeof value !== `object`) return\n const prototype = Object.getPrototypeOf(value)\n if (prototype === null || prototype === Object.prototype) return\n const tag = (value as { [Symbol.toStringTag]?: unknown })[Symbol.toStringTag]\n if (typeof tag !== `string` || !tag.startsWith(`Temporal.`)) return\n const kind = sqliteTemporalKind(value)\n if (!kind)\n throw new InvalidPersistedCollectionConfigError(\n `Unsupported ${tag} value for SQLite persistence`,\n )\n const constructor = requireSQLiteTemporalConstructor(kind)\n let text: string\n try {\n text = constructor.prototype.toString.call(value)\n } catch {\n throw new InvalidPersistedCollectionConfigError(\n `Invalid ${kind} value for the registered global constructor`,\n )\n }\n const native = constructor.from(text)\n const iso =\n kind === `Temporal.PlainDate` ? native.withCalendar(`iso8601`) : undefined\n // Text keys avoid both floating-point precision loss and SQLite's int64 cap.\n const order = iso\n ? `${String(iso.year + 1_000_000).padStart(7, `0`)}${String(iso.month).padStart(2, `0`)}${String(iso.day).padStart(2, `0`)}`\n : (native.epochNanoseconds + 10_000_000_000_000_000_000_000n)\n .toString()\n .padStart(23, `0`)\n return { [PERSISTED_TYPE_TAG]: kind, [PERSISTED_VALUE_TAG]: text, order }\n}\n\nexport function sqliteTemporalIdentity(\n value: SerializedSQLiteTemporal,\n): string {\n return `${value[PERSISTED_TYPE_TAG]}:${value[PERSISTED_VALUE_TAG]}`\n}\n"],"names":["SQLiteBigIntOutOfRangeError","InvalidPersistedCollectionConfigError"],"mappings":";;;AAKO,MAAM,oBAAoB,CAAC;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAO5B,SAAS,0BAA0B,OAAuB;AAC/D,MAAI,QAAQ,qBAAqB,QAAQ,mBAAmB;AAC1D,UAAM,IAAIA,OAAAA;AAAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAuC;AAC3E,4BAA0B,KAAK;AAC/B,SAAO;AAAA,IACL,CAAC,kBAAkB,GAAG;AAAA,IACtB,CAAC,mBAAmB,GAAG,MAAM,SAAA;AAAA,EAAS;AAE1C;AAqBO,SAAS,mBACd,OACgC;AAChC,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU;AACjD,QAAM,MAAO,MAA6C,OAAO,WAAW;AAC5E,MAAI,QAAQ,sBAAsB,QAAQ,qBAAsB,QAAO;AACvE,SAAO;AACT;AAEA,SAAS,iCACP,MACqB;AACrB,QAAM,OAAO,KAAK,MAAM,YAAY,MAAM;AAC1C,QAAM,cACJ,WACA,WAAW,IAAI;AACjB,MACE,OAAO,aAAa,SAAS,cAC7B,OAAO,YAAY,UAAU,aAAa,YAC1C;AACA,UAAM,IAAIC,OAAAA;AAAAA,MACR,kBAAkB,IAAI;AAAA,IAAA;AAAA,EAE1B;AACA,SAAO;AACT;AAEO,SAAS,qBACd,MACA,OACS;AACT,SAAO,iCAAiC,IAAI,EAAE,KAAK,KAAK;AAC1D;AAGO,SAAS,wBACd,OACsC;AACtC,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU;AACjD,QAAM,YAAY,OAAO,eAAe,KAAK;AAC7C,MAAI,cAAc,QAAQ,cAAc,OAAO,UAAW;AAC1D,QAAM,MAAO,MAA6C,OAAO,WAAW;AAC5E,MAAI,OAAO,QAAQ,YAAY,CAAC,IAAI,WAAW,WAAW,EAAG;AAC7D,QAAM,OAAO,mBAAmB,KAAK;AACrC,MAAI,CAAC;AACH,UAAM,IAAIA,OAAAA;AAAAA,MACR,eAAe,GAAG;AAAA,IAAA;AAEtB,QAAM,cAAc,iCAAiC,IAAI;AACzD,MAAI;AACJ,MAAI;AACF,WAAO,YAAY,UAAU,SAAS,KAAK,KAAK;AAAA,EAClD,QAAQ;AACN,UAAM,IAAIA,OAAAA;AAAAA,MACR,WAAW,IAAI;AAAA,IAAA;AAAA,EAEnB;AACA,QAAM,SAAS,YAAY,KAAK,IAAI;AACpC,QAAM,MACJ,SAAS,uBAAuB,OAAO,aAAa,SAAS,IAAI;AAEnE,QAAM,QAAQ,MACV,GAAG,OAAO,IAAI,OAAO,GAAS,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,OAAO,IAAI,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,OAAO,IAAI,GAAG,EAAE,SAAS,GAAG,GAAG,CAAC,MACvH,OAAO,mBAAmB,0BACxB,WACA,SAAS,IAAI,GAAG;AACvB,SAAO,EAAE,CAAC,kBAAkB,GAAG,MAAM,CAAC,mBAAmB,GAAG,MAAM,MAAA;AACpE;AAEO,SAAS,uBACd,OACQ;AACR,SAAO,GAAG,MAAM,kBAAkB,CAAC,IAAI,MAAM,mBAAmB,CAAC;AACnE;;;;;;;;;;;"}
@@ -8,3 +8,15 @@ export type SerializedSQLiteBigInt = {
8
8
  };
9
9
  export declare function assertSQLiteBigIntInRange(value: bigint): bigint;
10
10
  export declare function serializeSQLiteBigInt(value: bigint): SerializedSQLiteBigInt;
11
+ type SQLiteTemporalKind = `Temporal.Instant` | `Temporal.PlainDate`;
12
+ export type SerializedSQLiteTemporal = {
13
+ [PERSISTED_TYPE_TAG]: SQLiteTemporalKind;
14
+ [PERSISTED_VALUE_TAG]: string;
15
+ order: string;
16
+ };
17
+ export declare function sqliteTemporalKind(value: unknown): SQLiteTemporalKind | undefined;
18
+ export declare function reviveSQLiteTemporal(kind: SQLiteTemporalKind, value: string): unknown;
19
+ /** Registered prototype methods validate the brand; user toString is ignored. */
20
+ export declare function serializeSQLiteTemporal(value: unknown): SerializedSQLiteTemporal | undefined;
21
+ export declare function sqliteTemporalIdentity(value: SerializedSQLiteTemporal): string;
22
+ export {};
package/dist/esm/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { SQLITE_DRIVER_SHARED_LOGICAL_SCHEDULING_KEY, SingleProcessCoordinator, createPersistedTableName, decodePersistedStorageKey, encodePersistedStorageKey, forwardSQLiteDriverSharedLogicalScheduling, persistedCollectionOptions, validatePersistedCollectionCoordinator } from "./persisted.js";
2
2
  import { DuplicateRemoteSubsetOwnerError, IndeterminateCommitError, InvalidPersistedCollectionConfigError, InvalidPersistedCollectionCoordinatorError, InvalidPersistedStorageKeyEncodingError, InvalidPersistedStorageKeyError, InvalidPersistenceAdapterError, InvalidSyncConfigError, PersistedCollectionCoreError, PersistedCollectionDurabilityError, PersistenceUnavailableError, RetryableRemoteSubsetAcquisitionError, SQLiteBigIntOutOfRangeError, toPersistedCollectionDurabilityError } from "./errors.js";
3
3
  import { DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS, DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS, SQLiteCorePersistenceAdapter, createSQLiteCorePersistenceAdapter } from "./sqlite-core-adapter.js";
4
- import { PERSISTED_TYPE_TAG, PERSISTED_VALUE_TAG, SQLITE_BIGINT_MAX, SQLITE_BIGINT_MIN, assertSQLiteBigIntInRange, serializeSQLiteBigInt } from "./sqlite-value.js";
5
- import { RemoteSubsetWireValueError, toProcessLocalLoadSubsetOptions, toTransportedLoadSubsetOptions } from "./remote-subset-wire.js";
4
+ import { PERSISTED_TYPE_TAG, PERSISTED_VALUE_TAG, SQLITE_BIGINT_MAX, SQLITE_BIGINT_MIN, assertSQLiteBigIntInRange, reviveSQLiteTemporal, serializeSQLiteBigInt, serializeSQLiteTemporal, sqliteTemporalIdentity, sqliteTemporalKind } from "./sqlite-value.js";
5
+ import { RemoteSubsetWireValueError, toProcessLocalLoadSubsetOptions, toTransportedLoadSubsetOptions, validateRemoteSubsetOptions } from "./remote-subset-wire.js";
6
6
  import { safeRandomUUID } from "@tanstack/db";
7
7
  export {
8
8
  DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
@@ -35,11 +35,16 @@ export {
35
35
  encodePersistedStorageKey,
36
36
  forwardSQLiteDriverSharedLogicalScheduling,
37
37
  persistedCollectionOptions,
38
+ reviveSQLiteTemporal,
38
39
  safeRandomUUID,
39
40
  serializeSQLiteBigInt,
41
+ serializeSQLiteTemporal,
42
+ sqliteTemporalIdentity,
43
+ sqliteTemporalKind,
40
44
  toPersistedCollectionDurabilityError,
41
45
  toProcessLocalLoadSubsetOptions,
42
46
  toTransportedLoadSubsetOptions,
43
- validatePersistedCollectionCoordinator
47
+ validatePersistedCollectionCoordinator,
48
+ validateRemoteSubsetOptions
44
49
  };
45
50
  //# sourceMappingURL=index.js.map
@@ -358,6 +358,12 @@ export interface PersistedCollectionCoordinator {
358
358
  */
359
359
  requestEnsurePersistedIndex: (collectionId: string, signature: string, spec: PersistedIndexSpec, scopedAdapter?: HydrationPersistenceAdapter, localEnsureCompleted?: boolean) => Promise<void>;
360
360
  requestApplyLocalMutations?: (collectionId: string, mutations: Array<PersistedMutationEnvelope>) => Promise<ApplyLocalMutationsResponse>;
361
+ /**
362
+ * Applies a committed transaction through the supplied adapter when present.
363
+ * Wrappers must forward this leader-local loan: scheduling it again can wait
364
+ * on the hydration that is awaiting this call. Never serialize or retain the
365
+ * loan after the call; ordinary work uses the registered collection adapter.
366
+ */
361
367
  requestApplyCommittedTx: (collectionId: string, tx: PersistedTx, scopedAdapter?: HydrationPersistenceAdapter) => Promise<ApplyCommittedTxResponse>;
362
368
  /** The scoped adapter is leader-local and is never serialized to a follower. */
363
369
  pullSince?: (collectionId: string, fromRowVersion: number, scopedAdapter?: HydrationPersistenceAdapter) => Promise<PullSinceResponse>;
@@ -433,7 +439,7 @@ export declare class SingleProcessCoordinator implements PersistedCollectionCoor
433
439
  registerRemoteSubsetOwner(collectionId: string, owner: RemoteSubsetOwner): () => void;
434
440
  requestEnsurePersistedIndex(): Promise<void>;
435
441
  setAdapterForCollection(collectionId: string, adapter: PersistenceAdapter): void;
436
- requestApplyCommittedTx(collectionId: string, tx: PersistedTx): Promise<ApplyCommittedTxResponse>;
442
+ requestApplyCommittedTx(collectionId: string, tx: PersistedTx, scopedAdapter?: HydrationPersistenceAdapter): Promise<ApplyCommittedTxResponse>;
437
443
  pullSince(): Promise<PullSinceResponse>;
438
444
  }
439
445
  export declare function validatePersistedCollectionCoordinator(coordinator: PersistedCollectionCoordinator): void;
@@ -1,7 +1,7 @@
1
1
  import { safeRandomUUID, withCollectionConfigFactory, whenSyncAccepted, SyncTransactionAbortedError, getLoadSubsetDemandKey, compileSingleRowExpression, toBooleanPredicate, SYNC_PERSISTENCE_VERSION, SYNC_PERSISTENCE_PROTOCOL, PERSISTED_READINESS, NoPendingSyncTransactionCommitError, NoPendingSyncTransactionWriteError, withAcceptedReceipt } from "@tanstack/db";
2
2
  import { InvalidPersistedCollectionConfigError, DuplicateRemoteSubsetOwnerError, toPersistedCollectionDurabilityError, InvalidPersistedStorageKeyEncodingError, InvalidPersistedStorageKeyError, InvalidSyncConfigError, InvalidPersistedCollectionCoordinatorError, PersistedCollectionDurabilityError, InvalidPersistenceAdapterError } from "./errors.js";
3
- import { serializeSQLiteBigInt } from "./sqlite-value.js";
4
- import { toTransportedLoadSubsetOptions, toProcessLocalLoadSubsetOptions } from "./remote-subset-wire.js";
3
+ import { serializeSQLiteBigInt, serializeSQLiteTemporal } from "./sqlite-value.js";
4
+ import { toTransportedLoadSubsetOptions, toProcessLocalLoadSubsetOptions, validateRemoteSubsetOptions } from "./remote-subset-wire.js";
5
5
  import { reportRemoteSubsetOwnerError, unloadRemoteSubsetOwner } from "./remote-subset-owner.js";
6
6
  const SQLITE_DRIVER_SHARED_LOGICAL_SCHEDULING_KEY = /* @__PURE__ */ Symbol.for(
7
7
  `tanstack-db.sqlite-driver-supports-shared-logical-scheduling`
@@ -176,8 +176,8 @@ class SingleProcessCoordinator {
176
176
  setAdapterForCollection(collectionId, adapter) {
177
177
  this.collectionAdapters.set(collectionId, adapter);
178
178
  }
179
- async requestApplyCommittedTx(collectionId, tx) {
180
- const adapter = this.collectionAdapters.get(collectionId);
179
+ async requestApplyCommittedTx(collectionId, tx, scopedAdapter) {
180
+ const adapter = scopedAdapter ?? this.collectionAdapters.get(collectionId);
181
181
  if (!adapter) {
182
182
  throw new InvalidPersistedCollectionConfigError(
183
183
  `SingleProcessCoordinator has no persistence adapter configured for collection "${collectionId}"`
@@ -333,6 +333,8 @@ function toStableSerializable(value) {
333
333
  case `undefined`:
334
334
  return void 0;
335
335
  }
336
+ const temporal = serializeSQLiteTemporal(value);
337
+ if (temporal) return temporal;
336
338
  if (value instanceof Date) {
337
339
  return value.toISOString();
338
340
  }
@@ -745,7 +747,6 @@ class PersistedCollectionRuntime {
745
747
  await this.hydrateSubsetUnsafe(
746
748
  baseline,
747
749
  {
748
- requestRemoteEnsure: false,
749
750
  lifecycleGeneration,
750
751
  bindKeySetEvidence: true
751
752
  },
@@ -828,6 +829,7 @@ class PersistedCollectionRuntime {
828
829
  const subsetKey = this.getSubsetKey(options);
829
830
  const truncateGeneration = this.sourceTruncateGeneration;
830
831
  const routeRemoteDemandDuringHydration = this.canRouteRemoteDemandThroughCoordinator();
832
+ if (routeRemoteDemandDuringHydration) validateRemoteSubsetOptions(options);
831
833
  this.activeSubsets.set(subsetKey, options);
832
834
  const appliedCursor = this.appliedReceiptSequence;
833
835
  try {
@@ -837,7 +839,6 @@ class PersistedCollectionRuntime {
837
839
  (adapter) => this.hydrateSubsetUnsafe(
838
840
  options,
839
841
  {
840
- requestRemoteEnsure: this.mode === `sync-present` && !routeRemoteDemandDuringHydration,
841
842
  lifecycleGeneration,
842
843
  requestLocalLoadFailure: true,
843
844
  rejectBufferedReplayFailure: true
@@ -853,6 +854,9 @@ class PersistedCollectionRuntime {
853
854
  });
854
855
  if (lifecycleGeneration !== this.lifecycleGeneration) return;
855
856
  await this.waitForAppliedReceiptsAfter(appliedCursor);
857
+ if (!routeRemoteDemandDuringHydration && this.canRouteRemoteDemandThroughCoordinator()) {
858
+ validateRemoteSubsetOptions(options);
859
+ }
856
860
  } catch (error) {
857
861
  if (this.activeSubsets.get(subsetKey) === options) {
858
862
  this.activeSubsets.delete(subsetKey);
@@ -962,7 +966,6 @@ class PersistedCollectionRuntime {
962
966
  (adapter) => this.hydrateSubsetUnsafe(
963
967
  options,
964
968
  {
965
- requestRemoteEnsure: false,
966
969
  lifecycleGeneration,
967
970
  rejectBufferedReplayFailure: true
968
971
  },
@@ -1215,9 +1218,6 @@ class PersistedCollectionRuntime {
1215
1218
  if (config.lifecycleGeneration !== this.lifecycleGeneration) return;
1216
1219
  replayFailure = await this.flushQueuedHydrationTransactionsUnsafe(adapter);
1217
1220
  if (config.lifecycleGeneration !== this.lifecycleGeneration) return;
1218
- if (config.requestRemoteEnsure && !replayFailure) {
1219
- this.queueRemoteSubsetEnsure(options);
1220
- }
1221
1221
  } catch (error) {
1222
1222
  if (config.requestLocalLoadFailure && !rowsLoaded) {
1223
1223
  this.hydratingGeneration = config.lifecycleGeneration;
@@ -1810,6 +1810,7 @@ class PersistedCollectionRuntime {
1810
1810
  }
1811
1811
  const subsetKey = this.getSubsetKey(options);
1812
1812
  if (this.activeSubsets.get(subsetKey) !== options) return;
1813
+ validateRemoteSubsetOptions(options);
1813
1814
  this.pendingRemoteSubsetEnsures.set(subsetKey, options);
1814
1815
  void this.flushPendingRemoteSubsetEnsures();
1815
1816
  }
@@ -2212,8 +2213,8 @@ class PersistedCollectionRuntime {
2212
2213
  await this.requestCoordinatorPersistedIndex(indexMetadata, completedLocally);
2213
2214
  }
2214
2215
  async ensureLocalPersistedIndex(indexMetadata, adapter) {
2215
- const spec = this.buildPersistedIndexSpec(indexMetadata);
2216
2216
  try {
2217
+ const spec = this.buildPersistedIndexSpec(indexMetadata);
2217
2218
  await adapter.ensureIndex(
2218
2219
  this.collectionId,
2219
2220
  indexMetadata.signature,
@@ -2226,8 +2227,8 @@ class PersistedCollectionRuntime {
2226
2227
  }
2227
2228
  }
2228
2229
  async requestCoordinatorPersistedIndex(indexMetadata, completedLocally) {
2229
- const spec = this.buildPersistedIndexSpec(indexMetadata);
2230
2230
  try {
2231
+ const spec = this.buildPersistedIndexSpec(indexMetadata);
2231
2232
  await this.persistence.coordinator.requestEnsurePersistedIndex(
2232
2233
  this.collectionId,
2233
2234
  indexMetadata.signature,
@@ -2835,6 +2836,7 @@ function createWrappedSyncConfig(sourceSyncConfig, runtime, persistedReadiness)
2835
2836
  settleRuntimeTransaction(openTransaction, applied2);
2836
2837
  return visibleAfterDurable(openTransaction, applied2);
2837
2838
  }
2839
+ openTransaction.hydrationSequence = void 0;
2838
2840
  let applied;
2839
2841
  try {
2840
2842
  applied = runtime.applyHydrationBufferedTransaction(transaction);