@nano_kit/query 1.0.0-alpha.0

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 (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/CacheStorage.d.ts +39 -0
  4. package/dist/CacheStorage.d.ts.map +1 -0
  5. package/dist/CacheStorage.types.d.ts +19 -0
  6. package/dist/CacheStorage.types.d.ts.map +1 -0
  7. package/dist/ClientContext.d.ts +80 -0
  8. package/dist/ClientContext.d.ts.map +1 -0
  9. package/dist/RequestContext.d.ts +44 -0
  10. package/dist/RequestContext.d.ts.map +1 -0
  11. package/dist/cache.d.ts +36 -0
  12. package/dist/cache.d.ts.map +1 -0
  13. package/dist/cache.types.d.ts +13 -0
  14. package/dist/cache.types.d.ts.map +1 -0
  15. package/dist/client.d.ts +41 -0
  16. package/dist/client.d.ts.map +1 -0
  17. package/dist/client.mock.d.ts +24 -0
  18. package/dist/client.mock.d.ts.map +1 -0
  19. package/dist/client.types.d.ts +12 -0
  20. package/dist/client.types.d.ts.map +1 -0
  21. package/dist/index.d.ts +7 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +951 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/map.d.ts +42 -0
  26. package/dist/map.d.ts.map +1 -0
  27. package/dist/queries/base.d.ts +17 -0
  28. package/dist/queries/base.d.ts.map +1 -0
  29. package/dist/queries/index.d.ts +5 -0
  30. package/dist/queries/index.d.ts.map +1 -0
  31. package/dist/queries/infinite.d.ts +44 -0
  32. package/dist/queries/infinite.d.ts.map +1 -0
  33. package/dist/queries/mutation.d.ts +29 -0
  34. package/dist/queries/mutation.d.ts.map +1 -0
  35. package/dist/queries/operation.d.ts +67 -0
  36. package/dist/queries/operation.d.ts.map +1 -0
  37. package/dist/queries/query.d.ts +35 -0
  38. package/dist/queries/query.d.ts.map +1 -0
  39. package/dist/settings/abortable.d.ts +24 -0
  40. package/dist/settings/abortable.d.ts.map +1 -0
  41. package/dist/settings/entities.d.ts +42 -0
  42. package/dist/settings/entities.d.ts.map +1 -0
  43. package/dist/settings/index.d.ts +8 -0
  44. package/dist/settings/index.d.ts.map +1 -0
  45. package/dist/settings/indexedDbStorage.d.ts +17 -0
  46. package/dist/settings/indexedDbStorage.d.ts.map +1 -0
  47. package/dist/settings/retryOnError.d.ts +11 -0
  48. package/dist/settings/retryOnError.d.ts.map +1 -0
  49. package/dist/settings/revalidateOnFocus.d.ts +12 -0
  50. package/dist/settings/revalidateOnFocus.d.ts.map +1 -0
  51. package/dist/settings/revalidateOnInterval.d.ts +9 -0
  52. package/dist/settings/revalidateOnInterval.d.ts.map +1 -0
  53. package/dist/settings/revalidateOnReconnect.d.ts +12 -0
  54. package/dist/settings/revalidateOnReconnect.d.ts.map +1 -0
  55. package/dist/utils.d.ts +3 -0
  56. package/dist/utils.d.ts.map +1 -0
  57. package/package.json +45 -0
package/dist/index.js ADDED
@@ -0,0 +1,951 @@
1
+ import { batch, setMapKey, fireMapEvent, $$insert, subMapEvent, $getMapKey, clearMap, deleteMapKey, untracked, external, onMount, mountable, listen, effect, taskPromise, computed, action, onStart, effectScope, signal, readonly } from '@nano_kit/store';
2
+
3
+ const abortControllers = /* @__PURE__ */ new WeakMap();
4
+ // @__NO_SIDE_EFFECTS__
5
+ function abortSignal(ctx) {
6
+ let controller = abortControllers.get(ctx);
7
+ if (!controller) {
8
+ abortControllers.set(ctx, controller = new AbortController());
9
+ }
10
+ return controller.signal;
11
+ }
12
+ function abort(promiseOrCtx) {
13
+ abortControllers.get(promiseOrCtx)?.abort();
14
+ }
15
+ function abortPrevious(ctx) {
16
+ abort(ctx.prevCtx);
17
+ }
18
+ // @__NO_SIDE_EFFECTS__
19
+ function abortable() {
20
+ return (ctx) => {
21
+ if (ctx.abortable === void 0) {
22
+ const superRun = ctx.run;
23
+ ctx.run = function(requestCtx, start, onSettled, interrupt) {
24
+ let abortController;
25
+ const promise = superRun.call(
26
+ this,
27
+ requestCtx,
28
+ start,
29
+ onSettled,
30
+ (error) => interrupt?.(error) || abortController?.signal.aborted === true
31
+ );
32
+ if (abortController = abortControllers.get(requestCtx)) {
33
+ abortControllers.set(promise, abortController);
34
+ void promise.finally(() => abortControllers.delete(promise));
35
+ }
36
+ return promise;
37
+ };
38
+ }
39
+ ctx.abortable = true;
40
+ };
41
+ }
42
+
43
+ // @__NO_SIDE_EFFECTS__
44
+ function queryKey(name, filter = (params) => params) {
45
+ const key = ((...params) => ({
46
+ shard: name,
47
+ key: JSON.stringify(filter(params))
48
+ }));
49
+ key.shard = name;
50
+ key.key = void 0;
51
+ return key;
52
+ }
53
+ // @__NO_SIDE_EFFECTS__
54
+ function operationKey(name, filter) {
55
+ return /* @__PURE__ */ queryKey(name, filter);
56
+ }
57
+ // @__NO_SIDE_EFFECTS__
58
+ function dataCacheFacade(cache) {
59
+ return dataCacheGetterSetter.bind(cache);
60
+ }
61
+ function dataCacheGetterSetter(key, ...value) {
62
+ if (value.length) {
63
+ const newValue = value[0];
64
+ this.set(key, (entry = this.initial()) => ({
65
+ ...entry,
66
+ data: typeof newValue === "function" ? newValue(entry.data) : newValue
67
+ }));
68
+ } else {
69
+ return this.$get(key).data;
70
+ }
71
+ }
72
+ // @__NO_SIDE_EFFECTS__
73
+ function loadingCacheFacade(cache) {
74
+ return (key) => cache.$get(key).loading;
75
+ }
76
+ // @__NO_SIDE_EFFECTS__
77
+ function errorCacheFacade(cache) {
78
+ return (key) => cache.$get(key).error;
79
+ }
80
+
81
+ const ENTITY_KEY = "#entity";
82
+ const EntityKey = queryKey(ENTITY_KEY);
83
+ function isIdentifier(value) {
84
+ const type = typeof value;
85
+ return type === "number" || type === "string";
86
+ }
87
+ function isEntityRef(value) {
88
+ return ENTITY_KEY in value;
89
+ }
90
+ let currentCtx = null;
91
+ // @__NO_SIDE_EFFECTS__
92
+ function entity(name, id = (entity2) => entity2.id) {
93
+ return (idOrRefOrEntity) => {
94
+ if (isIdentifier(idOrRefOrEntity)) {
95
+ return EntityKey(name, idOrRefOrEntity);
96
+ }
97
+ if (!idOrRefOrEntity || !currentCtx) {
98
+ return idOrRefOrEntity;
99
+ }
100
+ if (isEntityRef(idOrRefOrEntity)) {
101
+ return currentCtx.$get(idOrRefOrEntity[ENTITY_KEY]).data;
102
+ }
103
+ const key = EntityKey(name, id(idOrRefOrEntity));
104
+ currentCtx.set(key, {
105
+ ...currentCtx.initial(),
106
+ data: idOrRefOrEntity
107
+ });
108
+ return {
109
+ ...idOrRefOrEntity,
110
+ [ENTITY_KEY]: key
111
+ };
112
+ };
113
+ }
114
+ // @__NO_SIDE_EFFECTS__
115
+ function entities(mapper) {
116
+ return (ctx) => {
117
+ const safeMapper = (data) => {
118
+ if (data) {
119
+ try {
120
+ currentCtx = ctx;
121
+ return mapper(data);
122
+ } finally {
123
+ currentCtx = null;
124
+ }
125
+ }
126
+ return data;
127
+ };
128
+ ctx.mapComputedData = ctx.mapData = safeMapper;
129
+ };
130
+ }
131
+
132
+ // @__NO_SIDE_EFFECTS__
133
+ function hasShardedMapKey(map, shardedKey) {
134
+ const {
135
+ shard,
136
+ key
137
+ } = shardedKey;
138
+ if (key === void 0) {
139
+ return map.has(shard);
140
+ }
141
+ return map.get(shard)?.has(key) || false;
142
+ }
143
+ // @__NO_SIDE_EFFECTS__
144
+ function $getShardedMapKey(map, shardedKey) {
145
+ const {
146
+ shard,
147
+ key
148
+ } = shardedKey;
149
+ let shardMap;
150
+ if ((shardMap = map.get(shard)) === void 0) {
151
+ subMapEvent(map, $$insert);
152
+ return void 0;
153
+ }
154
+ return $getMapKey(shardMap, key);
155
+ }
156
+ function setShardedMapKey(map, shardedKey, value) {
157
+ const {
158
+ shard,
159
+ key
160
+ } = shardedKey;
161
+ let shardMap = map.get(shard);
162
+ const shardExists = shardMap !== void 0;
163
+ if (key === void 0) {
164
+ if (shardExists) {
165
+ batch(() => {
166
+ for (const params of shardMap.keys()) {
167
+ setMapKey(shardMap, params, value);
168
+ }
169
+ });
170
+ }
171
+ return;
172
+ }
173
+ if (!shardExists) {
174
+ map.set(
175
+ shard,
176
+ shardMap = /* @__PURE__ */ new Map()
177
+ );
178
+ }
179
+ setMapKey(shardMap, key, value);
180
+ if (!shardExists) {
181
+ fireMapEvent(map, $$insert);
182
+ }
183
+ }
184
+ function deleteShardedMapKey(map, shardedKey) {
185
+ const {
186
+ shard,
187
+ key
188
+ } = shardedKey;
189
+ const shardMap = map.get(shard);
190
+ if (shardMap === void 0) {
191
+ return;
192
+ }
193
+ if (key === void 0) {
194
+ clearMap(shardMap);
195
+ return;
196
+ }
197
+ deleteMapKey(shardMap, key);
198
+ }
199
+
200
+ const DEFAULT_DEDUPE_TIME = 4e3;
201
+ const DEFAULT_CACHE_TIME = Infinity;
202
+ const UNSET_REV = Infinity;
203
+ // @__NO_SIDE_EFFECTS__
204
+ function revLock(rev) {
205
+ return rev > 0 ? rev * -1 : rev;
206
+ }
207
+ // @__NO_SIDE_EFFECTS__
208
+ function revLocked(rev) {
209
+ return rev < 0;
210
+ }
211
+ let revCounter = 0;
212
+ class CacheStorage {
213
+ dedupeTime = DEFAULT_DEDUPE_TIME;
214
+ cacheTime = DEFAULT_CACHE_TIME;
215
+ cache = /* @__PURE__ */ new Map();
216
+ initial() {
217
+ return {
218
+ rev: UNSET_REV,
219
+ dedupes: 0,
220
+ expires: 0,
221
+ data: null,
222
+ error: null,
223
+ loading: false
224
+ };
225
+ }
226
+ $get(key) {
227
+ const cache = this.cache;
228
+ if (!hasShardedMapKey(cache, key)) {
229
+ setShardedMapKey(cache, key, this.initial());
230
+ }
231
+ const result = $getShardedMapKey(cache, key);
232
+ return result;
233
+ }
234
+ set(key, entry) {
235
+ setShardedMapKey(this.cache, key, entry);
236
+ }
237
+ /**
238
+ * Invalidate cache entry for the given key.
239
+ * If shard key is used, invalidate all entries in the shard.
240
+ * @param key - The cache key to invalidate.
241
+ */
242
+ invalidate(key) {
243
+ deleteShardedMapKey(this.cache, key);
244
+ }
245
+ /**
246
+ * Revalidate cache entry for the given key.
247
+ * If shard key is used, revalidate all entries in the shard.
248
+ * @param key - The cache key to revalidate.
249
+ */
250
+ revalidate(key) {
251
+ if (key.key === void 0 || hasShardedMapKey(this.cache, key)) {
252
+ this.set(key, (entry) => ({
253
+ ...entry,
254
+ rev: UNSET_REV,
255
+ dedupes: 0
256
+ }));
257
+ }
258
+ }
259
+ mute(entry, loadingDedupe = true, timeDedupe = true) {
260
+ return loadingDedupe && entry.loading || timeDedupe && entry.dedupes > Date.now() || /* @__PURE__ */ revLocked(entry.rev);
261
+ }
262
+ loading(key) {
263
+ const rev = ++revCounter;
264
+ this.set(key, (entry = this.initial()) => ({
265
+ ...entry,
266
+ rev,
267
+ data: entry.expires > Date.now() ? entry.data : null,
268
+ error: null,
269
+ loading: true
270
+ }));
271
+ return rev;
272
+ }
273
+ settled(key, data, error, rev) {
274
+ const now = Date.now();
275
+ this.set(key, (entry = this.initial()) => rev !== void 0 && rev !== entry.rev ? entry : {
276
+ ...entry,
277
+ dedupes: now + this.dedupeTime,
278
+ expires: now + this.cacheTime,
279
+ data: error === null ? data : entry.data,
280
+ error,
281
+ loading: false
282
+ });
283
+ }
284
+ }
285
+
286
+ const DB_NAME = "nano_kit";
287
+ const STORE_NAME = "query";
288
+ const DB_VERSION = 1;
289
+ function connect() {
290
+ return new Promise((resolve) => {
291
+ const request = indexedDB.open(DB_NAME, DB_VERSION);
292
+ request.onerror = () => resolve(null);
293
+ request.onsuccess = () => resolve(request.result);
294
+ request.onupgradeneeded = () => {
295
+ const db = request.result;
296
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
297
+ const store = db.createObjectStore(STORE_NAME, {
298
+ keyPath: ["shard", "key"]
299
+ });
300
+ store.createIndex("shard", "shard", {
301
+ unique: false
302
+ });
303
+ }
304
+ };
305
+ });
306
+ }
307
+ async function SELECT(connection, key) {
308
+ const db = await connection;
309
+ if (!db) {
310
+ return null;
311
+ }
312
+ return new Promise((resolve) => {
313
+ const transaction = db.transaction(STORE_NAME, "readonly");
314
+ const store = transaction.objectStore(STORE_NAME);
315
+ const request = store.get([key.shard, key.key]);
316
+ request.onerror = () => resolve(null);
317
+ request.onsuccess = () => {
318
+ const result = request.result;
319
+ if (!result) {
320
+ resolve(null);
321
+ return;
322
+ }
323
+ const now = Date.now();
324
+ if (result.expires < now || result.data.expires < now) {
325
+ void DELETE(connection, key);
326
+ resolve(null);
327
+ return;
328
+ }
329
+ resolve(result.data);
330
+ };
331
+ });
332
+ }
333
+ async function SET(connection, cacheKey, entry, lifetime) {
334
+ const db = await connection;
335
+ if (!db) {
336
+ return;
337
+ }
338
+ return new Promise((resolve) => {
339
+ const {
340
+ shard,
341
+ key
342
+ } = cacheKey;
343
+ const transaction = db.transaction(STORE_NAME, "readwrite");
344
+ const store = transaction.objectStore(STORE_NAME);
345
+ const storedEntry = {
346
+ shard,
347
+ key,
348
+ data: entry,
349
+ expires: Date.now() + lifetime
350
+ };
351
+ const request = store.put(storedEntry);
352
+ request.onerror = () => resolve();
353
+ request.onsuccess = () => resolve();
354
+ });
355
+ }
356
+ async function DELETE(connection, cacheKey) {
357
+ const db = await connection;
358
+ if (!db) {
359
+ return;
360
+ }
361
+ return new Promise((resolve) => {
362
+ const {
363
+ shard,
364
+ key
365
+ } = cacheKey;
366
+ const transaction = db.transaction(STORE_NAME, "readwrite");
367
+ const store = transaction.objectStore(STORE_NAME);
368
+ if (key === void 0) {
369
+ const index = store.index("shard");
370
+ const range = IDBKeyRange.only(shard);
371
+ const request = index.openCursor(range);
372
+ request.onerror = () => resolve();
373
+ request.onsuccess = () => {
374
+ const cursor = request.result;
375
+ if (cursor) {
376
+ cursor.delete();
377
+ cursor.continue();
378
+ } else {
379
+ resolve();
380
+ }
381
+ };
382
+ } else {
383
+ const request = store.delete([shard, key]);
384
+ request.onerror = () => resolve();
385
+ request.onsuccess = () => resolve();
386
+ }
387
+ });
388
+ }
389
+ // @__NO_SIDE_EFFECTS__
390
+ function indexedDbStorage(lifetime) {
391
+ return (ctx) => {
392
+ if (typeof indexedDB === "undefined") {
393
+ return;
394
+ }
395
+ if (ctx.indexedDbStorageLifetime === void 0) {
396
+ let saveSingleEntry = function(key) {
397
+ const entry = untracked(() => superGet.call(this, key));
398
+ if (entry && !entry.loading && !revLocked(entry.rev)) {
399
+ void this.task(SET(db, key, entry, this.indexedDbStorageLifetime));
400
+ }
401
+ };
402
+ const superGet = ctx.$get;
403
+ const superSet = ctx.set;
404
+ const superInvalidate = ctx.invalidate;
405
+ const db = connect();
406
+ ctx.$get = function(key) {
407
+ const cache = this.cache;
408
+ const hasKey = hasShardedMapKey(cache, key);
409
+ const entry = superGet.call(this, key);
410
+ if (hasKey) {
411
+ return entry;
412
+ }
413
+ superSet.call(this, key, {
414
+ ...entry,
415
+ rev: revLock(entry.rev)
416
+ });
417
+ void this.task(SELECT(db, key).then((storedEntry) => superSet.call(this, key, {
418
+ ...entry,
419
+ ...storedEntry,
420
+ rev: UNSET_REV
421
+ })));
422
+ return superGet.call(this, key);
423
+ };
424
+ ctx.set = function(cacheKey, entry) {
425
+ superSet.call(this, cacheKey, entry);
426
+ const {
427
+ shard,
428
+ key
429
+ } = cacheKey;
430
+ if (key !== void 0) {
431
+ saveSingleEntry.call(this, cacheKey);
432
+ } else {
433
+ const shardMap = this.cache.get(shard);
434
+ if (shardMap) {
435
+ for (const key2 of shardMap.keys()) {
436
+ saveSingleEntry.call(this, {
437
+ shard,
438
+ key: key2
439
+ });
440
+ }
441
+ }
442
+ }
443
+ };
444
+ ctx.invalidate = function(key) {
445
+ superInvalidate.call(this, key);
446
+ void this.task(DELETE(db, key));
447
+ };
448
+ }
449
+ ctx.indexedDbStorageLifetime = lifetime;
450
+ };
451
+ }
452
+
453
+ // @__NO_SIDE_EFFECTS__
454
+ function addFn(prevFn, fn) {
455
+ if (prevFn === void 0) {
456
+ return fn;
457
+ }
458
+ return function(...args) {
459
+ prevFn.apply(this, args);
460
+ fn.apply(this, args);
461
+ };
462
+ }
463
+ function settle(promise, onSettled) {
464
+ return promise.then(
465
+ onSettled,
466
+ (error) => onSettled(void 0, error)
467
+ );
468
+ }
469
+
470
+ const $windowVisible = external(($windowVisible2) => {
471
+ if (typeof document === "undefined") {
472
+ $windowVisible2(true);
473
+ return;
474
+ }
475
+ const set = () => $windowVisible2(!document.hidden);
476
+ set();
477
+ onMount(mountable($windowVisible2), () => {
478
+ document.addEventListener("visibilitychange", set);
479
+ return () => {
480
+ document.removeEventListener("visibilitychange", set);
481
+ };
482
+ });
483
+ });
484
+ // @__NO_SIDE_EFFECTS__
485
+ function revalidateOnFocus() {
486
+ return (ctx) => {
487
+ if (ctx.revalidateOnFocusEnabled === void 0) {
488
+ ctx.mounted = addFn(ctx.mounted, function() {
489
+ listen($windowVisible, (visible) => {
490
+ if (visible) {
491
+ this.revalidate(this.$key());
492
+ }
493
+ });
494
+ });
495
+ }
496
+ ctx.revalidateOnFocusEnabled = true;
497
+ };
498
+ }
499
+
500
+ // @__NO_SIDE_EFFECTS__
501
+ function revalidateOnInterval(interval) {
502
+ return (ctx) => {
503
+ if (ctx.revalidateInterval === void 0) {
504
+ ctx.mounted = addFn(ctx.mounted, function() {
505
+ effect(() => {
506
+ const id = setInterval(() => {
507
+ this.revalidate(this.$key());
508
+ }, this.revalidateInterval);
509
+ return () => clearInterval(id);
510
+ });
511
+ });
512
+ }
513
+ ctx.revalidateInterval = interval;
514
+ };
515
+ }
516
+
517
+ const $networkOnline = external(($networkOnline2) => {
518
+ if (typeof navigator === "undefined") {
519
+ $networkOnline2(true);
520
+ return;
521
+ }
522
+ const set = () => $networkOnline2(navigator.onLine);
523
+ set();
524
+ onMount(mountable($networkOnline2), () => {
525
+ window.addEventListener("online", set);
526
+ window.addEventListener("offline", set);
527
+ return () => {
528
+ window.removeEventListener("online", set);
529
+ window.removeEventListener("offline", set);
530
+ };
531
+ });
532
+ });
533
+ // @__NO_SIDE_EFFECTS__
534
+ function revalidateOnReconnect() {
535
+ return (ctx) => {
536
+ if (ctx.revalidateOnReconnectEnabled === void 0) {
537
+ ctx.mounted = addFn(ctx.mounted, function() {
538
+ listen($networkOnline, (online) => {
539
+ if (online) {
540
+ this.revalidate(this.$key());
541
+ }
542
+ });
543
+ });
544
+ }
545
+ ctx.revalidateOnReconnectEnabled = true;
546
+ };
547
+ }
548
+
549
+ // @__NO_SIDE_EFFECTS__
550
+ function defaultCalcRetryDelay(retryCount) {
551
+ return (
552
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
553
+ ~~((Math.random() + 0.5) * (1 << (retryCount < 8 ? retryCount : 8))) * 2e3
554
+ );
555
+ }
556
+ function getRetryCount(ctx, key) {
557
+ return ctx.retryCounts?.get(key.key) || 0;
558
+ }
559
+ function setRetryCount(ctx, key, count) {
560
+ (ctx.retryCounts ??= /* @__PURE__ */ new Map()).set(key.key, count);
561
+ }
562
+ function clearRetryCount(ctx, key) {
563
+ ctx.retryCounts?.delete(key.key);
564
+ }
565
+ // @__NO_SIDE_EFFECTS__
566
+ function retryOnError(calcRetryDelay = defaultCalcRetryDelay) {
567
+ return (ctx) => {
568
+ if (ctx.calcRetryDelay === void 0) {
569
+ const superRun = ctx.run;
570
+ ctx.run = function(queryCtx, start, onSettled, interrupt) {
571
+ clearTimeout(this.retryTimeoutId);
572
+ const promise = superRun.call(this, queryCtx, start, onSettled, interrupt);
573
+ if (!("shard" in queryCtx)) {
574
+ return promise;
575
+ }
576
+ void this.task(promise.then(
577
+ (result) => {
578
+ const error = result?.[1];
579
+ if (!error) {
580
+ clearRetryCount(this, queryCtx);
581
+ } else {
582
+ const retryCount = getRetryCount(this, queryCtx) + 1;
583
+ const delay = this.calcRetryDelay(retryCount, error);
584
+ this.retryTimeoutId = setTimeout(() => {
585
+ this.invalidate(queryCtx);
586
+ setRetryCount(this, queryCtx, retryCount);
587
+ }, delay);
588
+ }
589
+ }
590
+ ));
591
+ return promise;
592
+ };
593
+ }
594
+ ctx.calcRetryDelay = calcRetryDelay;
595
+ };
596
+ }
597
+
598
+ class ClientContext extends CacheStorage {
599
+ $key = void 0;
600
+ $disabled = void 0;
601
+ loadingDedupe = true;
602
+ timeDedupe = true;
603
+ onEveryError = void 0;
604
+ task(task) {
605
+ return taskPromise(task);
606
+ }
607
+ mapData(data) {
608
+ return data;
609
+ }
610
+ mapComputedData(data) {
611
+ return data;
612
+ }
613
+ mapError(error) {
614
+ return error?.message;
615
+ }
616
+ mounted() {
617
+ }
618
+ mute(entry) {
619
+ return this.$disabled?.() === true || super.mute(entry, this.loadingDedupe, this.timeDedupe);
620
+ }
621
+ run(requestCtx, start, onSettled, interrupt) {
622
+ const {
623
+ mapData,
624
+ mapError: mapError2
625
+ } = this;
626
+ return this.task(settle(start(), (data, error) => {
627
+ if (error && interrupt?.(error)) {
628
+ return;
629
+ }
630
+ const dataOrNull = error ? null : mapData(data);
631
+ const errorString = error ? mapError2(error) : null;
632
+ onSettled(dataOrNull, errorString);
633
+ requestCtx.settled(data, error);
634
+ this.handleError(error, requestCtx.stopErrorPropagation);
635
+ return [data, error];
636
+ }));
637
+ }
638
+ handleError(error, stopped) {
639
+ if (error !== void 0) {
640
+ this.onEveryError?.(error, stopped);
641
+ }
642
+ }
643
+ }
644
+ // @__NO_SIDE_EFFECTS__
645
+ function forkMutationClient(ctx, settings = []) {
646
+ const child = Object.create(ctx);
647
+ for (const setting of settings) {
648
+ setting(child);
649
+ }
650
+ return child;
651
+ }
652
+ // @__NO_SIDE_EFFECTS__
653
+ function forkQueryClient(ctx, $key, settings = []) {
654
+ const child = Object.create(ctx);
655
+ child.$key = $key;
656
+ for (const setting of settings) {
657
+ setting(child);
658
+ }
659
+ return child;
660
+ }
661
+ // @__NO_SIDE_EFFECTS__
662
+ function dedupeTime(time) {
663
+ return (ctx) => ctx.dedupeTime = time;
664
+ }
665
+ // @__NO_SIDE_EFFECTS__
666
+ function cacheTime(time) {
667
+ return (ctx) => ctx.cacheTime = time;
668
+ }
669
+ // @__NO_SIDE_EFFECTS__
670
+ function mapError(fn) {
671
+ return (ctx) => ctx.mapError = fn;
672
+ }
673
+ // @__NO_SIDE_EFFECTS__
674
+ function onEveryError(fn) {
675
+ return (ctx) => ctx.onEveryError = addFn(ctx.onEveryError, fn);
676
+ }
677
+ // @__NO_SIDE_EFFECTS__
678
+ function disabled($disabled) {
679
+ return (ctx) => ctx.$disabled = $disabled;
680
+ }
681
+ // @__NO_SIDE_EFFECTS__
682
+ function dedupe(loading, time = loading) {
683
+ return (ctx) => {
684
+ ctx.loadingDedupe = loading;
685
+ ctx.timeDedupe = time;
686
+ };
687
+ }
688
+ // @__NO_SIDE_EFFECTS__
689
+ function tasks(runner) {
690
+ return (ctx) => ctx.task = runner;
691
+ }
692
+
693
+ class RequestContext {
694
+ onSuccess = void 0;
695
+ onError = void 0;
696
+ onSettled = void 0;
697
+ stopErrorPropagation = false;
698
+ prevCtx = void 0;
699
+ constructor(prevCtx) {
700
+ if (this.prevCtx = prevCtx) {
701
+ prevCtx.prevCtx = void 0;
702
+ }
703
+ }
704
+ settled(data, error) {
705
+ this.onSettled?.(data, error);
706
+ if (error !== void 0) {
707
+ this.onError?.(error);
708
+ } else {
709
+ this.onSuccess?.(data);
710
+ }
711
+ }
712
+ }
713
+ class QueryContext extends RequestContext {
714
+ shard;
715
+ key;
716
+ P;
717
+ R;
718
+ constructor(key, prevCtx) {
719
+ super(prevCtx);
720
+ this.shard = key.shard;
721
+ this.key = key.key;
722
+ }
723
+ }
724
+ function onSuccess(ctx, fn) {
725
+ ctx.onSuccess = addFn(ctx.onSuccess, fn);
726
+ }
727
+ function onError(ctx, fn) {
728
+ ctx.onError = addFn(ctx.onError, fn);
729
+ }
730
+ function onSettled(ctx, fn) {
731
+ ctx.onSettled = addFn(ctx.onSettled, fn);
732
+ }
733
+ function stopErrorPropagation(ctx) {
734
+ ctx.stopErrorPropagation = true;
735
+ }
736
+
737
+ // @__NO_SIDE_EFFECTS__
738
+ function baseQuery(rootCtx, key, params, fn, settings) {
739
+ const $params = computed(() => params.map(($signal) => $signal()));
740
+ const $key = computed((prevKey) => {
741
+ const nextKey = key(...$params());
742
+ if (prevKey && prevKey.shard === nextKey.shard && prevKey.key === nextKey.key) {
743
+ return prevKey;
744
+ }
745
+ return nextKey;
746
+ });
747
+ const clientCtx = forkQueryClient(rootCtx, $key, settings);
748
+ const $entry = computed(() => clientCtx.$get($key()));
749
+ const $rev = computed((v = 0) => $entry().rev === UNSET_REV ? v + 1 : v);
750
+ const { mapComputedData } = clientCtx;
751
+ const $data = mountable(computed(() => mapComputedData($entry().data)));
752
+ const $error = computed(() => $entry().error);
753
+ const $loading = computed(() => $entry().loading);
754
+ let prevQueryCtx;
755
+ const fetch = action((...extraParams) => {
756
+ if (clientCtx.mute($entry())) {
757
+ return Promise.resolve();
758
+ }
759
+ const key2 = $key();
760
+ const params2 = $params();
761
+ const queryCtx = prevQueryCtx = new QueryContext(key2, prevQueryCtx);
762
+ let rev;
763
+ return clientCtx.run(
764
+ queryCtx,
765
+ () => {
766
+ rev = clientCtx.loading(key2);
767
+ return fn(...params2, ...extraParams, queryCtx);
768
+ },
769
+ (data, error) => clientCtx.settled(key2, data, error, rev)
770
+ );
771
+ });
772
+ return {
773
+ clientCtx,
774
+ fetch,
775
+ $params,
776
+ $key,
777
+ $rev,
778
+ $data,
779
+ $error,
780
+ $loading
781
+ };
782
+ }
783
+
784
+ // @__NO_SIDE_EFFECTS__
785
+ function query(key, params, fn, settings) {
786
+ const {
787
+ clientCtx,
788
+ fetch,
789
+ $params,
790
+ $key,
791
+ $rev,
792
+ $data,
793
+ $error,
794
+ $loading
795
+ } = baseQuery(this, key, params, fn, settings);
796
+ onStart($data, () => effectScope(() => {
797
+ effect(() => {
798
+ $rev();
799
+ $params();
800
+ clientCtx.$disabled?.();
801
+ void fetch();
802
+ });
803
+ clientCtx.mounted();
804
+ }));
805
+ return [$data, $error, $loading, $key];
806
+ }
807
+
808
+ // @__NO_SIDE_EFFECTS__
809
+ function infinite(key, params, next, fn, settings) {
810
+ const {
811
+ clientCtx,
812
+ fetch,
813
+ $params,
814
+ $key,
815
+ $rev,
816
+ $data,
817
+ $error,
818
+ $loading
819
+ } = baseQuery(this, key, params, async (...args) => {
820
+ const queryCtx = args[args.length - 1];
821
+ const data = clientCtx.$get(queryCtx).data;
822
+ const page = await fn(...args);
823
+ const nextValue = next(page);
824
+ return {
825
+ pages: [...data?.pages || [], page],
826
+ next: nextValue,
827
+ more: Boolean(nextValue)
828
+ };
829
+ }, settings);
830
+ const initialTimeDedupe = clientCtx.timeDedupe;
831
+ const fetchNext = action(() => {
832
+ const data = $data();
833
+ if (!data?.more) {
834
+ return Promise.resolve();
835
+ }
836
+ clientCtx.timeDedupe = false;
837
+ return fetch(data.next);
838
+ });
839
+ onStart($data, () => effectScope(() => {
840
+ effect(() => {
841
+ $rev();
842
+ $params();
843
+ clientCtx.$disabled?.();
844
+ clientCtx.timeDedupe = initialTimeDedupe;
845
+ void fetch(void 0);
846
+ });
847
+ clientCtx.mounted();
848
+ }));
849
+ return [fetchNext, $data, $error, $loading, $key];
850
+ }
851
+
852
+ // @__NO_SIDE_EFFECTS__
853
+ function operation(key, params, fn, settings = []) {
854
+ const {
855
+ clientCtx,
856
+ fetch,
857
+ $key,
858
+ $data,
859
+ $error,
860
+ $loading
861
+ } = baseQuery(this, key, params, fn, [dedupe(true, false), ...settings]);
862
+ onStart($data, () => effectScope(() => clientCtx.mounted()));
863
+ return [fetch, $data, $error, $loading, $key];
864
+ }
865
+
866
+ // @__NO_SIDE_EFFECTS__
867
+ function mutation(fn, settings = []) {
868
+ const clientCtx = forkMutationClient(this, settings);
869
+ const {
870
+ mapComputedData,
871
+ $disabled,
872
+ loadingDedupe
873
+ } = clientCtx;
874
+ const $result = signal(null);
875
+ const $data = computed(() => mapComputedData($result()));
876
+ const $error = signal(null);
877
+ const $loading = signal(false);
878
+ let prevRequestCtx;
879
+ const fetch = action((...params) => {
880
+ if ($disabled?.() === true || loadingDedupe && $loading()) {
881
+ return Promise.resolve();
882
+ }
883
+ const requestCtx = prevRequestCtx = new RequestContext(prevRequestCtx);
884
+ return clientCtx.run(
885
+ requestCtx,
886
+ () => {
887
+ $loading(true);
888
+ return fn(...params, requestCtx);
889
+ },
890
+ (data, error) => {
891
+ if (prevRequestCtx === requestCtx) {
892
+ batch(() => {
893
+ if (error === null) {
894
+ $result(data);
895
+ }
896
+ $error(error);
897
+ $loading(false);
898
+ });
899
+ }
900
+ }
901
+ );
902
+ });
903
+ return [
904
+ fetch,
905
+ $data,
906
+ readonly($error),
907
+ readonly($loading)
908
+ ];
909
+ }
910
+
911
+ // @__NO_SIDE_EFFECTS__
912
+ function client(...settings) {
913
+ const ctx = new ClientContext();
914
+ const client2 = {
915
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
916
+ query: query.bind(ctx),
917
+ invalidate: ((key) => ctx.invalidate(key)),
918
+ revalidate: ((key) => ctx.revalidate(key)),
919
+ $data: dataCacheFacade(ctx),
920
+ $error: errorCacheFacade(ctx),
921
+ $loading: loadingCacheFacade(ctx)
922
+ };
923
+ for (const setting of settings) {
924
+ setting(ctx, client2);
925
+ }
926
+ return client2;
927
+ }
928
+ // @__NO_SIDE_EFFECTS__
929
+ function infinites() {
930
+ return ((ctx, client2) => {
931
+ client2.infinite = infinite.bind(ctx);
932
+ return client2;
933
+ });
934
+ }
935
+ // @__NO_SIDE_EFFECTS__
936
+ function operations() {
937
+ return ((ctx, client2) => {
938
+ client2.operation = operation.bind(ctx);
939
+ return client2;
940
+ });
941
+ }
942
+ // @__NO_SIDE_EFFECTS__
943
+ function mutations() {
944
+ return ((ctx, client2) => {
945
+ client2.mutation = mutation.bind(ctx);
946
+ return client2;
947
+ });
948
+ }
949
+
950
+ export { $networkOnline, $windowVisible, ClientContext, DEFAULT_CACHE_TIME, DEFAULT_DEDUPE_TIME, QueryContext, RequestContext, abort, abortPrevious, abortSignal, abortable, cacheTime, client, dedupe, dedupeTime, defaultCalcRetryDelay, disabled, entities, entity, indexedDbStorage, infinites, mapError, mutations, onError, onEveryError, onSettled, onSuccess, operationKey, operations, queryKey, retryOnError, revalidateOnFocus, revalidateOnInterval, revalidateOnReconnect, stopErrorPropagation, tasks };
951
+ //# sourceMappingURL=index.js.map