@choksheak/react-utils 0.2.2 → 0.2.4
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 +3 -1
- package/package.json +39 -33
- package/sharedQuery.d.mts +68 -8
- package/sharedQuery.d.ts +67 -7
- package/sharedQuery.js +240 -79
- package/sharedQuery.mjs +228 -77
- package/src/sharedQuery.ts +338 -103
- package/src/utils/useDeepMemo.ts +19 -0
- package/utils/useDeepMemo.d.mts +4 -0
- package/utils/useDeepMemo.d.ts +2 -0
- package/utils/useDeepMemo.js +51 -0
- package/utils/useDeepMemo.mjs +16 -0
- package/docs/.nojekyll +0 -1
- package/docs/assets/hierarchy.js +0 -1
- package/docs/assets/highlight.css +0 -22
- package/docs/assets/icons.js +0 -18
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -60
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1633
- package/docs/classes/sharedQuery.SharedQuery.html +0 -17
- package/docs/classes/sharedState.SharedState.html +0 -9
- package/docs/classes/utils_storage.InMemoryStorageAdapter.html +0 -9
- package/docs/classes/utils_storage.IndexedDbAdapter.html +0 -9
- package/docs/classes/utils_storage.LocalStorageAdapter.html +0 -9
- package/docs/functions/sharedQuery.sharedQuery.html +0 -5
- package/docs/functions/sharedQuery.useSharedQuery.html +0 -4
- package/docs/functions/sharedState.sharedState.html +0 -3
- package/docs/functions/sharedState.useSharedState.html +0 -3
- package/docs/functions/sharedState.useSharedStateSetter.html +0 -2
- package/docs/functions/sharedState.useSharedStateValue.html +0 -2
- package/docs/functions/utils_storage.getStorageAdapter.html +0 -1
- package/docs/functions/utils_stringify.stringifyDeterministicForKeys.html +0 -7
- package/docs/hierarchy.html +0 -1
- package/docs/index.html +0 -2
- package/docs/modules/fetcher.html +0 -1
- package/docs/modules/index.html +0 -1
- package/docs/modules/sharedQuery.html +0 -1
- package/docs/modules/sharedState.html +0 -1
- package/docs/modules/utils_storage.html +0 -1
- package/docs/modules/utils_stringify.html +0 -1
- package/docs/modules.html +0 -1
- package/docs/types/sharedQuery.FetchFn.html +0 -1
- package/docs/types/sharedQuery.PersistTo.html +0 -1
- package/docs/types/sharedQuery.QueryStateValue.html +0 -6
- package/docs/types/sharedQuery.SharedQueryOptions.html +0 -1
- package/docs/types/sharedQuery.SharedQueryState.html +0 -3
- package/docs/types/sharedQuery.UseQueryResult.html +0 -1
- package/docs/types/sharedState.SharedStateOptions.html +0 -1
- package/docs/types/utils_storage.StorageAdapter.html +0 -5
- package/docs/types/utils_storage.StorageOptions.html +0 -5
- package/docs/variables/fetcher.fetcher.html +0 -2
- package/docs/variables/fetcher.fetcherWithRetries.html +0 -2
- package/docs/variables/sharedQuery.SharedQueryDefaults.html +0 -2
- package/docs/variables/sharedState.SharedStateDefaults.html +0 -6
- package/src/utils/stringify.test.ts +0 -46
- package/utils/stringify.test.d.mts +0 -2
- package/utils/stringify.test.d.ts +0 -2
- package/utils/stringify.test.js +0 -69
- package/utils/stringify.test.mjs +0 -86
package/sharedQuery.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/sharedQuery.ts
|
|
2
2
|
import { MS_PER_DAY as MS_PER_DAY2 } from "@choksheak/ts-utils/timeConstants";
|
|
3
|
-
import
|
|
3
|
+
import getByteSize from "object-sizeof";
|
|
4
|
+
import { useCallback, useEffect, useMemo as useMemo2, useRef } from "react";
|
|
4
5
|
|
|
5
6
|
// src/sharedState.ts
|
|
6
7
|
import { MS_PER_DAY } from "@choksheak/ts-utils/timeConstants";
|
|
@@ -265,34 +266,68 @@ function stringifyDeterministicForKeys(params) {
|
|
|
265
266
|
});
|
|
266
267
|
}
|
|
267
268
|
|
|
269
|
+
// src/utils/useDeepMemo.ts
|
|
270
|
+
import isEqual from "lodash/isEqual";
|
|
271
|
+
import { useMemo, useState } from "react";
|
|
272
|
+
function useDeepMemo(value) {
|
|
273
|
+
const [state, setState] = useState(value);
|
|
274
|
+
return useMemo(() => {
|
|
275
|
+
if (state === value || isEqual(state, value)) {
|
|
276
|
+
return state;
|
|
277
|
+
}
|
|
278
|
+
setState(value);
|
|
279
|
+
return value;
|
|
280
|
+
}, [state, value]);
|
|
281
|
+
}
|
|
282
|
+
|
|
268
283
|
// src/sharedQuery.ts
|
|
269
284
|
var SharedQueryDefaults = {
|
|
285
|
+
// Refetch on every page load.
|
|
270
286
|
staleMs: 0,
|
|
287
|
+
// Keep in cache for a long time.
|
|
271
288
|
expiryMs: 30 * MS_PER_DAY2,
|
|
272
|
-
|
|
289
|
+
// Always refetch automatically if the data is stale.
|
|
290
|
+
refetchOnStale: true,
|
|
291
|
+
// No default persistence configured.
|
|
292
|
+
persistTo: void 0,
|
|
293
|
+
// 100 is not too large, but please tweak accordingly.
|
|
294
|
+
maxSize: 100,
|
|
295
|
+
// 100kb limit before discarding old records.
|
|
296
|
+
maxBytes: 1e5,
|
|
297
|
+
// Default to log to console.
|
|
298
|
+
log: (...args) => console.log("[sharedQuery]", ...args)
|
|
273
299
|
};
|
|
274
300
|
var SharedQuery = class {
|
|
275
|
-
|
|
301
|
+
inflightQueries = /* @__PURE__ */ new Map();
|
|
276
302
|
queryState;
|
|
277
303
|
queryName;
|
|
278
304
|
queryFn;
|
|
279
305
|
expiryMs;
|
|
280
306
|
staleMs;
|
|
281
307
|
refetchOnStale;
|
|
308
|
+
maxSize;
|
|
309
|
+
maxBytes;
|
|
310
|
+
log;
|
|
282
311
|
constructor(options) {
|
|
283
312
|
this.queryName = options.queryName;
|
|
284
313
|
this.queryFn = options.queryFn;
|
|
285
|
-
this.
|
|
286
|
-
this.
|
|
287
|
-
this.refetchOnStale =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
314
|
+
this.staleMs = options?.staleMs ?? SharedQueryDefaults.staleMs;
|
|
315
|
+
this.expiryMs = options?.expiryMs ?? SharedQueryDefaults.expiryMs;
|
|
316
|
+
this.refetchOnStale = options?.refetchOnStale ?? SharedQueryDefaults.refetchOnStale;
|
|
317
|
+
if (!options.localStorageKey && !options.indexedDbKey) {
|
|
318
|
+
const persistTo = options.persistTo ?? SharedQueryDefaults.persistTo;
|
|
319
|
+
if (persistTo === "localStorage") {
|
|
320
|
+
options.localStorageKey = options.queryName;
|
|
321
|
+
} else if (persistTo === "indexedDb") {
|
|
322
|
+
options.indexedDbKey = options.queryName;
|
|
323
|
+
}
|
|
293
324
|
}
|
|
325
|
+
this.maxSize = options?.maxSize ?? SharedQueryDefaults.maxSize;
|
|
326
|
+
this.maxBytes = options?.maxBytes ?? SharedQueryDefaults.maxBytes;
|
|
327
|
+
this.log = options?.log ?? SharedQueryDefaults.log;
|
|
294
328
|
this.queryState = sharedState(
|
|
295
329
|
{},
|
|
330
|
+
// defaultValue
|
|
296
331
|
{
|
|
297
332
|
...options,
|
|
298
333
|
// Fallback to use expiryMs for the storeExpiryMs.
|
|
@@ -300,9 +335,24 @@ var SharedQuery = class {
|
|
|
300
335
|
}
|
|
301
336
|
);
|
|
302
337
|
}
|
|
338
|
+
/** Returns a key to identify requests based on the given args. */
|
|
303
339
|
getQueryKey(args) {
|
|
304
340
|
return this.queryName + ":" + stringifyDeterministicForKeys(args);
|
|
305
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Get the AbortController to abort the inflight query (if any).
|
|
344
|
+
*
|
|
345
|
+
* Note that once you get the controller, you can also get the signal easily
|
|
346
|
+
* using `controller.signal`. So if you need both the controller and the
|
|
347
|
+
* signal, just use this function.
|
|
348
|
+
*/
|
|
349
|
+
getAbortController(queryKey) {
|
|
350
|
+
return this.inflightQueries.get(queryKey)?.abortController ?? null;
|
|
351
|
+
}
|
|
352
|
+
/** Get the AbortSignal to check for query abortions. */
|
|
353
|
+
getAbortSignal(queryKey) {
|
|
354
|
+
return this.getAbortController(queryKey)?.signal ?? null;
|
|
355
|
+
}
|
|
306
356
|
isStale(dataUpdatedMs) {
|
|
307
357
|
if (this.staleMs === 0) return true;
|
|
308
358
|
const ageMs = Date.now() - dataUpdatedMs;
|
|
@@ -318,52 +368,53 @@ var SharedQuery = class {
|
|
|
318
368
|
const cached = this.queryState.getSnapshot()?.[queryKey];
|
|
319
369
|
if (cached?.data && !this.isExpired(cached.dataUpdatedMs ?? 0)) {
|
|
320
370
|
if (!this.isStale(cached.dataUpdatedMs ?? 0)) {
|
|
321
|
-
|
|
322
|
-
`Return fresh data ${queryKey} from cache without fetching`
|
|
323
|
-
);
|
|
371
|
+
this.log(`Return fresh data ${queryKey} from cache without fetching`);
|
|
324
372
|
return cached.data;
|
|
325
373
|
}
|
|
326
374
|
if (this.refetchOnStale) {
|
|
327
|
-
|
|
375
|
+
this.log(`refetchOnStale for ${queryKey}`);
|
|
328
376
|
void this.dedupedFetch(queryKey, ...args);
|
|
329
377
|
}
|
|
330
|
-
|
|
378
|
+
this.log(`Returning stale data for ${queryKey}`);
|
|
331
379
|
return cached.data;
|
|
332
380
|
}
|
|
333
381
|
return await this.dedupedFetch(queryKey, ...args);
|
|
334
382
|
}
|
|
335
383
|
dedupedFetch(queryKey, ...args) {
|
|
336
|
-
const
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
return
|
|
384
|
+
const inflightQuery = this.inflightQueries.get(queryKey);
|
|
385
|
+
if (inflightQuery) {
|
|
386
|
+
this.log(`Deduplicating inflight fetch for ${queryKey}`);
|
|
387
|
+
return inflightQuery.promise;
|
|
340
388
|
}
|
|
341
389
|
const promise = this.startFetching(queryKey, args);
|
|
342
|
-
|
|
390
|
+
const abortController = new AbortController();
|
|
391
|
+
this.inflightQueries.set(queryKey, { promise, abortController });
|
|
343
392
|
return promise;
|
|
344
393
|
}
|
|
345
394
|
async startFetching(queryKey, args) {
|
|
346
|
-
|
|
395
|
+
this.log(`Start fetching ${queryKey}`);
|
|
347
396
|
try {
|
|
348
397
|
const data = await this.queryFn(...args);
|
|
349
|
-
|
|
398
|
+
this.log(`Successfully fetched ${queryKey}`);
|
|
350
399
|
this.setData(queryKey, data, Date.now());
|
|
351
400
|
return data;
|
|
352
401
|
} catch (e) {
|
|
353
|
-
|
|
402
|
+
this.log(`Failed to fetch ${queryKey}: ${e}`);
|
|
354
403
|
throw e;
|
|
355
404
|
} finally {
|
|
356
|
-
this.
|
|
405
|
+
this.inflightQueries.delete(queryKey);
|
|
357
406
|
}
|
|
358
407
|
}
|
|
359
408
|
/** Set the data directly if the user obtained it from somewhere else. */
|
|
360
409
|
async setData(queryKey, data, dataUpdatedMs = Date.now()) {
|
|
361
410
|
const entry = {
|
|
411
|
+
lastUpdatedMs: Date.now(),
|
|
362
412
|
loading: false,
|
|
363
413
|
data,
|
|
364
414
|
dataUpdatedMs
|
|
365
415
|
};
|
|
366
416
|
this.queryState.setValue((prev) => ({ ...prev, [queryKey]: entry }));
|
|
417
|
+
this.enforceSizeLimit();
|
|
367
418
|
}
|
|
368
419
|
/** Do a new fetch even when the data is already cached. */
|
|
369
420
|
async updateFromSource(...args) {
|
|
@@ -371,18 +422,98 @@ var SharedQuery = class {
|
|
|
371
422
|
return await this.dedupedFetch(key, ...args);
|
|
372
423
|
}
|
|
373
424
|
/** Delete the cached data for one set of arguments. */
|
|
374
|
-
deleteData(
|
|
375
|
-
const queryKey = this.getQueryKey(args);
|
|
425
|
+
deleteData(queryKey) {
|
|
376
426
|
const record = this.queryState.getSnapshot();
|
|
377
427
|
const clone = { ...record };
|
|
378
428
|
delete clone[queryKey];
|
|
379
429
|
this.queryState.setValue(clone);
|
|
380
|
-
this.
|
|
430
|
+
const inflight = this.inflightQueries.get(queryKey);
|
|
431
|
+
if (inflight) {
|
|
432
|
+
this.inflightQueries.delete(queryKey);
|
|
433
|
+
inflight.abortController.abort("Deleted");
|
|
434
|
+
}
|
|
381
435
|
}
|
|
382
436
|
/** Delete all currently cached data & all inflight promises. */
|
|
383
437
|
clear() {
|
|
384
438
|
this.queryState.delete();
|
|
385
|
-
|
|
439
|
+
for (const { abortController } of Array.from(
|
|
440
|
+
this.inflightQueries.values()
|
|
441
|
+
)) {
|
|
442
|
+
abortController.abort("Cleared");
|
|
443
|
+
}
|
|
444
|
+
this.inflightQueries.clear();
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Discard the oldest entries if the size exceeds the limit. The last
|
|
448
|
+
* remaining record cannot be deleted no matter what the limit is.
|
|
449
|
+
*/
|
|
450
|
+
enforceSizeLimit() {
|
|
451
|
+
if (!this.maxSize && !this.maxBytes) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const oldState = this.queryState.getSnapshot();
|
|
455
|
+
const oldSize = Object.keys(oldState).length;
|
|
456
|
+
if (oldSize <= 1) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const oldByteSize = getByteSize(oldState);
|
|
460
|
+
let newState = oldState;
|
|
461
|
+
let needUpdate = false;
|
|
462
|
+
if (this.maxSize) {
|
|
463
|
+
const numToCut = oldSize - this.maxSize;
|
|
464
|
+
if (numToCut > 0) {
|
|
465
|
+
this.log(
|
|
466
|
+
`enforceSizeLimit for ${this.queryName} needed due to size ${oldSize} > ${this.maxSize}`
|
|
467
|
+
);
|
|
468
|
+
newState = { ...newState };
|
|
469
|
+
needUpdate = true;
|
|
470
|
+
Object.entries(newState).sort(
|
|
471
|
+
(entry1, entry2) => (
|
|
472
|
+
// Sort descending.
|
|
473
|
+
entry2[1].lastUpdatedMs - entry1[1].lastUpdatedMs
|
|
474
|
+
)
|
|
475
|
+
).slice(-numToCut).forEach(([key]) => {
|
|
476
|
+
delete newState[key];
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (this.maxBytes && Object.keys(newState).length > 1) {
|
|
481
|
+
const currentByteSize = needUpdate ? getByteSize(newState) : oldByteSize;
|
|
482
|
+
let bytesToCut = currentByteSize - this.maxBytes;
|
|
483
|
+
if (bytesToCut > 0) {
|
|
484
|
+
this.log(
|
|
485
|
+
`enforceSizeLimit for ${this.queryName} needed due to byte size ${currentByteSize.toLocaleString()} > ${this.maxBytes.toLocaleString()}`
|
|
486
|
+
);
|
|
487
|
+
if (!needUpdate) {
|
|
488
|
+
newState = { ...newState };
|
|
489
|
+
needUpdate = true;
|
|
490
|
+
}
|
|
491
|
+
const entriesByTimeAscending = Object.entries(newState).sort(
|
|
492
|
+
(entry1, entry2) => entry1[1].lastUpdatedMs - entry2[1].lastUpdatedMs
|
|
493
|
+
);
|
|
494
|
+
for (
|
|
495
|
+
let i = 0;
|
|
496
|
+
// Leave the last record entriesByTimeAscending[len-1] untouched.
|
|
497
|
+
i < entriesByTimeAscending.length - 1 && bytesToCut > 0;
|
|
498
|
+
i++
|
|
499
|
+
) {
|
|
500
|
+
const key = entriesByTimeAscending[i][0];
|
|
501
|
+
const thisSize = getByteSize(key) + getByteSize(newState[key]);
|
|
502
|
+
delete newState[key];
|
|
503
|
+
bytesToCut -= thisSize;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (needUpdate) {
|
|
508
|
+
this.queryState.setValue(newState);
|
|
509
|
+
this.log(
|
|
510
|
+
`Trimmed data for ${this.queryName}: size=(${oldSize} -> ${Object.keys(newState).length}) (limit=${this.maxSize}), byteSize=(${oldByteSize.toLocaleString()} -> ${getByteSize(newState).toLocaleString()}) (limit=${this.maxBytes.toLocaleString()})`
|
|
511
|
+
);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
this.log(
|
|
515
|
+
`No need to trim data for ${this.queryName}: size=${oldSize} (limit=${this.maxSize}), byteSize=${oldByteSize.toLocaleString()} (limit=${this.maxBytes.toLocaleString()})`
|
|
516
|
+
);
|
|
386
517
|
}
|
|
387
518
|
};
|
|
388
519
|
var seenQueryNames = /* @__PURE__ */ new Set();
|
|
@@ -393,74 +524,94 @@ function sharedQuery(options) {
|
|
|
393
524
|
seenQueryNames.add(options.queryName);
|
|
394
525
|
return new SharedQuery(options);
|
|
395
526
|
}
|
|
396
|
-
var DEFAULT_QUERY_STATE_ENTRY = {
|
|
527
|
+
var DEFAULT_QUERY_STATE_ENTRY = {
|
|
528
|
+
lastUpdatedMs: 0,
|
|
529
|
+
loading: true
|
|
530
|
+
};
|
|
397
531
|
function useSharedQuery(query, args = []) {
|
|
532
|
+
const stableArgs = useDeepMemo(args);
|
|
398
533
|
const [queryState, setQueryState] = useSharedState(query.queryState);
|
|
399
534
|
const isMounted = useRef(true);
|
|
400
|
-
const queryKey =
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
535
|
+
const queryKey = useMemo2(
|
|
536
|
+
() => query.getQueryKey(stableArgs),
|
|
537
|
+
[query, stableArgs]
|
|
538
|
+
);
|
|
539
|
+
const queryStateValue = queryState[queryKey];
|
|
540
|
+
const execute = useCallback(
|
|
541
|
+
async (forceRefresh) => {
|
|
542
|
+
query.log(`Begin executing shared query ${queryKey}`);
|
|
543
|
+
setQueryState((prev) => {
|
|
544
|
+
const clone = { ...prev };
|
|
545
|
+
clone[queryKey] = {
|
|
546
|
+
...clone[queryKey] ?? {},
|
|
547
|
+
lastUpdatedMs: Date.now(),
|
|
548
|
+
loading: true
|
|
549
|
+
};
|
|
550
|
+
return clone;
|
|
551
|
+
});
|
|
552
|
+
try {
|
|
553
|
+
const data = await (forceRefresh ? query.updateFromSource(...stableArgs) : query.getCachedOrFetch(...stableArgs));
|
|
554
|
+
if (isMounted.current) {
|
|
555
|
+
setQueryState((prev) => {
|
|
556
|
+
const clone = { ...prev };
|
|
557
|
+
const now = Date.now();
|
|
558
|
+
clone[queryKey] = {
|
|
559
|
+
// Don't keep old error.
|
|
560
|
+
lastUpdatedMs: now,
|
|
561
|
+
loading: false,
|
|
562
|
+
data,
|
|
563
|
+
dataUpdatedMs: now
|
|
564
|
+
};
|
|
565
|
+
return clone;
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
} catch (e) {
|
|
569
|
+
if (isMounted.current) {
|
|
570
|
+
setQueryState((prev) => {
|
|
571
|
+
const clone = { ...prev };
|
|
572
|
+
const now = Date.now();
|
|
573
|
+
clone[queryKey] = {
|
|
574
|
+
// Keep old data.
|
|
575
|
+
...clone[queryKey] ?? {},
|
|
576
|
+
lastUpdatedMs: now,
|
|
577
|
+
loading: false,
|
|
578
|
+
error: e,
|
|
579
|
+
errorUpdatedMs: now
|
|
580
|
+
};
|
|
581
|
+
return clone;
|
|
582
|
+
});
|
|
583
|
+
}
|
|
439
584
|
}
|
|
440
|
-
}
|
|
441
|
-
|
|
585
|
+
},
|
|
586
|
+
[query, queryKey, setQueryState, stableArgs]
|
|
587
|
+
);
|
|
442
588
|
useEffect(() => {
|
|
443
589
|
isMounted.current = true;
|
|
444
|
-
void execute();
|
|
590
|
+
void execute(false);
|
|
445
591
|
return () => {
|
|
446
592
|
isMounted.current = false;
|
|
447
593
|
};
|
|
448
594
|
}, [execute]);
|
|
449
|
-
return
|
|
450
|
-
const state =
|
|
595
|
+
return useMemo2(() => {
|
|
596
|
+
const state = queryStateValue ?? DEFAULT_QUERY_STATE_ENTRY;
|
|
451
597
|
return {
|
|
452
598
|
...state,
|
|
599
|
+
abortCurrentQuery: (reason) => {
|
|
600
|
+
const controller = query.getAbortController(queryKey);
|
|
601
|
+
controller?.abort(reason);
|
|
602
|
+
return Boolean(controller);
|
|
603
|
+
},
|
|
453
604
|
refetch: () => {
|
|
454
|
-
|
|
605
|
+
void execute(true);
|
|
455
606
|
},
|
|
456
607
|
setData: (data, dataUpdatedMs) => {
|
|
457
608
|
query.setData(queryKey, data, dataUpdatedMs ?? Date.now());
|
|
458
609
|
},
|
|
459
610
|
deleteData: () => {
|
|
460
|
-
query.deleteData(
|
|
611
|
+
query.deleteData(queryKey);
|
|
461
612
|
}
|
|
462
613
|
};
|
|
463
|
-
}, [query, queryKey,
|
|
614
|
+
}, [execute, query, queryKey, queryStateValue]);
|
|
464
615
|
}
|
|
465
616
|
export {
|
|
466
617
|
SharedQuery,
|