@tanstack/db-sqlite-persistence-core 0.2.19 → 0.2.21
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/persisted.cjs +31 -34
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/esm/persisted.js +31 -34
- package/dist/esm/persisted.js.map +1 -1
- package/package.json +2 -2
- package/src/persisted.ts +48 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/db-sqlite-persistence-core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21",
|
|
4
4
|
"description": "SQLite persisted collection core for TanStack DB",
|
|
5
5
|
"author": "TanStack Team",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@standard-schema/spec": "^1.1.0",
|
|
43
|
-
"@tanstack/db": "0.
|
|
43
|
+
"@tanstack/db": "0.9.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"typescript": ">=4.7"
|
package/src/persisted.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
CollectionIndexMetadata,
|
|
22
22
|
DeleteMutationFnParams,
|
|
23
23
|
InsertMutationFnParams,
|
|
24
|
+
LoadSubsetFn,
|
|
24
25
|
LoadSubsetOptions,
|
|
25
26
|
PendingMutation,
|
|
26
27
|
SyncAppliedReceipt,
|
|
@@ -1015,7 +1016,7 @@ class PersistedCollectionRuntime<
|
|
|
1015
1016
|
|
|
1016
1017
|
async loadSubset(
|
|
1017
1018
|
options: LoadSubsetOptions,
|
|
1018
|
-
upstreamLoadSubset?:
|
|
1019
|
+
upstreamLoadSubset?: LoadSubsetFn,
|
|
1019
1020
|
): Promise<void> {
|
|
1020
1021
|
this.activeSubsets.set(this.getSubsetKey(options), options)
|
|
1021
1022
|
|
|
@@ -1029,17 +1030,18 @@ class PersistedCollectionRuntime<
|
|
|
1029
1030
|
|
|
1030
1031
|
if (upstreamLoadSubset) {
|
|
1031
1032
|
try {
|
|
1032
|
-
|
|
1033
|
-
if (maybePromise instanceof Promise) {
|
|
1034
|
-
await maybePromise.catch((error) => {
|
|
1035
|
-
console.warn(
|
|
1036
|
-
`Failed to load remote subset in persisted wrapper:`,
|
|
1037
|
-
error,
|
|
1038
|
-
)
|
|
1039
|
-
this.queueRemoteSubsetEnsure(options)
|
|
1040
|
-
})
|
|
1041
|
-
}
|
|
1033
|
+
await upstreamLoadSubset(options)
|
|
1042
1034
|
} catch (error) {
|
|
1035
|
+
if (
|
|
1036
|
+
options.signal?.aborted ||
|
|
1037
|
+
(typeof error === `object` &&
|
|
1038
|
+
error !== null &&
|
|
1039
|
+
`name` in error &&
|
|
1040
|
+
error.name === `AbortError`)
|
|
1041
|
+
) {
|
|
1042
|
+
this.pendingRemoteSubsetEnsures.delete(this.getSubsetKey(options))
|
|
1043
|
+
throw error
|
|
1044
|
+
}
|
|
1043
1045
|
console.warn(`Failed to trigger remote subset load:`, error)
|
|
1044
1046
|
this.queueRemoteSubsetEnsure(options)
|
|
1045
1047
|
}
|
|
@@ -1051,6 +1053,7 @@ class PersistedCollectionRuntime<
|
|
|
1051
1053
|
upstreamUnloadSubset?: (options: LoadSubsetOptions) => void,
|
|
1052
1054
|
): void {
|
|
1053
1055
|
this.activeSubsets.delete(this.getSubsetKey(options))
|
|
1056
|
+
this.pendingRemoteSubsetEnsures.delete(this.getSubsetKey(options))
|
|
1054
1057
|
upstreamUnloadSubset?.(options)
|
|
1055
1058
|
}
|
|
1056
1059
|
|
|
@@ -1824,7 +1827,8 @@ class PersistedCollectionRuntime<
|
|
|
1824
1827
|
private queueRemoteSubsetEnsure(options: LoadSubsetOptions): void {
|
|
1825
1828
|
if (
|
|
1826
1829
|
this.mode !== `sync-present` ||
|
|
1827
|
-
!this.persistence.coordinator.requestEnsureRemoteSubset
|
|
1830
|
+
!this.persistence.coordinator.requestEnsureRemoteSubset ||
|
|
1831
|
+
this.activeSubsets.get(this.getSubsetKey(options)) !== options
|
|
1828
1832
|
) {
|
|
1829
1833
|
return
|
|
1830
1834
|
}
|
|
@@ -2276,24 +2280,7 @@ function createWrappedSyncConfig<
|
|
|
2276
2280
|
const getOpenTransaction = () =>
|
|
2277
2281
|
transactionStack[transactionStack.length - 1]
|
|
2278
2282
|
let fullStartPromise: Promise<void> | null = null
|
|
2279
|
-
const
|
|
2280
|
-
const loadSubscriptionIds = new WeakMap<object, string>()
|
|
2281
|
-
let nextLoadSubscriptionId = 0
|
|
2282
|
-
const getLoadKey = (options: LoadSubsetOptions) => {
|
|
2283
|
-
const subscription = options.subscription as object | undefined
|
|
2284
|
-
if (subscription && typeof subscription === `object`) {
|
|
2285
|
-
const existingId = loadSubscriptionIds.get(subscription)
|
|
2286
|
-
if (existingId) {
|
|
2287
|
-
return `sub:${existingId}`
|
|
2288
|
-
}
|
|
2289
|
-
nextLoadSubscriptionId++
|
|
2290
|
-
const nextId = String(nextLoadSubscriptionId)
|
|
2291
|
-
loadSubscriptionIds.set(subscription, nextId)
|
|
2292
|
-
return `sub:${nextId}`
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
return `opts:${stableSerialize(normalizeSubsetOptionsForKey(options))}`
|
|
2296
|
-
}
|
|
2283
|
+
const acquisitions = new Map<LoadSubsetOptions, { forwarded: boolean }>()
|
|
2297
2284
|
runtime.setSyncControls({
|
|
2298
2285
|
begin: params.begin,
|
|
2299
2286
|
write: params.write as SyncControlFns<T, TKey>[`write`],
|
|
@@ -2590,23 +2577,48 @@ function createWrappedSyncConfig<
|
|
|
2590
2577
|
return {
|
|
2591
2578
|
cleanup: () => {
|
|
2592
2579
|
startupState.cleanedUp = true
|
|
2580
|
+
acquisitions.clear()
|
|
2593
2581
|
sourceResult.cleanup?.()
|
|
2594
2582
|
runtime.cleanup()
|
|
2595
2583
|
runtime.clearSyncControls()
|
|
2596
2584
|
},
|
|
2597
2585
|
loadSubset: async (options: LoadSubsetOptions) => {
|
|
2598
|
-
const
|
|
2599
|
-
|
|
2586
|
+
const acquisition = { forwarded: false }
|
|
2587
|
+
acquisitions.set(options, acquisition)
|
|
2600
2588
|
await fullStartPromise
|
|
2601
2589
|
const resolvedSourceResult = await sourceResultPromise
|
|
2602
|
-
if (
|
|
2590
|
+
if (
|
|
2591
|
+
startupState.cleanedUp ||
|
|
2592
|
+
acquisitions.get(options) !== acquisition
|
|
2593
|
+
) {
|
|
2603
2594
|
return
|
|
2604
2595
|
}
|
|
2605
|
-
|
|
2596
|
+
return runtime.loadSubset(options, (loadOptions) => {
|
|
2597
|
+
// Hydration is another async boundary. A release before this
|
|
2598
|
+
// point owns no upstream lease and must not start one later.
|
|
2599
|
+
if (
|
|
2600
|
+
startupState.cleanedUp ||
|
|
2601
|
+
acquisitions.get(options) !== acquisition
|
|
2602
|
+
) {
|
|
2603
|
+
return true
|
|
2604
|
+
}
|
|
2605
|
+
if (!resolvedSourceResult.loadSubset) return true
|
|
2606
|
+
acquisition.forwarded = true
|
|
2607
|
+
try {
|
|
2608
|
+
return resolvedSourceResult.loadSubset(loadOptions)
|
|
2609
|
+
} catch (error) {
|
|
2610
|
+
acquisition.forwarded = false
|
|
2611
|
+
throw error
|
|
2612
|
+
}
|
|
2613
|
+
})
|
|
2606
2614
|
},
|
|
2607
2615
|
unloadSubset: (options: LoadSubsetOptions) => {
|
|
2608
|
-
|
|
2609
|
-
|
|
2616
|
+
const acquisition = acquisitions.get(options)
|
|
2617
|
+
acquisitions.delete(options)
|
|
2618
|
+
runtime.unloadSubset(
|
|
2619
|
+
options,
|
|
2620
|
+
acquisition?.forwarded ? sourceResult.unloadSubset : undefined,
|
|
2621
|
+
)
|
|
2610
2622
|
},
|
|
2611
2623
|
}
|
|
2612
2624
|
},
|