@signalium/query 1.0.10 → 1.0.12
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/CHANGELOG.md +21 -0
- package/dist/cjs/EntityMap.js +45 -7
- package/dist/cjs/EntityMap.js.map +1 -1
- package/dist/cjs/QueryClient.js +48 -4
- package/dist/cjs/QueryClient.js.map +1 -1
- package/dist/cjs/QueryResult.js +132 -80
- package/dist/cjs/QueryResult.js.map +1 -1
- package/dist/cjs/errors.js +17 -0
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/proxy.js +54 -14
- package/dist/cjs/proxy.js.map +1 -1
- package/dist/cjs/query.js +2 -1
- package/dist/cjs/query.js.map +1 -1
- package/dist/cjs/stores/async.js +56 -6
- package/dist/cjs/stores/async.js.map +1 -1
- package/dist/cjs/stores/shared.js +5 -1
- package/dist/cjs/stores/shared.js.map +1 -1
- package/dist/cjs/stores/sync.js +49 -13
- package/dist/cjs/stores/sync.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/typeDefs.js +141 -8
- package/dist/cjs/typeDefs.js.map +1 -1
- package/dist/esm/EntityMap.d.ts +9 -3
- package/dist/esm/EntityMap.d.ts.map +1 -1
- package/dist/esm/EntityMap.js +46 -8
- package/dist/esm/EntityMap.js.map +1 -1
- package/dist/esm/QueryClient.d.ts +31 -2
- package/dist/esm/QueryClient.d.ts.map +1 -1
- package/dist/esm/QueryClient.js +47 -4
- package/dist/esm/QueryClient.js.map +1 -1
- package/dist/esm/QueryResult.d.ts +9 -3
- package/dist/esm/QueryResult.d.ts.map +1 -1
- package/dist/esm/QueryResult.js +132 -80
- package/dist/esm/QueryResult.js.map +1 -1
- package/dist/esm/errors.d.ts.map +1 -1
- package/dist/esm/errors.js +18 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/proxy.d.ts +1 -1
- package/dist/esm/proxy.d.ts.map +1 -1
- package/dist/esm/proxy.js +54 -14
- package/dist/esm/proxy.js.map +1 -1
- package/dist/esm/query.d.ts +2 -0
- package/dist/esm/query.d.ts.map +1 -1
- package/dist/esm/query.js +2 -1
- package/dist/esm/query.js.map +1 -1
- package/dist/esm/stores/async.d.ts +8 -3
- package/dist/esm/stores/async.d.ts.map +1 -1
- package/dist/esm/stores/async.js +57 -7
- package/dist/esm/stores/async.js.map +1 -1
- package/dist/esm/stores/shared.d.ts +2 -0
- package/dist/esm/stores/shared.d.ts.map +1 -1
- package/dist/esm/stores/shared.js +2 -0
- package/dist/esm/stores/shared.js.map +1 -1
- package/dist/esm/stores/sync.d.ts +4 -3
- package/dist/esm/stores/sync.d.ts.map +1 -1
- package/dist/esm/stores/sync.js +43 -8
- package/dist/esm/stores/sync.js.map +1 -1
- package/dist/esm/type-utils.d.ts +4 -0
- package/dist/esm/type-utils.d.ts.map +1 -1
- package/dist/esm/typeDefs.d.ts +53 -5
- package/dist/esm/typeDefs.d.ts.map +1 -1
- package/dist/esm/typeDefs.js +139 -8
- package/dist/esm/typeDefs.js.map +1 -1
- package/dist/esm/types.d.ts +38 -12
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/cjs/QueryStore.js +0 -583
- package/dist/cjs/QueryStore.js.map +0 -1
- package/dist/esm/QueryStore.d.ts +0 -147
- package/dist/esm/QueryStore.d.ts.map +0 -1
- package/dist/esm/QueryStore.js +0 -570
- package/dist/esm/QueryStore.js.map +0 -1
|
@@ -17,9 +17,15 @@ import { NetworkManager } from './NetworkManager.js';
|
|
|
17
17
|
import { QueryResultImpl } from './QueryResult.js';
|
|
18
18
|
import { RefetchManager } from './RefetchManager.js';
|
|
19
19
|
import { MemoryEvictionManager } from './MemoryEvictionManager.js';
|
|
20
|
-
import {
|
|
20
|
+
import { type Signal } from 'signalium';
|
|
21
21
|
export interface QueryContext {
|
|
22
22
|
fetch: typeof fetch;
|
|
23
|
+
log?: {
|
|
24
|
+
error?: (message: string, error?: unknown) => void;
|
|
25
|
+
warn?: (message: string, error?: unknown) => void;
|
|
26
|
+
info?: (message: string) => void;
|
|
27
|
+
debug?: (message: string) => void;
|
|
28
|
+
};
|
|
23
29
|
evictionMultiplier?: number;
|
|
24
30
|
refetchMultiplier?: number;
|
|
25
31
|
}
|
|
@@ -39,7 +45,7 @@ export interface StreamCacheOptions {
|
|
|
39
45
|
export interface QueryPaginationOptions<Result> {
|
|
40
46
|
getNextPageParams?(lastPage: Result, params?: QueryParams | undefined): QueryParams | undefined;
|
|
41
47
|
}
|
|
42
|
-
export type QueryParams = Record<string, string | number | boolean | undefined | null
|
|
48
|
+
export type QueryParams = Record<string, string | number | boolean | undefined | null | Signal<string | number | boolean | undefined | null>>;
|
|
43
49
|
export declare const enum QueryType {
|
|
44
50
|
Query = "query",
|
|
45
51
|
InfiniteQuery = "infiniteQuery",
|
|
@@ -52,6 +58,7 @@ export interface QueryDefinition<Params extends QueryParams | undefined, Result,
|
|
|
52
58
|
shape: TypeDef;
|
|
53
59
|
shapeKey: number;
|
|
54
60
|
fetchFn: (context: QueryContext, params: Params, prevResult?: Result) => Promise<Result>;
|
|
61
|
+
debounce?: number;
|
|
55
62
|
cache?: QueryCacheOptions;
|
|
56
63
|
stream?: {
|
|
57
64
|
shape: TypeDef;
|
|
@@ -70,6 +77,7 @@ export interface InfiniteQueryDefinition<Params extends QueryParams | undefined,
|
|
|
70
77
|
shapeKey: number;
|
|
71
78
|
fetchFn: (context: QueryContext, params: Params, prevResult?: Result) => Promise<Result>;
|
|
72
79
|
pagination: QueryPaginationOptions<Result>;
|
|
80
|
+
debounce?: number;
|
|
73
81
|
cache?: QueryCacheOptions;
|
|
74
82
|
stream?: {
|
|
75
83
|
shape: TypeDef;
|
|
@@ -96,6 +104,10 @@ export interface CachedQuery {
|
|
|
96
104
|
updatedAt: number;
|
|
97
105
|
extra?: CachedQueryExtra;
|
|
98
106
|
}
|
|
107
|
+
export interface CachedQueryExtra {
|
|
108
|
+
streamOrphanRefs?: number[];
|
|
109
|
+
optimisticInsertRefs?: number[];
|
|
110
|
+
}
|
|
99
111
|
export interface QueryStore {
|
|
100
112
|
/**
|
|
101
113
|
* Asynchronously retrieves a document by key.
|
|
@@ -117,8 +129,24 @@ export interface QueryStore {
|
|
|
117
129
|
* Handles eviction internally when the cache is full.
|
|
118
130
|
*/
|
|
119
131
|
activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void;
|
|
132
|
+
deleteQuery(queryKey: number): void;
|
|
120
133
|
}
|
|
121
134
|
export type MaybePromise<T> = T | Promise<T>;
|
|
135
|
+
/**
|
|
136
|
+
* Extracts actual values from params that may contain Signals.
|
|
137
|
+
*/
|
|
138
|
+
export declare function extractParamsForKey(params: QueryParams | undefined): Record<string, string | number | boolean | undefined | null> | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Computes the query key for instance lookup. This is used for two different keys:
|
|
141
|
+
*
|
|
142
|
+
* - Query instance key
|
|
143
|
+
* - Query storage key
|
|
144
|
+
*
|
|
145
|
+
* Instance keys are created by passing in the query definition and parameters WITHOUT
|
|
146
|
+
* extracting the Signal values, whereas storage keys are created by extracting the Signal values.
|
|
147
|
+
* This way, we can reuse the same instance for given Signals, but different underlying values
|
|
148
|
+
* will be stored and put into the LRU cache separately.
|
|
149
|
+
*/
|
|
122
150
|
export declare const queryKeyFor: (queryDef: AnyQueryDefinition<any, any, any>, params: unknown) => number;
|
|
123
151
|
export declare class QueryClient {
|
|
124
152
|
private store;
|
|
@@ -134,6 +162,7 @@ export declare class QueryClient {
|
|
|
134
162
|
saveQueryData(queryDef: AnyQueryDefinition<QueryParams | undefined, unknown, unknown>, queryKey: number, data: unknown, updatedAt: number, entityRefs?: Set<number>, extra?: CachedQueryExtra): void;
|
|
135
163
|
activateQuery(queryInstance: QueryResultImpl<unknown>): void;
|
|
136
164
|
loadCachedQuery(queryDef: AnyQueryDefinition<QueryParams | undefined, unknown, unknown>, queryKey: number): MaybePromise<CachedQuery | undefined>;
|
|
165
|
+
deleteCachedQuery(queryKey: number): void;
|
|
137
166
|
/**
|
|
138
167
|
* Loads a query from the document store and returns a QueryResult
|
|
139
168
|
* that triggers fetches and prepopulates with cached data
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryClient.d.ts","sourceRoot":"","sources":["../../src/QueryClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAY,MAAM,YAAY,CAAC;AAClH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"QueryClient.d.ts","sourceRoot":"","sources":["../../src/QueryClient.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/QueryClient.js
CHANGED
|
@@ -17,19 +17,54 @@ import { NetworkManager } from './NetworkManager.js';
|
|
|
17
17
|
import { QueryResultImpl } from './QueryResult.js';
|
|
18
18
|
import { RefetchManager } from './RefetchManager.js';
|
|
19
19
|
import { MemoryEvictionManager } from './MemoryEvictionManager.js';
|
|
20
|
+
/**
|
|
21
|
+
* Checks if a value is a Signal instance
|
|
22
|
+
*/
|
|
23
|
+
function isSignal(value) {
|
|
24
|
+
return typeof value === 'object' && value !== null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extracts actual values from params that may contain Signals.
|
|
28
|
+
*/
|
|
29
|
+
export function extractParamsForKey(params) {
|
|
30
|
+
if (params === undefined) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const extracted = {};
|
|
34
|
+
for (const [key, value] of Object.entries(params)) {
|
|
35
|
+
if (isSignal(value)) {
|
|
36
|
+
extracted[key] = value.value;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
extracted[key] = value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return extracted;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Computes the query key for instance lookup. This is used for two different keys:
|
|
46
|
+
*
|
|
47
|
+
* - Query instance key
|
|
48
|
+
* - Query storage key
|
|
49
|
+
*
|
|
50
|
+
* Instance keys are created by passing in the query definition and parameters WITHOUT
|
|
51
|
+
* extracting the Signal values, whereas storage keys are created by extracting the Signal values.
|
|
52
|
+
* This way, we can reuse the same instance for given Signals, but different underlying values
|
|
53
|
+
* will be stored and put into the LRU cache separately.
|
|
54
|
+
*/
|
|
20
55
|
export const queryKeyFor = (queryDef, params) => {
|
|
21
56
|
return hashValue([queryDef.id, queryDef.shapeKey, params]);
|
|
22
57
|
};
|
|
23
58
|
export class QueryClient {
|
|
24
59
|
store;
|
|
25
60
|
context;
|
|
26
|
-
entityMap
|
|
61
|
+
entityMap;
|
|
27
62
|
queryInstances = new Map();
|
|
28
63
|
memoryEvictionManager;
|
|
29
64
|
refetchManager;
|
|
30
65
|
networkManager;
|
|
31
66
|
isServer;
|
|
32
|
-
constructor(store, context = { fetch }, networkManager, memoryEvictionManager, refetchManager) {
|
|
67
|
+
constructor(store, context = { fetch, log: console }, networkManager, memoryEvictionManager, refetchManager) {
|
|
33
68
|
this.store = store;
|
|
34
69
|
this.context = context;
|
|
35
70
|
this.memoryEvictionManager =
|
|
@@ -37,6 +72,7 @@ export class QueryClient {
|
|
|
37
72
|
this.refetchManager = refetchManager ?? new RefetchManager(this.context.refetchMultiplier);
|
|
38
73
|
this.networkManager = networkManager ?? new NetworkManager();
|
|
39
74
|
this.isServer = typeof window === 'undefined';
|
|
75
|
+
this.entityMap = new EntityStore(this);
|
|
40
76
|
}
|
|
41
77
|
getContext() {
|
|
42
78
|
return this.context;
|
|
@@ -48,17 +84,22 @@ export class QueryClient {
|
|
|
48
84
|
this.store.saveQuery(queryDef, queryKey, data, updatedAt, clonedRefs, extra);
|
|
49
85
|
}
|
|
50
86
|
activateQuery(queryInstance) {
|
|
51
|
-
const { def, queryKey } = queryInstance;
|
|
52
|
-
|
|
87
|
+
const { def, queryKey, storageKey } = queryInstance;
|
|
88
|
+
// Use storageKey for cache operations (store.activateQuery)
|
|
89
|
+
this.store.activateQuery(def, storageKey);
|
|
53
90
|
// Only add to refetch manager if it's not a stream
|
|
54
91
|
if (def.type !== "stream" /* QueryType.Stream */ && def.cache?.refetchInterval) {
|
|
55
92
|
this.refetchManager.addQuery(queryInstance);
|
|
56
93
|
}
|
|
94
|
+
// Use queryKey for instance eviction (memoryEvictionManager)
|
|
57
95
|
this.memoryEvictionManager.cancelEviction(queryKey);
|
|
58
96
|
}
|
|
59
97
|
loadCachedQuery(queryDef, queryKey) {
|
|
60
98
|
return this.store.loadQuery(queryDef, queryKey, this.entityMap);
|
|
61
99
|
}
|
|
100
|
+
deleteCachedQuery(queryKey) {
|
|
101
|
+
this.store.deleteQuery(queryKey);
|
|
102
|
+
}
|
|
62
103
|
/**
|
|
63
104
|
* Loads a query from the document store and returns a QueryResult
|
|
64
105
|
* that triggers fetches and prepopulates with cached data
|
|
@@ -78,7 +119,9 @@ export class QueryClient {
|
|
|
78
119
|
return this.entityMap.hydratePreloadedEntity(key, shape);
|
|
79
120
|
}
|
|
80
121
|
saveEntity(key, obj, shape, entityRefs) {
|
|
122
|
+
// console.log('saveEntity', key, JSON.stringify(obj, null, 2), shape, entityRefs, new Error().stack);
|
|
81
123
|
const record = this.entityMap.setEntity(key, obj, shape, entityRefs);
|
|
124
|
+
// console.log('saveEntity record', JSON.stringify(obj, null, 2), new Error().stack);
|
|
82
125
|
this.store.saveEntity(key, obj, entityRefs);
|
|
83
126
|
return record;
|
|
84
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryClient.js","sourceRoot":"","sources":["../../src/QueryClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"QueryClient.js","sourceRoot":"","sources":["../../src/QueryClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { type AnyQueryDefinition, type QueryClient, type QueryParams } from './Q
|
|
|
8
8
|
export declare class QueryResultImpl<T> implements BaseQueryResult<T, unknown, unknown> {
|
|
9
9
|
def: AnyQueryDefinition<any, any, any>;
|
|
10
10
|
queryKey: number;
|
|
11
|
+
storageKey: number;
|
|
11
12
|
private queryClient;
|
|
12
13
|
private initialized;
|
|
13
14
|
private isRefetchingSignal;
|
|
@@ -18,12 +19,12 @@ export declare class QueryResultImpl<T> implements BaseQueryResult<T, unknown, u
|
|
|
18
19
|
private allNestedRefIdsSignal;
|
|
19
20
|
private refetchPromise;
|
|
20
21
|
private fetchMorePromise;
|
|
21
|
-
private attemptCount;
|
|
22
22
|
private unsubscribe?;
|
|
23
|
-
private streamUnsubscribe?;
|
|
24
23
|
private relay;
|
|
25
24
|
private _relayState;
|
|
26
|
-
private
|
|
25
|
+
private wasPaused;
|
|
26
|
+
private currentParams;
|
|
27
|
+
private debounceTimer;
|
|
27
28
|
private get relayState();
|
|
28
29
|
private _extra;
|
|
29
30
|
private get extraData();
|
|
@@ -59,6 +60,11 @@ export declare class QueryResultImpl<T> implements BaseQueryResult<T, unknown, u
|
|
|
59
60
|
* Fetches fresh data, updates the cache, and updates updatedAt timestamp
|
|
60
61
|
*/
|
|
61
62
|
private runQuery;
|
|
63
|
+
/**
|
|
64
|
+
* Triggers a debounced refetch. If debounce is configured, delays the fetch.
|
|
65
|
+
* Otherwise, calls refetch immediately.
|
|
66
|
+
*/
|
|
67
|
+
private debouncedRefetch;
|
|
62
68
|
refetch: () => Promise<T>;
|
|
63
69
|
fetchNextPage: () => Promise<T>;
|
|
64
70
|
get isRefetching(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryResult.d.ts","sourceRoot":"","sources":["../../src/QueryResult.ts"],"names":[],"mappings":"AAYA,OAAO,EAAa,eAAe,EAA+B,UAAU,EAAE,MAAM,YAAY,CAAC;AAIjG,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"QueryResult.d.ts","sourceRoot":"","sources":["../../src/QueryResult.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/QueryResult.js
CHANGED
|
@@ -4,6 +4,7 @@ import { NetworkMode } from './types.js';
|
|
|
4
4
|
import { getProxyId, parseValue } from './proxy.js';
|
|
5
5
|
import { parseEntities, parseObjectEntities } from './parseEntities.js';
|
|
6
6
|
import { ValidatorDef } from './typeDefs.js';
|
|
7
|
+
import { extractParamsForKey, queryKeyFor, } from './QueryClient.js';
|
|
7
8
|
// ======================================================
|
|
8
9
|
// QueryResultExtra - Manages stream orphans and optimistic inserts
|
|
9
10
|
// ======================================================
|
|
@@ -254,7 +255,8 @@ class QueryResultExtra {
|
|
|
254
255
|
*/
|
|
255
256
|
export class QueryResultImpl {
|
|
256
257
|
def;
|
|
257
|
-
queryKey;
|
|
258
|
+
queryKey; // Instance key (includes Signal identity)
|
|
259
|
+
storageKey = -1; // Storage key (extracted values only)
|
|
258
260
|
queryClient;
|
|
259
261
|
initialized = false;
|
|
260
262
|
isRefetchingSignal = signal(false);
|
|
@@ -265,12 +267,12 @@ export class QueryResultImpl {
|
|
|
265
267
|
allNestedRefIdsSignal = undefined;
|
|
266
268
|
refetchPromise = undefined;
|
|
267
269
|
fetchMorePromise = undefined;
|
|
268
|
-
attemptCount = 0;
|
|
269
270
|
unsubscribe = undefined;
|
|
270
|
-
streamUnsubscribe = undefined;
|
|
271
271
|
relay;
|
|
272
272
|
_relayState = undefined;
|
|
273
|
-
|
|
273
|
+
wasPaused = false;
|
|
274
|
+
currentParams = undefined;
|
|
275
|
+
debounceTimer = undefined;
|
|
274
276
|
get relayState() {
|
|
275
277
|
const relayState = this._relayState;
|
|
276
278
|
if (!relayState) {
|
|
@@ -303,7 +305,7 @@ export class QueryResultImpl {
|
|
|
303
305
|
else {
|
|
304
306
|
// Clone current params
|
|
305
307
|
let hasDefinedParams = false;
|
|
306
|
-
const clonedParams = { ...this.
|
|
308
|
+
const clonedParams = { ...this.currentParams };
|
|
307
309
|
// iterate over the next page params and copy any defined values to the
|
|
308
310
|
for (const [key, value] of Object.entries(nextParams)) {
|
|
309
311
|
if (value !== undefined && value !== null) {
|
|
@@ -320,91 +322,96 @@ export class QueryResultImpl {
|
|
|
320
322
|
setReactivePromise(this);
|
|
321
323
|
this.def = def;
|
|
322
324
|
this.queryClient = queryClient;
|
|
323
|
-
this.queryKey = queryKey;
|
|
325
|
+
this.queryKey = queryKey; // Instance key (Signal identity)
|
|
324
326
|
this.params = params;
|
|
325
327
|
// Create the relay and handle activation/deactivation
|
|
326
328
|
this.relay = relay(state => {
|
|
327
329
|
this._relayState = state;
|
|
330
|
+
// Extract params (reading Signal values establishes tracking)
|
|
331
|
+
this.currentParams = extractParamsForKey(this.params);
|
|
332
|
+
this.storageKey = queryKeyFor(this.def, this.currentParams);
|
|
328
333
|
// Load from cache first, then fetch fresh data
|
|
329
334
|
this.queryClient.activateQuery(this);
|
|
330
|
-
// Track network status for reconnect handling
|
|
331
|
-
const networkManager = this.queryClient.networkManager;
|
|
332
|
-
const isOnline = networkManager.getOnlineSignal().value;
|
|
333
335
|
// Store initial offline state
|
|
334
|
-
|
|
336
|
+
const isPaused = this.isPaused;
|
|
337
|
+
this.wasPaused = isPaused;
|
|
335
338
|
if (this.initialized) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
this.def.stream
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if (this.def.type !== "stream" /* QueryType.Stream */) {
|
|
342
|
-
// Check if we just came back online
|
|
343
|
-
if (!this.wasOffline && isOnline) {
|
|
344
|
-
// We're back online - check if we should refresh
|
|
345
|
-
const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;
|
|
346
|
-
if (refreshStaleOnReconnect && this.isStale) {
|
|
347
|
-
this.refetch();
|
|
348
|
-
}
|
|
349
|
-
// Reset attempt count on reconnect
|
|
350
|
-
this.attemptCount = 0;
|
|
339
|
+
if (!isPaused) {
|
|
340
|
+
// For any query with streams, resubscribe on reactivation
|
|
341
|
+
if (this.def.type === "stream" /* QueryType.Stream */ ||
|
|
342
|
+
this.def.stream) {
|
|
343
|
+
this.setupSubscription();
|
|
351
344
|
}
|
|
352
|
-
|
|
345
|
+
if (this.def.type !== "stream" /* QueryType.Stream */ && this.isStale) {
|
|
353
346
|
this.refetch();
|
|
354
347
|
}
|
|
355
348
|
}
|
|
356
|
-
// Update wasOffline for next check
|
|
357
|
-
this.wasOffline = !isOnline;
|
|
358
349
|
}
|
|
359
350
|
else {
|
|
360
351
|
this.initialize();
|
|
361
352
|
}
|
|
353
|
+
const deactivate = () => {
|
|
354
|
+
// Clear debounce timer if active
|
|
355
|
+
clearTimeout(this.debounceTimer);
|
|
356
|
+
this.debounceTimer = undefined;
|
|
357
|
+
// Last subscriber left, deactivate refetch and schedule memory eviction
|
|
358
|
+
// Unsubscribe from any active streams
|
|
359
|
+
this.unsubscribe?.();
|
|
360
|
+
this.unsubscribe = undefined;
|
|
361
|
+
// Remove from refetch manager if configured
|
|
362
|
+
if (this.def.type !== "stream" /* QueryType.Stream */ && this.def.cache?.refetchInterval) {
|
|
363
|
+
this.queryClient.refetchManager.removeQuery(this);
|
|
364
|
+
}
|
|
365
|
+
// Schedule removal from memory using the global eviction manager
|
|
366
|
+
// This allows quick reactivation from memory if needed again soon
|
|
367
|
+
// Disk cache (if configured) will still be available after eviction
|
|
368
|
+
// Use queryKey for instance eviction, storageKey for cache eviction
|
|
369
|
+
this.queryClient.memoryEvictionManager.scheduleEviction(this.queryKey);
|
|
370
|
+
};
|
|
362
371
|
// Return deactivation callback
|
|
363
372
|
return {
|
|
364
373
|
update: () => {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
// For StreamQuery, we're done - it doesn't react to network status
|
|
371
|
-
if (this.def.type === "stream" /* QueryType.Stream */) {
|
|
374
|
+
const { wasPaused, isPaused } = this;
|
|
375
|
+
this.wasPaused = isPaused;
|
|
376
|
+
if (isPaused) {
|
|
377
|
+
deactivate();
|
|
378
|
+
// TODO: Add abort signal
|
|
372
379
|
return;
|
|
373
380
|
}
|
|
374
|
-
//
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
//
|
|
383
|
-
this.
|
|
384
|
-
|
|
385
|
-
// Update wasOffline for next check
|
|
386
|
-
this.wasOffline = !currentlyOnline;
|
|
387
|
-
},
|
|
388
|
-
deactivate: () => {
|
|
389
|
-
// Last subscriber left, deactivate refetch and schedule memory eviction
|
|
390
|
-
// Unsubscribe from any active streams
|
|
391
|
-
if (this.unsubscribe) {
|
|
392
|
-
this.unsubscribe();
|
|
393
|
-
this.unsubscribe = undefined;
|
|
381
|
+
// Read Signal values again to establish tracking for any new Signals
|
|
382
|
+
// Extract params (reading Signal values establishes tracking)
|
|
383
|
+
const newExtractedParams = extractParamsForKey(this.params);
|
|
384
|
+
const newStorageKey = queryKeyFor(this.def, newExtractedParams);
|
|
385
|
+
const paramsDidChange = newStorageKey !== this.storageKey;
|
|
386
|
+
// Check if storage key changed (comparing hash values)
|
|
387
|
+
if (paramsDidChange) {
|
|
388
|
+
// Same storage key, just Signal instances changed but values are the same
|
|
389
|
+
// Update params and trigger debounced refetch
|
|
390
|
+
this.params = newExtractedParams;
|
|
391
|
+
this.storageKey = newStorageKey;
|
|
394
392
|
}
|
|
395
|
-
if (
|
|
396
|
-
this.
|
|
397
|
-
this.
|
|
393
|
+
if (wasPaused) {
|
|
394
|
+
this.queryClient.activateQuery(this);
|
|
395
|
+
if (this.def.type !== "stream" /* QueryType.Stream */) {
|
|
396
|
+
const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;
|
|
397
|
+
if (refreshStaleOnReconnect && this.isStale) {
|
|
398
|
+
state.setPromise(this.runQuery(this.currentParams, true));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
this.setupSubscription();
|
|
403
|
+
}
|
|
398
404
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
405
|
+
else if (paramsDidChange) {
|
|
406
|
+
if (this.def.type !== "stream" /* QueryType.Stream */) {
|
|
407
|
+
this.debouncedRefetch();
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
this.setupSubscription();
|
|
411
|
+
}
|
|
402
412
|
}
|
|
403
|
-
// Schedule removal from memory using the global eviction manager
|
|
404
|
-
// This allows quick reactivation from memory if needed again soon
|
|
405
|
-
// Disk cache (if configured) will still be available after eviction
|
|
406
|
-
this.queryClient.memoryEvictionManager.scheduleEviction(this.queryKey);
|
|
407
413
|
},
|
|
414
|
+
deactivate,
|
|
408
415
|
};
|
|
409
416
|
});
|
|
410
417
|
}
|
|
@@ -486,10 +493,11 @@ export class QueryResultImpl {
|
|
|
486
493
|
*/
|
|
487
494
|
async initialize() {
|
|
488
495
|
const state = this.relayState;
|
|
496
|
+
this.initialized = true;
|
|
497
|
+
let cached;
|
|
489
498
|
try {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const cached = await this.queryClient.loadCachedQuery(this.def, this.queryKey);
|
|
499
|
+
// Load from cache first (use storage key for cache operations)
|
|
500
|
+
cached = await this.queryClient.loadCachedQuery(this.def, this.storageKey);
|
|
493
501
|
if (cached !== undefined) {
|
|
494
502
|
// Set the cached timestamp
|
|
495
503
|
this.updatedAt = cached.updatedAt;
|
|
@@ -508,6 +516,17 @@ export class QueryResultImpl {
|
|
|
508
516
|
? parseEntities(cached.value, shape, this.queryClient, new Set())
|
|
509
517
|
: parseValue(cached.value, shape, this.def.id);
|
|
510
518
|
}
|
|
519
|
+
}
|
|
520
|
+
catch (error) {
|
|
521
|
+
this.queryClient.deleteCachedQuery(this.storageKey);
|
|
522
|
+
this.queryClient
|
|
523
|
+
.getContext()
|
|
524
|
+
.log?.warn?.('Failed to initialize query, the query cache may be corrupted or invalid', error);
|
|
525
|
+
}
|
|
526
|
+
if (this.isPaused) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
try {
|
|
511
530
|
// Setup subscriptions (handles both StreamQuery and Query/InfiniteQuery with stream)
|
|
512
531
|
if (this.def.type === "stream" /* QueryType.Stream */ ||
|
|
513
532
|
this.def.stream) {
|
|
@@ -518,13 +537,19 @@ export class QueryResultImpl {
|
|
|
518
537
|
if (cached !== undefined) {
|
|
519
538
|
// Check if data is stale
|
|
520
539
|
if (this.isStale) {
|
|
521
|
-
// Data is stale, trigger background refetch
|
|
522
|
-
this.
|
|
540
|
+
// Data is stale, trigger background refetch (with debounce if configured)
|
|
541
|
+
if (this.def.debounce !== undefined && this.def.debounce > 0) {
|
|
542
|
+
this.debouncedRefetch();
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
this.refetch();
|
|
546
|
+
}
|
|
523
547
|
}
|
|
524
548
|
}
|
|
525
549
|
else {
|
|
526
|
-
// No cached data, fetch fresh
|
|
527
|
-
|
|
550
|
+
// No cached data, fetch fresh immediately (don't debounce initial fetch)
|
|
551
|
+
// Debounce only applies to refetches triggered by parameter changes
|
|
552
|
+
state.setPromise(this.runQuery(this.currentParams, true));
|
|
528
553
|
}
|
|
529
554
|
}
|
|
530
555
|
}
|
|
@@ -554,14 +579,17 @@ export class QueryResultImpl {
|
|
|
554
579
|
shapeDef = stream.shape;
|
|
555
580
|
subscribeFn = stream.subscribeFn;
|
|
556
581
|
}
|
|
557
|
-
|
|
582
|
+
// Extract params (reading Signal values establishes tracking)
|
|
583
|
+
const extractedParams = this.currentParams;
|
|
584
|
+
this.unsubscribe = subscribeFn(this.queryClient.getContext(), extractedParams, update => {
|
|
558
585
|
const parsedData = parseObjectEntities(update, shapeDef, this.queryClient);
|
|
559
586
|
// Update the relay state
|
|
560
587
|
if (this.def.type === "stream" /* QueryType.Stream */) {
|
|
561
588
|
this.relayState.value = parsedData;
|
|
562
589
|
this.updatedAt = Date.now();
|
|
563
590
|
// Cache the data
|
|
564
|
-
|
|
591
|
+
// Use storage key for cache operations
|
|
592
|
+
this.queryClient.saveQueryData(this.def, this.storageKey, parsedData, this.updatedAt);
|
|
565
593
|
}
|
|
566
594
|
else {
|
|
567
595
|
const allRefIds = this.getAllEntityRefs();
|
|
@@ -588,8 +616,6 @@ export class QueryResultImpl {
|
|
|
588
616
|
try {
|
|
589
617
|
const queryDef = this.def;
|
|
590
618
|
const freshData = await queryDef.fetchFn(this.queryClient.getContext(), params);
|
|
591
|
-
// Success! Reset attempt count
|
|
592
|
-
this.attemptCount = 0;
|
|
593
619
|
// Parse and cache the fresh data
|
|
594
620
|
let entityRefs;
|
|
595
621
|
const isInfinite = this.def.type === "infiniteQuery" /* QueryType.InfiniteQuery */;
|
|
@@ -620,14 +646,14 @@ export class QueryResultImpl {
|
|
|
620
646
|
}
|
|
621
647
|
this._nextPageParams = undefined;
|
|
622
648
|
// Cache the data (synchronous, fire-and-forget)
|
|
623
|
-
|
|
649
|
+
// Use storage key for cache operations
|
|
650
|
+
this.queryClient.saveQueryData(this.def, this.storageKey, queryData, updatedAt, entityRefs, this.getExtraForPersistence());
|
|
624
651
|
// Update the timestamp
|
|
625
652
|
this.updatedAt = Date.now();
|
|
626
653
|
return queryData;
|
|
627
654
|
}
|
|
628
655
|
catch (error) {
|
|
629
656
|
lastError = error;
|
|
630
|
-
this.attemptCount = attempt + 1;
|
|
631
657
|
// If we've exhausted retries, throw the error
|
|
632
658
|
if (attempt >= retries) {
|
|
633
659
|
throw error;
|
|
@@ -645,6 +671,28 @@ export class QueryResultImpl {
|
|
|
645
671
|
throw lastError;
|
|
646
672
|
}
|
|
647
673
|
// ======================================================
|
|
674
|
+
// Private debounce methods
|
|
675
|
+
// ======================================================
|
|
676
|
+
/**
|
|
677
|
+
* Triggers a debounced refetch. If debounce is configured, delays the fetch.
|
|
678
|
+
* Otherwise, calls refetch immediately.
|
|
679
|
+
*/
|
|
680
|
+
debouncedRefetch() {
|
|
681
|
+
// We know this is a non-stream query because we're calling refetch, which is only available on non-stream queries
|
|
682
|
+
const debounce = this.def.debounce;
|
|
683
|
+
if (debounce === undefined) {
|
|
684
|
+
this.refetch();
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
// Clear existing timer
|
|
688
|
+
clearTimeout(this.debounceTimer);
|
|
689
|
+
// Set new timer
|
|
690
|
+
this.debounceTimer = setTimeout(() => {
|
|
691
|
+
this.debounceTimer = undefined;
|
|
692
|
+
this.refetch();
|
|
693
|
+
}, debounce);
|
|
694
|
+
}
|
|
695
|
+
// ======================================================
|
|
648
696
|
// Public methods
|
|
649
697
|
// ======================================================
|
|
650
698
|
refetch = () => {
|
|
@@ -657,13 +705,16 @@ export class QueryResultImpl {
|
|
|
657
705
|
if (this.refetchPromise) {
|
|
658
706
|
return this.refetchPromise;
|
|
659
707
|
}
|
|
708
|
+
// Clear debounce timer if active (manual refetch should bypass debounce)
|
|
709
|
+
clearTimeout(this.debounceTimer);
|
|
710
|
+
this.debounceTimer = undefined;
|
|
660
711
|
// Clear memoized nextPageParams so it's recalculated after refetch
|
|
661
712
|
this._nextPageParams = undefined;
|
|
662
713
|
// Set the signal before any async operations so it's immediately visible
|
|
663
714
|
// Use untrack to avoid reactive violations when called from reactive context
|
|
664
715
|
this.isRefetchingSignal.value = true;
|
|
665
716
|
this._version.update(v => v + 1);
|
|
666
|
-
const promise = this.runQuery(this.
|
|
717
|
+
const promise = this.runQuery(this.currentParams, true)
|
|
667
718
|
.then(result => {
|
|
668
719
|
this.relayState.value = result;
|
|
669
720
|
// Clear stream orphans and optimistic inserts on refetch
|
|
@@ -747,7 +798,8 @@ export class QueryResultImpl {
|
|
|
747
798
|
return; // Query not initialized yet
|
|
748
799
|
}
|
|
749
800
|
const extra = this._extra?.getForPersistence();
|
|
750
|
-
|
|
801
|
+
// Use storage key for cache operations
|
|
802
|
+
this.queryClient.saveQueryData(this.def, this.storageKey, this.relayState.value, this.updatedAt, this.refIds, extra);
|
|
751
803
|
}
|
|
752
804
|
/**
|
|
753
805
|
* Get extra data for persistence (converts Sets to arrays of entity ref IDs)
|