@signalium/query 1.0.10 → 1.0.11

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/EntityMap.js +45 -7
  3. package/dist/cjs/EntityMap.js.map +1 -1
  4. package/dist/cjs/QueryClient.js +44 -3
  5. package/dist/cjs/QueryClient.js.map +1 -1
  6. package/dist/cjs/QueryResult.js +122 -79
  7. package/dist/cjs/QueryResult.js.map +1 -1
  8. package/dist/cjs/QueryStore.js +0 -573
  9. package/dist/cjs/QueryStore.js.map +1 -1
  10. package/dist/cjs/errors.js +17 -0
  11. package/dist/cjs/errors.js.map +1 -1
  12. package/dist/cjs/proxy.js +54 -14
  13. package/dist/cjs/proxy.js.map +1 -1
  14. package/dist/cjs/query.js +2 -1
  15. package/dist/cjs/query.js.map +1 -1
  16. package/dist/cjs/stores/async.js +38 -3
  17. package/dist/cjs/stores/async.js.map +1 -1
  18. package/dist/cjs/stores/shared.js +5 -1
  19. package/dist/cjs/stores/shared.js.map +1 -1
  20. package/dist/cjs/stores/sync.js +46 -10
  21. package/dist/cjs/stores/sync.js.map +1 -1
  22. package/dist/cjs/typeDefs.js +128 -5
  23. package/dist/cjs/typeDefs.js.map +1 -1
  24. package/dist/esm/EntityMap.d.ts +9 -3
  25. package/dist/esm/EntityMap.d.ts.map +1 -1
  26. package/dist/esm/EntityMap.js +46 -8
  27. package/dist/esm/EntityMap.js.map +1 -1
  28. package/dist/esm/QueryClient.d.ts +19 -1
  29. package/dist/esm/QueryClient.d.ts.map +1 -1
  30. package/dist/esm/QueryClient.js +43 -3
  31. package/dist/esm/QueryClient.js.map +1 -1
  32. package/dist/esm/QueryResult.d.ts +9 -3
  33. package/dist/esm/QueryResult.d.ts.map +1 -1
  34. package/dist/esm/QueryResult.js +122 -79
  35. package/dist/esm/QueryResult.js.map +1 -1
  36. package/dist/esm/QueryStore.d.ts +0 -104
  37. package/dist/esm/QueryStore.d.ts.map +1 -1
  38. package/dist/esm/QueryStore.js +1 -562
  39. package/dist/esm/QueryStore.js.map +1 -1
  40. package/dist/esm/errors.d.ts.map +1 -1
  41. package/dist/esm/errors.js +18 -1
  42. package/dist/esm/errors.js.map +1 -1
  43. package/dist/esm/proxy.d.ts +1 -1
  44. package/dist/esm/proxy.d.ts.map +1 -1
  45. package/dist/esm/proxy.js +54 -14
  46. package/dist/esm/proxy.js.map +1 -1
  47. package/dist/esm/query.d.ts +2 -0
  48. package/dist/esm/query.d.ts.map +1 -1
  49. package/dist/esm/query.js +2 -1
  50. package/dist/esm/query.js.map +1 -1
  51. package/dist/esm/stores/async.d.ts +3 -1
  52. package/dist/esm/stores/async.d.ts.map +1 -1
  53. package/dist/esm/stores/async.js +39 -4
  54. package/dist/esm/stores/async.js.map +1 -1
  55. package/dist/esm/stores/shared.d.ts +2 -0
  56. package/dist/esm/stores/shared.d.ts.map +1 -1
  57. package/dist/esm/stores/shared.js +2 -0
  58. package/dist/esm/stores/shared.js.map +1 -1
  59. package/dist/esm/stores/sync.d.ts +4 -2
  60. package/dist/esm/stores/sync.d.ts.map +1 -1
  61. package/dist/esm/stores/sync.js +40 -5
  62. package/dist/esm/stores/sync.js.map +1 -1
  63. package/dist/esm/type-utils.d.ts +4 -0
  64. package/dist/esm/type-utils.d.ts.map +1 -1
  65. package/dist/esm/typeDefs.d.ts +53 -5
  66. package/dist/esm/typeDefs.d.ts.map +1 -1
  67. package/dist/esm/typeDefs.js +126 -5
  68. package/dist/esm/typeDefs.js.map +1 -1
  69. package/dist/esm/types.d.ts +36 -10
  70. package/dist/esm/types.d.ts.map +1 -1
  71. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @signalium/query
2
2
 
3
+ ## 1.0.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 7f94377: Fixup format registry and add global format type registry
8
+ - d1f9def: Add ability to defined cached methods to entities
9
+ - e0a4844: Add ability for Entities to subscribe to streams when in use
10
+ - 6b961f0: Add support for Signal query parameters and debounced updates
11
+ - Updated dependencies [2cf6766]
12
+ - signalium@2.1.4
13
+
3
14
  ## 1.0.10
4
15
 
5
16
  ### Patch Changes
@@ -5,6 +5,10 @@ const signalium_1 = require("signalium");
5
5
  const proxy_js_1 = require("./proxy.js");
6
6
  class EntityStore {
7
7
  map = new Map();
8
+ queryClient;
9
+ constructor(queryClient) {
10
+ this.queryClient = queryClient;
11
+ }
8
12
  hasEntity(key) {
9
13
  return this.map.has(key);
10
14
  }
@@ -19,8 +23,7 @@ class EntityStore {
19
23
  refIds.add(key);
20
24
  // Entangle the signal value. Whenever the signal value is updated, refIds
21
25
  // will also be updated, so no need for a second signal.
22
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
23
- record.signal.value;
26
+ record.notifier.consume();
24
27
  if (record.entityRefs !== undefined) {
25
28
  for (const ref of record.entityRefs) {
26
29
  this.getNestedEntityRefIds(ref, refIds);
@@ -33,14 +36,16 @@ class EntityStore {
33
36
  if (record === undefined) {
34
37
  throw new Error(`Entity ${key} not found`);
35
38
  }
36
- record.proxy = (0, proxy_js_1.createEntityProxy)(key, record, shape);
39
+ record.proxy = this.createEntityProxy(record, shape);
37
40
  return record;
38
41
  }
39
- setPreloadedEntity(key, obj) {
42
+ setPreloadedEntity(key, data) {
40
43
  const record = {
41
44
  key,
42
- signal: (0, signalium_1.signal)(obj, { equals: false }),
45
+ data,
46
+ notifier: (0, signalium_1.notifier)(),
43
47
  cache: new Map(),
48
+ id: undefined,
44
49
  proxy: undefined,
45
50
  entityRefs: undefined,
46
51
  };
@@ -51,15 +56,48 @@ class EntityStore {
51
56
  let record = this.map.get(key);
52
57
  if (record === undefined) {
53
58
  record = this.setPreloadedEntity(key, obj);
54
- record.proxy = (0, proxy_js_1.createEntityProxy)(key, record, shape);
59
+ record.proxy = this.createEntityProxy(record, shape);
55
60
  }
56
61
  else {
57
- record.signal.update(value => (0, proxy_js_1.mergeValues)(value, obj));
62
+ record.data = (0, proxy_js_1.mergeValues)(record.data, obj);
63
+ record.notifier.notify();
58
64
  record.cache.clear();
59
65
  }
60
66
  record.entityRefs = entityRefs;
61
67
  return record;
62
68
  }
69
+ createEntityProxy(record, shape) {
70
+ const idField = shape.idField;
71
+ if (idField === undefined) {
72
+ throw new Error(`Entity id field is required ${shape.typenameValue}`);
73
+ }
74
+ const id = record.data[idField];
75
+ if (typeof id !== 'string' && typeof id !== 'number') {
76
+ console.log(record.data);
77
+ throw new Error(`Entity id must be string or number: ${shape.typenameValue}`);
78
+ }
79
+ record.id = id;
80
+ let entityRelay;
81
+ const entityConfig = shape._entityConfig;
82
+ if (entityConfig?.stream) {
83
+ entityRelay = (0, signalium_1.relay)(state => {
84
+ const context = this.queryClient.getContext();
85
+ const onUpdate = (update) => {
86
+ const currentValue = record.data;
87
+ const merged = (0, proxy_js_1.mergeValues)(currentValue, update);
88
+ record.data = merged;
89
+ record.notifier.notify();
90
+ record.cache.clear();
91
+ };
92
+ const unsubscribe = entityConfig.stream.subscribe(context, id, onUpdate);
93
+ // Set initial value to the proxy - this resolves the relay promise
94
+ // Proxy should always exist at this point since it's created before relay access
95
+ state.value = record.proxy;
96
+ return unsubscribe;
97
+ });
98
+ }
99
+ return (0, proxy_js_1.createEntityProxy)(record.key, record, shape, entityRelay, this.queryClient);
100
+ }
63
101
  }
64
102
  exports.EntityStore = EntityStore;
65
103
  //# sourceMappingURL=EntityMap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityMap.js","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAE3C,yCAA4D;AAY5D,MAAa,WAAW;IACd,GAAG,GAAG,IAAI,GAAG,EAAgD,CAAC;IAEtE,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,qBAAqB,CAAC,GAAW,EAAE,MAAmB;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAEnC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,+CAA+C,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhB,0EAA0E;QAC1E,wDAAwD;QACxD,oEAAoE;QACpE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;QAEpB,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACpC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,sBAAsB,CAAC,GAAW,EAAE,KAAgB;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,CAAC,KAAK,GAAG,IAAA,4BAAiB,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAErD,OAAO,MAAsB,CAAC;IAChC,CAAC;IAED,kBAAkB,CAAC,GAAW,EAAE,GAA4B;QAC1D,MAAM,MAAM,GAA0B;YACpC,GAAG;YACH,MAAM,EAAE,IAAA,kBAAM,EAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YACtC,KAAK,EAAE,IAAI,GAAG,EAAE;YAChB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,SAAS;SACtB,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,SAAS,CAAC,GAAW,EAAE,GAA4B,EAAE,KAAgB,EAAE,UAAwB;QAC7F,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE/B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAE3C,MAAM,CAAC,KAAK,GAAG,IAAA,4BAAiB,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAA,sBAAW,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QAE/B,OAAO,MAAsB,CAAC;IAChC,CAAC;CACF;AA3ED,kCA2EC"}
1
+ {"version":3,"file":"EntityMap.js","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.QueryClientContext = exports.QueryClient = exports.queryKeyFor = void 0;
16
+ exports.extractParamsForKey = extractParamsForKey;
16
17
  exports.addOptimisticInsert = addOptimisticInsert;
17
18
  exports.removeOptimisticInsert = removeOptimisticInsert;
18
19
  const signalium_1 = require("signalium");
@@ -22,6 +23,41 @@ const NetworkManager_js_1 = require("./NetworkManager.js");
22
23
  const QueryResult_js_1 = require("./QueryResult.js");
23
24
  const RefetchManager_js_1 = require("./RefetchManager.js");
24
25
  const MemoryEvictionManager_js_1 = require("./MemoryEvictionManager.js");
26
+ /**
27
+ * Checks if a value is a Signal instance
28
+ */
29
+ function isSignal(value) {
30
+ return typeof value === 'object' && value !== null;
31
+ }
32
+ /**
33
+ * Extracts actual values from params that may contain Signals.
34
+ */
35
+ function extractParamsForKey(params) {
36
+ if (params === undefined) {
37
+ return undefined;
38
+ }
39
+ const extracted = {};
40
+ for (const [key, value] of Object.entries(params)) {
41
+ if (isSignal(value)) {
42
+ extracted[key] = value.value;
43
+ }
44
+ else {
45
+ extracted[key] = value;
46
+ }
47
+ }
48
+ return extracted;
49
+ }
50
+ /**
51
+ * Computes the query key for instance lookup. This is used for two different keys:
52
+ *
53
+ * - Query instance key
54
+ * - Query storage key
55
+ *
56
+ * Instance keys are created by passing in the query definition and parameters WITHOUT
57
+ * extracting the Signal values, whereas storage keys are created by extracting the Signal values.
58
+ * This way, we can reuse the same instance for given Signals, but different underlying values
59
+ * will be stored and put into the LRU cache separately.
60
+ */
25
61
  const queryKeyFor = (queryDef, params) => {
26
62
  return (0, utils_1.hashValue)([queryDef.id, queryDef.shapeKey, params]);
27
63
  };
@@ -29,7 +65,7 @@ exports.queryKeyFor = queryKeyFor;
29
65
  class QueryClient {
30
66
  store;
31
67
  context;
32
- entityMap = new EntityMap_js_1.EntityStore();
68
+ entityMap;
33
69
  queryInstances = new Map();
34
70
  memoryEvictionManager;
35
71
  refetchManager;
@@ -43,6 +79,7 @@ class QueryClient {
43
79
  this.refetchManager = refetchManager ?? new RefetchManager_js_1.RefetchManager(this.context.refetchMultiplier);
44
80
  this.networkManager = networkManager ?? new NetworkManager_js_1.NetworkManager();
45
81
  this.isServer = typeof window === 'undefined';
82
+ this.entityMap = new EntityMap_js_1.EntityStore(this);
46
83
  }
47
84
  getContext() {
48
85
  return this.context;
@@ -54,12 +91,14 @@ class QueryClient {
54
91
  this.store.saveQuery(queryDef, queryKey, data, updatedAt, clonedRefs, extra);
55
92
  }
56
93
  activateQuery(queryInstance) {
57
- const { def, queryKey } = queryInstance;
58
- this.store.activateQuery(def, queryKey);
94
+ const { def, queryKey, storageKey } = queryInstance;
95
+ // Use storageKey for cache operations (store.activateQuery)
96
+ this.store.activateQuery(def, storageKey);
59
97
  // Only add to refetch manager if it's not a stream
60
98
  if (def.type !== "stream" /* QueryType.Stream */ && def.cache?.refetchInterval) {
61
99
  this.refetchManager.addQuery(queryInstance);
62
100
  }
101
+ // Use queryKey for instance eviction (memoryEvictionManager)
63
102
  this.memoryEvictionManager.cancelEviction(queryKey);
64
103
  }
65
104
  loadCachedQuery(queryDef, queryKey) {
@@ -84,7 +123,9 @@ class QueryClient {
84
123
  return this.entityMap.hydratePreloadedEntity(key, shape);
85
124
  }
86
125
  saveEntity(key, obj, shape, entityRefs) {
126
+ // console.log('saveEntity', key, JSON.stringify(obj, null, 2), shape, entityRefs, new Error().stack);
87
127
  const record = this.entityMap.setEntity(key, obj, shape, entityRefs);
128
+ // console.log('saveEntity record', JSON.stringify(obj, null, 2), new Error().stack);
88
129
  this.store.saveEntity(key, obj, entityRefs);
89
130
  return record;
90
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"QueryClient.js","sourceRoot":"","sources":["../../src/QueryClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QueryClient.js","sourceRoot":"","sources":["../../src/QueryClient.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ const types_js_1 = require("./types.js");
7
7
  const proxy_js_1 = require("./proxy.js");
8
8
  const parseEntities_js_1 = require("./parseEntities.js");
9
9
  const typeDefs_js_1 = require("./typeDefs.js");
10
+ const QueryClient_js_1 = require("./QueryClient.js");
10
11
  // ======================================================
11
12
  // QueryResultExtra - Manages stream orphans and optimistic inserts
12
13
  // ======================================================
@@ -257,7 +258,8 @@ class QueryResultExtra {
257
258
  */
258
259
  class QueryResultImpl {
259
260
  def;
260
- queryKey;
261
+ queryKey; // Instance key (includes Signal identity)
262
+ storageKey = -1; // Storage key (extracted values only)
261
263
  queryClient;
262
264
  initialized = false;
263
265
  isRefetchingSignal = (0, signalium_1.signal)(false);
@@ -268,12 +270,12 @@ class QueryResultImpl {
268
270
  allNestedRefIdsSignal = undefined;
269
271
  refetchPromise = undefined;
270
272
  fetchMorePromise = undefined;
271
- attemptCount = 0;
272
273
  unsubscribe = undefined;
273
- streamUnsubscribe = undefined;
274
274
  relay;
275
275
  _relayState = undefined;
276
- wasOffline = false;
276
+ wasPaused = false;
277
+ currentParams = undefined;
278
+ debounceTimer = undefined;
277
279
  get relayState() {
278
280
  const relayState = this._relayState;
279
281
  if (!relayState) {
@@ -306,7 +308,7 @@ class QueryResultImpl {
306
308
  else {
307
309
  // Clone current params
308
310
  let hasDefinedParams = false;
309
- const clonedParams = { ...this.params };
311
+ const clonedParams = { ...this.currentParams };
310
312
  // iterate over the next page params and copy any defined values to the
311
313
  for (const [key, value] of Object.entries(nextParams)) {
312
314
  if (value !== undefined && value !== null) {
@@ -323,91 +325,96 @@ class QueryResultImpl {
323
325
  (0, utils_1.setReactivePromise)(this);
324
326
  this.def = def;
325
327
  this.queryClient = queryClient;
326
- this.queryKey = queryKey;
328
+ this.queryKey = queryKey; // Instance key (Signal identity)
327
329
  this.params = params;
328
330
  // Create the relay and handle activation/deactivation
329
331
  this.relay = (0, signalium_1.relay)(state => {
330
332
  this._relayState = state;
333
+ // Extract params (reading Signal values establishes tracking)
334
+ this.currentParams = (0, QueryClient_js_1.extractParamsForKey)(this.params);
335
+ this.storageKey = (0, QueryClient_js_1.queryKeyFor)(this.def, this.currentParams);
331
336
  // Load from cache first, then fetch fresh data
332
337
  this.queryClient.activateQuery(this);
333
- // Track network status for reconnect handling
334
- const networkManager = this.queryClient.networkManager;
335
- const isOnline = networkManager.getOnlineSignal().value;
336
338
  // Store initial offline state
337
- this.wasOffline = !isOnline;
339
+ const isPaused = this.isPaused;
340
+ this.wasPaused = isPaused;
338
341
  if (this.initialized) {
339
- // For any query with streams, resubscribe on reactivation
340
- if (this.def.type === "stream" /* QueryType.Stream */ ||
341
- this.def.stream) {
342
- this.setupSubscription();
343
- }
344
- if (this.def.type !== "stream" /* QueryType.Stream */) {
345
- // Check if we just came back online
346
- if (!this.wasOffline && isOnline) {
347
- // We're back online - check if we should refresh
348
- const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;
349
- if (refreshStaleOnReconnect && this.isStale) {
350
- this.refetch();
351
- }
352
- // Reset attempt count on reconnect
353
- this.attemptCount = 0;
342
+ if (!isPaused) {
343
+ // For any query with streams, resubscribe on reactivation
344
+ if (this.def.type === "stream" /* QueryType.Stream */ ||
345
+ this.def.stream) {
346
+ this.setupSubscription();
354
347
  }
355
- else if (this.isStale && !this.isPaused) {
348
+ if (this.def.type !== "stream" /* QueryType.Stream */ && this.isStale) {
356
349
  this.refetch();
357
350
  }
358
351
  }
359
- // Update wasOffline for next check
360
- this.wasOffline = !isOnline;
361
352
  }
362
353
  else {
363
354
  this.initialize();
364
355
  }
356
+ const deactivate = () => {
357
+ // Clear debounce timer if active
358
+ clearTimeout(this.debounceTimer);
359
+ this.debounceTimer = undefined;
360
+ // Last subscriber left, deactivate refetch and schedule memory eviction
361
+ // Unsubscribe from any active streams
362
+ this.unsubscribe?.();
363
+ this.unsubscribe = undefined;
364
+ // Remove from refetch manager if configured
365
+ if (this.def.type !== "stream" /* QueryType.Stream */ && this.def.cache?.refetchInterval) {
366
+ this.queryClient.refetchManager.removeQuery(this);
367
+ }
368
+ // Schedule removal from memory using the global eviction manager
369
+ // This allows quick reactivation from memory if needed again soon
370
+ // Disk cache (if configured) will still be available after eviction
371
+ // Use queryKey for instance eviction, storageKey for cache eviction
372
+ this.queryClient.memoryEvictionManager.scheduleEviction(this.queryKey);
373
+ };
365
374
  // Return deactivation callback
366
375
  return {
367
376
  update: () => {
368
- // For any query with streams, unsubscribe and resubscribe to re-establish connection
369
- if (this.def.type === "stream" /* QueryType.Stream */ ||
370
- this.def.stream) {
371
- this.setupSubscription();
372
- }
373
- // For StreamQuery, we're done - it doesn't react to network status
374
- if (this.def.type === "stream" /* QueryType.Stream */) {
377
+ const { wasPaused, isPaused } = this;
378
+ this.wasPaused = isPaused;
379
+ if (isPaused) {
380
+ deactivate();
381
+ // TODO: Add abort signal
375
382
  return;
376
383
  }
377
- // Network status changed - check if we should react
378
- const currentlyOnline = networkManager.getOnlineSignal().value;
379
- // If we just came back online
380
- if (this.wasOffline && currentlyOnline) {
381
- const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;
382
- if (refreshStaleOnReconnect && this.isStale) {
383
- state.setPromise(this.runQuery(this.params, true));
384
- }
385
- // Reset attempt count on reconnect
386
- this.attemptCount = 0;
387
- }
388
- // Update wasOffline for next check
389
- this.wasOffline = !currentlyOnline;
390
- },
391
- deactivate: () => {
392
- // Last subscriber left, deactivate refetch and schedule memory eviction
393
- // Unsubscribe from any active streams
394
- if (this.unsubscribe) {
395
- this.unsubscribe();
396
- this.unsubscribe = undefined;
384
+ // Read Signal values again to establish tracking for any new Signals
385
+ // Extract params (reading Signal values establishes tracking)
386
+ const newExtractedParams = (0, QueryClient_js_1.extractParamsForKey)(this.params);
387
+ const newStorageKey = (0, QueryClient_js_1.queryKeyFor)(this.def, newExtractedParams);
388
+ const paramsDidChange = newStorageKey !== this.storageKey;
389
+ // Check if storage key changed (comparing hash values)
390
+ if (paramsDidChange) {
391
+ // Same storage key, just Signal instances changed but values are the same
392
+ // Update params and trigger debounced refetch
393
+ this.params = newExtractedParams;
394
+ this.storageKey = newStorageKey;
397
395
  }
398
- if (this.streamUnsubscribe) {
399
- this.streamUnsubscribe();
400
- this.streamUnsubscribe = undefined;
396
+ if (wasPaused) {
397
+ this.queryClient.activateQuery(this);
398
+ if (this.def.type !== "stream" /* QueryType.Stream */) {
399
+ const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;
400
+ if (refreshStaleOnReconnect && this.isStale) {
401
+ state.setPromise(this.runQuery(this.currentParams, true));
402
+ }
403
+ }
404
+ else {
405
+ this.setupSubscription();
406
+ }
401
407
  }
402
- // Remove from refetch manager if configured
403
- if (this.def.type !== "stream" /* QueryType.Stream */ && this.def.cache?.refetchInterval) {
404
- this.queryClient.refetchManager.removeQuery(this);
408
+ else if (paramsDidChange) {
409
+ if (this.def.type !== "stream" /* QueryType.Stream */) {
410
+ this.debouncedRefetch();
411
+ }
412
+ else {
413
+ this.setupSubscription();
414
+ }
405
415
  }
406
- // Schedule removal from memory using the global eviction manager
407
- // This allows quick reactivation from memory if needed again soon
408
- // Disk cache (if configured) will still be available after eviction
409
- this.queryClient.memoryEvictionManager.scheduleEviction(this.queryKey);
410
416
  },
417
+ deactivate,
411
418
  };
412
419
  });
413
420
  }
@@ -491,8 +498,8 @@ class QueryResultImpl {
491
498
  const state = this.relayState;
492
499
  try {
493
500
  this.initialized = true;
494
- // Load from cache first
495
- const cached = await this.queryClient.loadCachedQuery(this.def, this.queryKey);
501
+ // Load from cache first (use storage key for cache operations)
502
+ const cached = await this.queryClient.loadCachedQuery(this.def, this.storageKey);
496
503
  if (cached !== undefined) {
497
504
  // Set the cached timestamp
498
505
  this.updatedAt = cached.updatedAt;
@@ -511,6 +518,9 @@ class QueryResultImpl {
511
518
  ? (0, parseEntities_js_1.parseEntities)(cached.value, shape, this.queryClient, new Set())
512
519
  : (0, proxy_js_1.parseValue)(cached.value, shape, this.def.id);
513
520
  }
521
+ if (this.isPaused) {
522
+ return;
523
+ }
514
524
  // Setup subscriptions (handles both StreamQuery and Query/InfiniteQuery with stream)
515
525
  if (this.def.type === "stream" /* QueryType.Stream */ ||
516
526
  this.def.stream) {
@@ -521,13 +531,19 @@ class QueryResultImpl {
521
531
  if (cached !== undefined) {
522
532
  // Check if data is stale
523
533
  if (this.isStale) {
524
- // Data is stale, trigger background refetch
525
- this.refetch();
534
+ // Data is stale, trigger background refetch (with debounce if configured)
535
+ if (this.def.debounce !== undefined && this.def.debounce > 0) {
536
+ this.debouncedRefetch();
537
+ }
538
+ else {
539
+ this.refetch();
540
+ }
526
541
  }
527
542
  }
528
543
  else {
529
- // No cached data, fetch fresh
530
- state.setPromise(this.runQuery(this.params, true));
544
+ // No cached data, fetch fresh immediately (don't debounce initial fetch)
545
+ // Debounce only applies to refetches triggered by parameter changes
546
+ state.setPromise(this.runQuery(this.currentParams, true));
531
547
  }
532
548
  }
533
549
  }
@@ -557,14 +573,17 @@ class QueryResultImpl {
557
573
  shapeDef = stream.shape;
558
574
  subscribeFn = stream.subscribeFn;
559
575
  }
560
- this.unsubscribe = subscribeFn(this.queryClient.getContext(), this.params, update => {
576
+ // Extract params (reading Signal values establishes tracking)
577
+ const extractedParams = this.currentParams;
578
+ this.unsubscribe = subscribeFn(this.queryClient.getContext(), extractedParams, update => {
561
579
  const parsedData = (0, parseEntities_js_1.parseObjectEntities)(update, shapeDef, this.queryClient);
562
580
  // Update the relay state
563
581
  if (this.def.type === "stream" /* QueryType.Stream */) {
564
582
  this.relayState.value = parsedData;
565
583
  this.updatedAt = Date.now();
566
584
  // Cache the data
567
- this.queryClient.saveQueryData(this.def, this.queryKey, parsedData, this.updatedAt);
585
+ // Use storage key for cache operations
586
+ this.queryClient.saveQueryData(this.def, this.storageKey, parsedData, this.updatedAt);
568
587
  }
569
588
  else {
570
589
  const allRefIds = this.getAllEntityRefs();
@@ -591,8 +610,6 @@ class QueryResultImpl {
591
610
  try {
592
611
  const queryDef = this.def;
593
612
  const freshData = await queryDef.fetchFn(this.queryClient.getContext(), params);
594
- // Success! Reset attempt count
595
- this.attemptCount = 0;
596
613
  // Parse and cache the fresh data
597
614
  let entityRefs;
598
615
  const isInfinite = this.def.type === "infiniteQuery" /* QueryType.InfiniteQuery */;
@@ -623,14 +640,14 @@ class QueryResultImpl {
623
640
  }
624
641
  this._nextPageParams = undefined;
625
642
  // Cache the data (synchronous, fire-and-forget)
626
- this.queryClient.saveQueryData(this.def, this.queryKey, queryData, updatedAt, entityRefs, this.getExtraForPersistence());
643
+ // Use storage key for cache operations
644
+ this.queryClient.saveQueryData(this.def, this.storageKey, queryData, updatedAt, entityRefs, this.getExtraForPersistence());
627
645
  // Update the timestamp
628
646
  this.updatedAt = Date.now();
629
647
  return queryData;
630
648
  }
631
649
  catch (error) {
632
650
  lastError = error;
633
- this.attemptCount = attempt + 1;
634
651
  // If we've exhausted retries, throw the error
635
652
  if (attempt >= retries) {
636
653
  throw error;
@@ -648,6 +665,28 @@ class QueryResultImpl {
648
665
  throw lastError;
649
666
  }
650
667
  // ======================================================
668
+ // Private debounce methods
669
+ // ======================================================
670
+ /**
671
+ * Triggers a debounced refetch. If debounce is configured, delays the fetch.
672
+ * Otherwise, calls refetch immediately.
673
+ */
674
+ debouncedRefetch() {
675
+ // We know this is a non-stream query because we're calling refetch, which is only available on non-stream queries
676
+ const debounce = this.def.debounce;
677
+ if (debounce === undefined) {
678
+ this.refetch();
679
+ return;
680
+ }
681
+ // Clear existing timer
682
+ clearTimeout(this.debounceTimer);
683
+ // Set new timer
684
+ this.debounceTimer = setTimeout(() => {
685
+ this.debounceTimer = undefined;
686
+ this.refetch();
687
+ }, debounce);
688
+ }
689
+ // ======================================================
651
690
  // Public methods
652
691
  // ======================================================
653
692
  refetch = () => {
@@ -660,13 +699,16 @@ class QueryResultImpl {
660
699
  if (this.refetchPromise) {
661
700
  return this.refetchPromise;
662
701
  }
702
+ // Clear debounce timer if active (manual refetch should bypass debounce)
703
+ clearTimeout(this.debounceTimer);
704
+ this.debounceTimer = undefined;
663
705
  // Clear memoized nextPageParams so it's recalculated after refetch
664
706
  this._nextPageParams = undefined;
665
707
  // Set the signal before any async operations so it's immediately visible
666
708
  // Use untrack to avoid reactive violations when called from reactive context
667
709
  this.isRefetchingSignal.value = true;
668
710
  this._version.update(v => v + 1);
669
- const promise = this.runQuery(this.params, true)
711
+ const promise = this.runQuery(this.currentParams, true)
670
712
  .then(result => {
671
713
  this.relayState.value = result;
672
714
  // Clear stream orphans and optimistic inserts on refetch
@@ -750,7 +792,8 @@ class QueryResultImpl {
750
792
  return; // Query not initialized yet
751
793
  }
752
794
  const extra = this._extra?.getForPersistence();
753
- this.queryClient.saveQueryData(this.def, this.queryKey, this.relayState.value, this.updatedAt, this.refIds, extra);
795
+ // Use storage key for cache operations
796
+ this.queryClient.saveQueryData(this.def, this.storageKey, this.relayState.value, this.updatedAt, this.refIds, extra);
754
797
  }
755
798
  /**
756
799
  * Get extra data for persistence (converts Sets to arrays of entity ref IDs)