@tanstack/db-sqlite-persistence-core 0.4.7 → 0.4.9
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 +32 -3
- package/dist/cjs/broadcast-coordinator.cjs +282 -43
- package/dist/cjs/broadcast-coordinator.cjs.map +1 -1
- package/dist/cjs/broadcast-coordinator.d.cts +25 -8
- package/dist/cjs/committed-tx-anchor.cjs +9 -0
- package/dist/cjs/committed-tx-anchor.cjs.map +1 -0
- package/dist/cjs/committed-tx-anchor.d.cts +1 -0
- package/dist/cjs/index.cjs +4 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/persisted.cjs +1599 -313
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/cjs/persisted.d.cts +106 -13
- package/dist/cjs/remote-subset-wire.cjs +11 -0
- package/dist/cjs/remote-subset-wire.cjs.map +1 -1
- package/dist/cjs/remote-subset-wire.d.cts +1 -0
- package/dist/cjs/sqlite-core-adapter.cjs +705 -64
- package/dist/cjs/sqlite-core-adapter.cjs.map +1 -1
- package/dist/cjs/sqlite-core-adapter.d.cts +53 -10
- package/dist/esm/broadcast-coordinator.d.ts +25 -8
- package/dist/esm/broadcast-coordinator.js +283 -44
- package/dist/esm/broadcast-coordinator.js.map +1 -1
- package/dist/esm/committed-tx-anchor.d.ts +1 -0
- package/dist/esm/committed-tx-anchor.js +9 -0
- package/dist/esm/committed-tx-anchor.js.map +1 -0
- package/dist/esm/index.js +6 -2
- package/dist/esm/persisted.d.ts +106 -13
- package/dist/esm/persisted.js +1601 -315
- package/dist/esm/persisted.js.map +1 -1
- package/dist/esm/remote-subset-wire.d.ts +1 -0
- package/dist/esm/remote-subset-wire.js +11 -0
- package/dist/esm/remote-subset-wire.js.map +1 -1
- package/dist/esm/sqlite-core-adapter.d.ts +53 -10
- package/dist/esm/sqlite-core-adapter.js +708 -67
- package/dist/esm/sqlite-core-adapter.js.map +1 -1
- package/package.json +2 -2
- package/src/broadcast-coordinator.ts +415 -62
- package/src/committed-tx-anchor.ts +13 -0
- package/src/persisted.ts +2283 -370
- package/src/remote-subset-wire.ts +12 -0
- package/src/sqlite-core-adapter.ts +891 -68
package/dist/esm/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { SQLITE_DRIVER_SHARED_LOGICAL_SCHEDULING_KEY, SingleProcessCoordinator, createPersistedTableName, decodePersistedStorageKey, encodePersistedStorageKey, forwardSQLiteDriverSharedLogicalScheduling, persistedCollectionOptions, validatePersistedCollectionCoordinator } from "./persisted.js";
|
|
1
|
+
import { SQLITE_DRIVER_SHARED_LOGICAL_SCHEDULING_KEY, SingleProcessCoordinator, createPersistedTableName, decodePersistedStorageKey, eagerStorageTarget, encodePersistedStorageKey, forwardSQLiteDriverSharedLogicalScheduling, managedStorageTarget, persistedCollectionOptions, resolvePersistedStorageTarget, 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
|
-
import { DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS, DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS, SQLiteCorePersistenceAdapter, createSQLiteCorePersistenceAdapter } from "./sqlite-core-adapter.js";
|
|
3
|
+
import { DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS, DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS, DEFAULT_CACHE_GENERATION_CLAIM_TTL_MS, SQLiteCorePersistenceAdapter, createSQLiteCorePersistenceAdapter } from "./sqlite-core-adapter.js";
|
|
4
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
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,
|
|
9
9
|
DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
|
|
10
|
+
DEFAULT_CACHE_GENERATION_CLAIM_TTL_MS,
|
|
10
11
|
DuplicateRemoteSubsetOwnerError,
|
|
11
12
|
IndeterminateCommitError,
|
|
12
13
|
InvalidPersistedCollectionConfigError,
|
|
@@ -32,9 +33,12 @@ export {
|
|
|
32
33
|
createPersistedTableName,
|
|
33
34
|
createSQLiteCorePersistenceAdapter,
|
|
34
35
|
decodePersistedStorageKey,
|
|
36
|
+
eagerStorageTarget,
|
|
35
37
|
encodePersistedStorageKey,
|
|
36
38
|
forwardSQLiteDriverSharedLogicalScheduling,
|
|
39
|
+
managedStorageTarget,
|
|
37
40
|
persistedCollectionOptions,
|
|
41
|
+
resolvePersistedStorageTarget,
|
|
38
42
|
reviveSQLiteTemporal,
|
|
39
43
|
safeRandomUUID,
|
|
40
44
|
serializeSQLiteBigInt,
|
package/dist/esm/persisted.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export type TxCommitted = {
|
|
|
49
49
|
latestRowVersion: number;
|
|
50
50
|
} & ({
|
|
51
51
|
requiresFullReload: true;
|
|
52
|
+
reconciliationReload?: true;
|
|
52
53
|
} | {
|
|
53
54
|
requiresFullReload: false;
|
|
54
55
|
changedRows: Array<{
|
|
@@ -149,6 +150,41 @@ export type ApplyCommittedTxResponse = {
|
|
|
149
150
|
sourceCode?: string | number;
|
|
150
151
|
path?: string | ReadonlyArray<string | number>;
|
|
151
152
|
};
|
|
153
|
+
/** The durable version read before a source transaction enters coordination. */
|
|
154
|
+
export type CommittedTxAnchor = {
|
|
155
|
+
latestRowVersion: number;
|
|
156
|
+
resetEpoch: number;
|
|
157
|
+
};
|
|
158
|
+
export type ReconcileCommittedTxResponse = {
|
|
159
|
+
type: `rpc:reconcileCommittedTx:res`;
|
|
160
|
+
rpcId: string;
|
|
161
|
+
ok: true;
|
|
162
|
+
alreadyApplied: boolean;
|
|
163
|
+
committed: {
|
|
164
|
+
term: number;
|
|
165
|
+
seq: number;
|
|
166
|
+
rowVersion: number;
|
|
167
|
+
};
|
|
168
|
+
} | {
|
|
169
|
+
type: `rpc:reconcileCommittedTx:res`;
|
|
170
|
+
rpcId: string;
|
|
171
|
+
ok: false;
|
|
172
|
+
code: `NOT_LEADER` | `UNDETERMINED` | `PERSISTENCE_ERROR`;
|
|
173
|
+
error: string;
|
|
174
|
+
sourceCode?: string | number;
|
|
175
|
+
path?: string | ReadonlyArray<string | number>;
|
|
176
|
+
};
|
|
177
|
+
export type ReconciledCommittedTx = {
|
|
178
|
+
kind: `already-applied` | `applied-now`;
|
|
179
|
+
committed: {
|
|
180
|
+
term: number;
|
|
181
|
+
seq: number;
|
|
182
|
+
rowVersion: number;
|
|
183
|
+
};
|
|
184
|
+
latestRowVersion: number;
|
|
185
|
+
} | {
|
|
186
|
+
kind: `unknown`;
|
|
187
|
+
};
|
|
152
188
|
export type PullSinceRequest = {
|
|
153
189
|
type: `rpc:pullSince:req`;
|
|
154
190
|
rpcId: string;
|
|
@@ -223,6 +259,27 @@ export type PersistedScannedRow<T extends object = Record<string, unknown>, TKey
|
|
|
223
259
|
};
|
|
224
260
|
export type PersistedRowScanOptions = SyncPersistenceScanOptions;
|
|
225
261
|
export type PersistedKeySetEvidence = SyncPersistenceKeySetEvidence;
|
|
262
|
+
export type PersistedCacheGenerationClaim = {
|
|
263
|
+
storageCollectionId: string;
|
|
264
|
+
claimId: string;
|
|
265
|
+
/** Present when the adapter expires dormant claims. */
|
|
266
|
+
expiresAtMs?: number;
|
|
267
|
+
};
|
|
268
|
+
/** An eager Collection name or a claim-bound persisted cache generation. */
|
|
269
|
+
export type PersistedStorageTarget = {
|
|
270
|
+
kind: `eager`;
|
|
271
|
+
collectionId: string;
|
|
272
|
+
} | {
|
|
273
|
+
kind: `managed`;
|
|
274
|
+
storageCollectionId: string;
|
|
275
|
+
claimId: string;
|
|
276
|
+
};
|
|
277
|
+
export declare function eagerStorageTarget(collectionId: string): PersistedStorageTarget;
|
|
278
|
+
export declare function managedStorageTarget(storageCollectionId: string, claimId: string): PersistedStorageTarget;
|
|
279
|
+
export declare function resolvePersistedStorageTarget(target: PersistedStorageTarget, legacyClaimId?: string): {
|
|
280
|
+
collectionId: string;
|
|
281
|
+
claimId?: string;
|
|
282
|
+
};
|
|
226
283
|
export type PersistencePullSinceResult = {
|
|
227
284
|
latestRowVersion: number;
|
|
228
285
|
requiresFullReload: true;
|
|
@@ -238,6 +295,8 @@ export type PersistedTx<T extends object = Record<string, unknown>, TKey extends
|
|
|
238
295
|
term: number;
|
|
239
296
|
seq: number;
|
|
240
297
|
rowVersion: number;
|
|
298
|
+
/** Claim authorizing this transaction's persisted cache generation. */
|
|
299
|
+
cacheGenerationClaimId?: string;
|
|
241
300
|
truncate?: boolean;
|
|
242
301
|
mutations: Array<{
|
|
243
302
|
type: `insert`;
|
|
@@ -272,16 +331,18 @@ export type PersistedTx<T extends object = Record<string, unknown>, TKey extends
|
|
|
272
331
|
*/
|
|
273
332
|
export declare const SQLITE_DRIVER_SHARED_LOGICAL_SCHEDULING_KEY: unique symbol;
|
|
274
333
|
export interface PersistenceAdapter {
|
|
275
|
-
loadSubset: (
|
|
334
|
+
loadSubset: (target: PersistedStorageTarget, options: LoadSubsetOptions, ctx?: {
|
|
276
335
|
requiredIndexSignatures?: ReadonlyArray<string>;
|
|
336
|
+
cacheGenerationClaimId?: string;
|
|
277
337
|
}) => Promise<Array<{
|
|
278
338
|
key: string | number;
|
|
279
339
|
value: Record<string, unknown>;
|
|
280
340
|
metadata?: unknown;
|
|
281
341
|
}>>;
|
|
282
|
-
loadResumeSnapshot: (
|
|
342
|
+
loadResumeSnapshot: (target: PersistedStorageTarget, ctx?: {
|
|
283
343
|
requiredIndexSignatures?: ReadonlyArray<string>;
|
|
284
344
|
includeRows?: boolean;
|
|
345
|
+
cacheGenerationClaimId?: string;
|
|
285
346
|
}) => Promise<{
|
|
286
347
|
rows: Array<{
|
|
287
348
|
key: string | number;
|
|
@@ -298,15 +359,43 @@ export interface PersistenceAdapter {
|
|
|
298
359
|
latestRowVersion: number;
|
|
299
360
|
resetEpoch: number;
|
|
300
361
|
}>;
|
|
301
|
-
applyCommittedTx: (
|
|
302
|
-
|
|
362
|
+
applyCommittedTx: (target: PersistedStorageTarget, tx: PersistedTx) => Promise<void>;
|
|
363
|
+
claimCacheGeneration?: (collectionId: string) => Promise<PersistedCacheGenerationClaim>;
|
|
364
|
+
rotateCacheGeneration?: (collectionId: string, claimId: string, resetMetadata?: {
|
|
365
|
+
key: string;
|
|
366
|
+
value: unknown;
|
|
367
|
+
}, expectedStorageCollectionId?: string) => Promise<PersistedCacheGenerationClaim>;
|
|
368
|
+
releaseCacheGenerationClaim?: (claimId: string) => Promise<void>;
|
|
369
|
+
renewCacheGenerationClaim?: (storageCollectionId: string, claimId: string) => Promise<number | undefined>;
|
|
370
|
+
getCacheGenerationNow?: () => number;
|
|
371
|
+
/** Atomically certify or apply one source transaction after a lost response. */
|
|
372
|
+
reconcileCommittedTx?: (target: PersistedStorageTarget, tx: PersistedTx, anchor: CommittedTxAnchor) => Promise<ReconciledCommittedTx>;
|
|
373
|
+
loadCollectionMetadata?: (target: PersistedStorageTarget, ctx?: {
|
|
374
|
+
cacheGenerationClaimId?: string;
|
|
375
|
+
}) => Promise<Array<{
|
|
303
376
|
key: string;
|
|
304
377
|
value: unknown;
|
|
305
378
|
}>>;
|
|
306
|
-
scanRows?: (
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
379
|
+
scanRows?: (target: PersistedStorageTarget, options?: PersistedRowScanOptions, ctx?: {
|
|
380
|
+
cacheGenerationClaimId?: string;
|
|
381
|
+
}) => Promise<Array<PersistedScannedRow>>;
|
|
382
|
+
ensureIndex: (target: PersistedStorageTarget, signature: string, spec: PersistedIndexSpec, ctx?: {
|
|
383
|
+
cacheGenerationClaimId?: string;
|
|
384
|
+
}) => Promise<void>;
|
|
385
|
+
markIndexRemoved?: (target: PersistedStorageTarget, signature: string, ctx?: {
|
|
386
|
+
cacheGenerationClaimId?: string;
|
|
387
|
+
}) => Promise<void>;
|
|
388
|
+
getStreamPosition?: (target: PersistedStorageTarget, ctx?: {
|
|
389
|
+
cacheGenerationClaimId?: string;
|
|
390
|
+
}) => Promise<{
|
|
391
|
+
latestTerm: number;
|
|
392
|
+
latestSeq: number;
|
|
393
|
+
latestRowVersion: number;
|
|
394
|
+
}>;
|
|
395
|
+
/** Reserve a new durable election term before announcing Browser leadership. */
|
|
396
|
+
reserveLeadershipTerm?: (target: PersistedStorageTarget, observedTerm: number, ctx?: {
|
|
397
|
+
cacheGenerationClaimId?: string;
|
|
398
|
+
}) => Promise<{
|
|
310
399
|
latestTerm: number;
|
|
311
400
|
latestSeq: number;
|
|
312
401
|
latestRowVersion: number;
|
|
@@ -323,7 +412,9 @@ export interface PersistenceAdapter {
|
|
|
323
412
|
isHydrationScopeScheduled?: () => boolean;
|
|
324
413
|
}
|
|
325
414
|
export type HydrationPersistenceAdapter = PersistenceAdapter & {
|
|
326
|
-
pullSince?: (
|
|
415
|
+
pullSince?: (target: PersistedStorageTarget, fromRowVersion: number, ctx?: {
|
|
416
|
+
cacheGenerationClaimId?: string;
|
|
417
|
+
}) => Promise<PersistencePullSinceResult>;
|
|
327
418
|
};
|
|
328
419
|
export type { RemoteSubsetOwner } from './remote-subset-owner.js';
|
|
329
420
|
export interface SQLiteDriver {
|
|
@@ -343,7 +434,7 @@ export interface SQLiteDriver {
|
|
|
343
434
|
export declare function forwardSQLiteDriverSharedLogicalScheduling<TDriver extends SQLiteDriver>(source: SQLiteDriver, wrapper: TDriver): TDriver;
|
|
344
435
|
export interface PersistedCollectionCoordinator {
|
|
345
436
|
getNodeId: () => string;
|
|
346
|
-
setAdapterForCollection?: (collectionId: string, adapter: PersistenceAdapter) => void;
|
|
437
|
+
setAdapterForCollection?: (collectionId: string, adapter: PersistenceAdapter, cacheGenerationClaimId?: string) => void;
|
|
347
438
|
subscribe: (collectionId: string, onMessage: (message: ProtocolEnvelope<unknown>) => void) => () => void;
|
|
348
439
|
publish: (collectionId: string, message: ProtocolEnvelope<unknown>) => void;
|
|
349
440
|
isLeader: (collectionId: string) => boolean;
|
|
@@ -356,8 +447,8 @@ export interface PersistedCollectionCoordinator {
|
|
|
356
447
|
* and is never serialized to a follower. `localEnsureCompleted` lets the
|
|
357
448
|
* built-in leader avoid repeating successful local work.
|
|
358
449
|
*/
|
|
359
|
-
requestEnsurePersistedIndex: (collectionId: string, signature: string, spec: PersistedIndexSpec, scopedAdapter?: HydrationPersistenceAdapter, localEnsureCompleted?: boolean) => Promise<void>;
|
|
360
|
-
requestApplyLocalMutations?: (collectionId: string, mutations: Array<PersistedMutationEnvelope
|
|
450
|
+
requestEnsurePersistedIndex: (collectionId: string, signature: string, spec: PersistedIndexSpec, scopedAdapter?: HydrationPersistenceAdapter, localEnsureCompleted?: boolean, cacheGenerationClaimId?: string) => Promise<void>;
|
|
451
|
+
requestApplyLocalMutations?: (collectionId: string, mutations: Array<PersistedMutationEnvelope>, cacheGenerationClaimId?: string) => Promise<ApplyLocalMutationsResponse>;
|
|
361
452
|
/**
|
|
362
453
|
* Applies a committed transaction through the supplied adapter when present.
|
|
363
454
|
* Wrappers must forward this leader-local loan: scheduling it again can wait
|
|
@@ -365,8 +456,10 @@ export interface PersistedCollectionCoordinator {
|
|
|
365
456
|
* loan after the call; ordinary work uses the registered collection adapter.
|
|
366
457
|
*/
|
|
367
458
|
requestApplyCommittedTx: (collectionId: string, tx: PersistedTx, scopedAdapter?: HydrationPersistenceAdapter) => Promise<ApplyCommittedTxResponse>;
|
|
459
|
+
/** Available only when the elected adapter can certify the durable outcome. */
|
|
460
|
+
reconcileCommittedTx?: (collectionId: string, tx: PersistedTx, anchor: CommittedTxAnchor, scopedAdapter?: HydrationPersistenceAdapter) => Promise<ReconcileCommittedTxResponse>;
|
|
368
461
|
/** The scoped adapter is leader-local and is never serialized to a follower. */
|
|
369
|
-
pullSince?: (collectionId: string, fromRowVersion: number, scopedAdapter?: HydrationPersistenceAdapter) => Promise<PullSinceResponse>;
|
|
462
|
+
pullSince?: (collectionId: string, fromRowVersion: number, scopedAdapter?: HydrationPersistenceAdapter, cacheGenerationClaimId?: string) => Promise<PullSinceResponse>;
|
|
370
463
|
}
|
|
371
464
|
export interface PersistedCollectionPersistence {
|
|
372
465
|
adapter: PersistenceAdapter;
|