@echojs-ecosystem/query 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,2140 @@
1
+ import { signal, effect, computed } from '@echojs-ecosystem/reactivity';
2
+
3
+ // src/provider/context.ts
4
+ var activeProvider = null;
5
+ var getQueryProvider = () => activeProvider;
6
+ var requireQueryProvider = () => {
7
+ if (!activeProvider) {
8
+ throw new Error(
9
+ "Query provider is not installed. Call app.use(createQueryProvider(...)) before using queries."
10
+ );
11
+ }
12
+ return activeProvider;
13
+ };
14
+ var setActiveQueryProvider = (provider) => {
15
+ activeProvider = provider;
16
+ };
17
+ var resetQueryProvider = () => {
18
+ activeProvider = null;
19
+ };
20
+
21
+ // src/client/default-client.ts
22
+ var defaultClient = null;
23
+ var pendingFactory = null;
24
+ var setDefaultQueryClient = (client) => {
25
+ defaultClient = client;
26
+ };
27
+ var registerDefaultQueryClientFactory = (factory) => {
28
+ pendingFactory = factory;
29
+ };
30
+ var getDefaultQueryClient = () => {
31
+ if (!defaultClient) {
32
+ if (!pendingFactory) {
33
+ throw new Error(
34
+ "@echojs-ecosystem/query: no default QueryClient. Call createQueryClient() first or pass { client } to .with()."
35
+ );
36
+ }
37
+ defaultClient = pendingFactory();
38
+ pendingFactory = null;
39
+ }
40
+ return defaultClient;
41
+ };
42
+
43
+ // src/core/cancelled-error.ts
44
+ var CancelledError = class extends Error {
45
+ revert;
46
+ silent;
47
+ constructor(options) {
48
+ super("CancelledError");
49
+ this.name = "CancelledError";
50
+ this.revert = options?.revert;
51
+ this.silent = options?.silent;
52
+ }
53
+ };
54
+ var isCancelledError = (value) => value instanceof CancelledError;
55
+ var isAbortError = (value) => {
56
+ if (isCancelledError(value)) return true;
57
+ if (!value || typeof value !== "object") return false;
58
+ if (value instanceof DOMException && value.name === "AbortError") return true;
59
+ return value.name === "AbortError";
60
+ };
61
+
62
+ // src/core/removable.ts
63
+ var Removable = class {
64
+ gcTimeoutId;
65
+ gcTimeMs = Number.POSITIVE_INFINITY;
66
+ scheduleGc(onRemove) {
67
+ this.clearGcTimeout();
68
+ if (!Number.isFinite(this.gcTimeMs)) return;
69
+ this.gcTimeoutId = setTimeout(() => {
70
+ onRemove();
71
+ }, this.gcTimeMs);
72
+ }
73
+ clearGcTimeout() {
74
+ if (this.gcTimeoutId !== void 0) {
75
+ clearTimeout(this.gcTimeoutId);
76
+ this.gcTimeoutId = void 0;
77
+ }
78
+ }
79
+ updateGcTime(cacheTimeMs) {
80
+ this.gcTimeMs = cacheTimeMs;
81
+ }
82
+ };
83
+
84
+ // src/utils/sleep.ts
85
+ var sleep = (ms) => new Promise((resolve) => {
86
+ setTimeout(resolve, ms);
87
+ });
88
+
89
+ // src/core/retryer.ts
90
+ var defaultRetryDelay = (failureCount) => Math.min(1e3 * 2 ** failureCount, 3e4);
91
+ var shouldRetry = (failureCount, error, retry) => {
92
+ if (retry === false || retry === void 0) return false;
93
+ if (typeof retry === "number") return failureCount < retry;
94
+ if (retry === true) return true;
95
+ return retry(failureCount, error);
96
+ };
97
+ var getRetryDelay = (failureCount, error, retryDelay) => {
98
+ if (typeof retryDelay === "function") return retryDelay(failureCount, error);
99
+ if (typeof retryDelay === "number") return retryDelay;
100
+ return defaultRetryDelay(failureCount);
101
+ };
102
+ var createRetryer = (config) => {
103
+ let failureCount = 0;
104
+ let rejectFn;
105
+ let resolveFn;
106
+ let settled = false;
107
+ const promise = new Promise((resolve, reject) => {
108
+ resolveFn = resolve;
109
+ rejectFn = reject;
110
+ });
111
+ const cancel = (options) => {
112
+ if (settled) return;
113
+ const error = new CancelledError({ silent: options?.silent });
114
+ config.onCancel?.(error);
115
+ settled = true;
116
+ rejectFn(error);
117
+ };
118
+ const run = () => {
119
+ if (settled) return;
120
+ const initialPromise = failureCount === 0 ? config.initialPromise : void 0;
121
+ Promise.resolve(initialPromise ?? config.fn()).then((value) => {
122
+ if (settled) return;
123
+ settled = true;
124
+ resolveFn(value);
125
+ }).catch(async (error) => {
126
+ if (settled) return;
127
+ if (isCancelledError(error) || isAbortError(error)) {
128
+ settled = true;
129
+ rejectFn(error);
130
+ return;
131
+ }
132
+ if (shouldRetry(failureCount, error, config.retry)) {
133
+ failureCount += 1;
134
+ config.onFail?.(failureCount, error);
135
+ await sleep(getRetryDelay(failureCount, error, config.retryDelay));
136
+ if (!settled) run();
137
+ return;
138
+ }
139
+ settled = true;
140
+ rejectFn(error);
141
+ });
142
+ };
143
+ return {
144
+ promise,
145
+ cancel,
146
+ start: () => {
147
+ run();
148
+ return promise;
149
+ }
150
+ };
151
+ };
152
+
153
+ // src/core/query-state.ts
154
+ var defaultQueryState = () => ({
155
+ data: void 0,
156
+ error: null,
157
+ status: "idle",
158
+ fetchStatus: "idle",
159
+ dataUpdatedAt: 0,
160
+ errorUpdatedAt: 0,
161
+ fetchFailureCount: 0,
162
+ isInvalidated: false,
163
+ hadSuccess: false
164
+ });
165
+ var queryReducer = (state, action) => {
166
+ switch (action.type) {
167
+ case "fetch":
168
+ return {
169
+ ...state,
170
+ fetchStatus: "fetching",
171
+ ...state.data === void 0 && state.status === "idle" ? { status: "pending", error: null } : {}
172
+ };
173
+ case "success":
174
+ return {
175
+ ...state,
176
+ data: action.data,
177
+ error: null,
178
+ status: "success",
179
+ fetchStatus: "idle",
180
+ dataUpdatedAt: Date.now(),
181
+ fetchFailureCount: 0,
182
+ isInvalidated: false,
183
+ hadSuccess: true
184
+ };
185
+ case "error":
186
+ return {
187
+ ...state,
188
+ error: action.error,
189
+ status: "error",
190
+ fetchStatus: "idle",
191
+ errorUpdatedAt: Date.now(),
192
+ fetchFailureCount: state.fetchFailureCount + 1,
193
+ isInvalidated: true
194
+ };
195
+ case "failed":
196
+ return {
197
+ ...state,
198
+ fetchFailureCount: action.failureCount,
199
+ error: action.error
200
+ };
201
+ case "invalidate":
202
+ return {
203
+ ...state,
204
+ isInvalidated: true
205
+ };
206
+ case "setState":
207
+ return {
208
+ ...state,
209
+ ...action.state
210
+ };
211
+ default:
212
+ return state;
213
+ }
214
+ };
215
+ var timeUntilStale = (updatedAt, staleTimeMs = 0) => Math.max(updatedAt + staleTimeMs - Date.now(), 0);
216
+ var isStaleByTime = (dataUpdatedAt, staleTimeMs, isInvalidated, hasData) => {
217
+ if (!hasData) return true;
218
+ if (isInvalidated) return true;
219
+ if (!Number.isFinite(staleTimeMs)) return false;
220
+ return timeUntilStale(dataUpdatedAt, staleTimeMs) === 0;
221
+ };
222
+
223
+ // src/async/lifecycle.ts
224
+ var runLifecycle = async (hooks, phase, ctx) => {
225
+ if (phase === "start") hooks.onStart?.(ctx);
226
+ if (phase === "success") hooks.onSuccess?.(ctx);
227
+ if (phase === "error") hooks.onError?.(ctx);
228
+ if (phase === "settled") hooks.onSettled?.(ctx);
229
+ };
230
+
231
+ // src/async/abort-control.ts
232
+ var resolveAbortInput = (input) => {
233
+ if (!input) return void 0;
234
+ if (typeof input === "function") return input();
235
+ return input;
236
+ };
237
+ var abortWithReason = (controller, reason) => {
238
+ if (!controller || controller.signal.aborted) return;
239
+ try {
240
+ controller.abort(reason);
241
+ } catch {
242
+ controller.abort();
243
+ }
244
+ };
245
+ var linkSignal = (source, target) => {
246
+ if (source.aborted) {
247
+ abortWithReason(target, source.reason);
248
+ return () => {
249
+ };
250
+ }
251
+ const listener = () => abortWithReason(target, source.reason);
252
+ source.addEventListener("abort", listener, { once: true });
253
+ return () => source.removeEventListener("abort", listener);
254
+ };
255
+ var mergeFetchAbortSource = (...sources) => {
256
+ let abortController;
257
+ let signal8;
258
+ for (const source of sources) {
259
+ if (!source) continue;
260
+ if (source.abortController !== void 0) abortController = source.abortController;
261
+ if (source.signal !== void 0) signal8 = source.signal;
262
+ }
263
+ return { abortController, signal: signal8 };
264
+ };
265
+ var createFetchAbortHandle = (source) => {
266
+ const controllerInput = resolveAbortInput(source?.abortController);
267
+ const signalInput = resolveAbortInput(source?.signal);
268
+ const unlinks = [];
269
+ let controller;
270
+ let ownsController;
271
+ if (controllerInput instanceof AbortController) {
272
+ controller = controllerInput;
273
+ ownsController = false;
274
+ } else if (controllerInput instanceof AbortSignal) {
275
+ controller = new AbortController();
276
+ ownsController = true;
277
+ unlinks.push(linkSignal(controllerInput, controller));
278
+ } else {
279
+ controller = new AbortController();
280
+ ownsController = true;
281
+ }
282
+ if (signalInput) {
283
+ const external = signalInput instanceof AbortSignal ? signalInput : signalInput.signal;
284
+ if (external !== controller.signal) {
285
+ unlinks.push(linkSignal(external, controller));
286
+ }
287
+ }
288
+ return {
289
+ controller,
290
+ signal: controller.signal,
291
+ ownsController,
292
+ abort: (reason) => abortWithReason(controller, reason),
293
+ dispose: () => {
294
+ for (const unlink of unlinks) unlink();
295
+ }
296
+ };
297
+ };
298
+
299
+ // src/utils/hash.ts
300
+ var hasObjectPrototype = (value) => Object.prototype.toString.call(value) === "[object Object]";
301
+ var isPlainObject = (value) => {
302
+ if (!hasObjectPrototype(value)) return false;
303
+ const record = value;
304
+ const ctor = record.constructor;
305
+ if (ctor === void 0) return true;
306
+ const prot = ctor.prototype;
307
+ if (!hasObjectPrototype(prot)) return false;
308
+ if (!Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf")) return false;
309
+ if (Object.getPrototypeOf(value) !== Object.prototype) return false;
310
+ return true;
311
+ };
312
+ var hashKey = (queryKey) => JSON.stringify(
313
+ queryKey,
314
+ (_, val) => isPlainObject(val) ? Object.keys(val).sort().reduce((result, key) => {
315
+ result[key] = val[key];
316
+ return result;
317
+ }, {}) : val
318
+ );
319
+ var partialMatchKey = (a, b) => {
320
+ if (a === b) return true;
321
+ if (typeof a !== typeof b) return false;
322
+ if (a && b && typeof a === "object" && typeof b === "object") {
323
+ const bRecord = b;
324
+ const aRecord = a;
325
+ return Object.keys(bRecord).every(
326
+ (key) => partialMatchKey(aRecord[key], bRecord[key])
327
+ );
328
+ }
329
+ return false;
330
+ };
331
+
332
+ // src/utils/functional-update.ts
333
+ var functionalUpdate = (updater, input) => typeof updater === "function" ? updater(input) : updater;
334
+
335
+ // src/core/query.ts
336
+ var Query = class extends Removable {
337
+ queryKey;
338
+ queryHash;
339
+ definition;
340
+ client;
341
+ params;
342
+ options;
343
+ state;
344
+ observers = /* @__PURE__ */ new Set();
345
+ $data;
346
+ $error;
347
+ $status;
348
+ $fetchStatus;
349
+ $pendingCount;
350
+ $updatedAt;
351
+ $isInvalidated;
352
+ #retryer;
353
+ #abortController;
354
+ #abortDispose;
355
+ #cache;
356
+ constructor(config) {
357
+ super();
358
+ this.client = config.client;
359
+ this.#cache = config.cache;
360
+ this.definition = config.definition;
361
+ this.params = config.params;
362
+ this.queryKey = config.queryKey;
363
+ this.queryHash = hashKey(config.queryKey);
364
+ this.options = config.options;
365
+ this.state = defaultQueryState();
366
+ this.updateGcTime(this.options.cacheTimeMs);
367
+ this.$data = signal(void 0);
368
+ this.$error = signal(null);
369
+ this.$status = signal("idle");
370
+ this.$fetchStatus = signal("idle");
371
+ this.$pendingCount = signal(0);
372
+ this.$updatedAt = signal(null);
373
+ this.$isInvalidated = signal(false);
374
+ }
375
+ get promise() {
376
+ return this.#retryer?.promise;
377
+ }
378
+ isActive() {
379
+ return this.observers.size > 0;
380
+ }
381
+ isStale() {
382
+ return isStaleByTime(
383
+ this.state.dataUpdatedAt,
384
+ this.options.staleTimeMs,
385
+ this.state.isInvalidated,
386
+ this.state.data !== void 0
387
+ );
388
+ }
389
+ isStaleByTime(staleTimeMs = this.options.staleTimeMs) {
390
+ return isStaleByTime(
391
+ this.state.dataUpdatedAt,
392
+ staleTimeMs,
393
+ this.state.isInvalidated,
394
+ this.state.data !== void 0
395
+ );
396
+ }
397
+ hasData() {
398
+ return this.state.data !== void 0;
399
+ }
400
+ addObserver(observer) {
401
+ if (!this.observers.has(observer)) {
402
+ this.observers.add(observer);
403
+ this.clearGcTimeout();
404
+ }
405
+ }
406
+ removeObserver(observer) {
407
+ if (this.observers.delete(observer) && this.observers.size === 0) {
408
+ this.scheduleGc(() => this.#cache.remove(this));
409
+ }
410
+ }
411
+ setData(updater) {
412
+ const next = functionalUpdate(updater, this.state.data);
413
+ this.#dispatch({ type: "success", data: next });
414
+ return next;
415
+ }
416
+ invalidate() {
417
+ if (!this.state.isInvalidated) {
418
+ this.#dispatch({ type: "invalidate" });
419
+ this.#cache.emit({
420
+ type: "queryInvalidated",
421
+ queryKey: this.queryKey,
422
+ hash: this.queryHash
423
+ });
424
+ }
425
+ }
426
+ getAbortController() {
427
+ return this.#abortController;
428
+ }
429
+ getAbortSignal() {
430
+ return this.#abortController?.signal;
431
+ }
432
+ cancel(options) {
433
+ abortWithReason(this.#abortController, options?.reason);
434
+ const promise = this.#retryer?.promise;
435
+ if (promise) {
436
+ void promise.catch(() => void 0);
437
+ }
438
+ this.#retryer?.cancel(options);
439
+ this.#retryer = void 0;
440
+ this.#clearAbortHandle();
441
+ this.#dispatch({ type: "setState", state: { fetchStatus: "idle" } });
442
+ return promise ? promise.then(() => void 0).catch(() => void 0) : Promise.resolve();
443
+ }
444
+ async fetch(options) {
445
+ if (this.state.fetchStatus !== "idle" && this.#retryer) {
446
+ if (options?.cancelRefetch) {
447
+ await this.cancel({ silent: true });
448
+ } else {
449
+ return this.#retryer.promise;
450
+ }
451
+ }
452
+ const abortHandle = createFetchAbortHandle(
453
+ mergeFetchAbortSource(this.options, options)
454
+ );
455
+ this.#abortController = abortHandle.controller;
456
+ this.#abortDispose = abortHandle.dispose;
457
+ const { controller: abortController, signal: signal8 } = abortHandle;
458
+ const lifecycleCtx = {
459
+ params: this.params,
460
+ queryKey: this.queryKey,
461
+ queryClient: this.client
462
+ };
463
+ this.#dispatch({ type: "fetch" });
464
+ this.$pendingCount.set(this.$pendingCount.peek() + 1);
465
+ void runLifecycle(this.options, "start", lifecycleCtx);
466
+ this.#retryer = createRetryer({
467
+ fn: async () => {
468
+ const raw = await this.definition.options.queryFn({
469
+ params: this.params,
470
+ signal: signal8,
471
+ abortController,
472
+ queryClient: this.client,
473
+ queryKey: this.queryKey
474
+ });
475
+ if (signal8.aborted) {
476
+ throw new CancelledError({ silent: true });
477
+ }
478
+ const transform = this.definition.options.transform;
479
+ return transform ? await transform(raw) : raw;
480
+ },
481
+ onCancel: () => abortHandle.abort(),
482
+ onFail: (failureCount, error) => {
483
+ const err = error instanceof Error ? error : new Error(String(error));
484
+ this.#dispatch({
485
+ type: "failed",
486
+ failureCount,
487
+ error: err
488
+ });
489
+ },
490
+ retry: this.options.retry,
491
+ retryDelay: this.options.retryDelay
492
+ });
493
+ try {
494
+ const data = await this.#retryer.start();
495
+ this.#dispatch({ type: "success", data });
496
+ this.#cache.emit({
497
+ type: "queryFetched",
498
+ queryKey: this.queryKey,
499
+ hash: this.queryHash,
500
+ data
501
+ });
502
+ await runLifecycle(this.options, "success", { ...lifecycleCtx, data });
503
+ await runLifecycle(this.options, "settled", { ...lifecycleCtx, data });
504
+ return data;
505
+ } catch (error) {
506
+ if (isCancelledError(error)) {
507
+ if (error.silent) {
508
+ return this.state.data;
509
+ }
510
+ throw error;
511
+ }
512
+ const err = error instanceof Error ? error : new Error(String(error));
513
+ this.#dispatch({ type: "error", error: err });
514
+ await runLifecycle(this.options, "error", { ...lifecycleCtx, error: err });
515
+ await runLifecycle(this.options, "settled", { ...lifecycleCtx, error: err });
516
+ throw error;
517
+ } finally {
518
+ this.$pendingCount.set(Math.max(0, this.$pendingCount.peek() - 1));
519
+ this.#retryer = void 0;
520
+ this.#clearAbortHandle();
521
+ this.scheduleGc(() => {
522
+ if (this.observers.size === 0) this.#cache.remove(this);
523
+ });
524
+ }
525
+ }
526
+ #clearAbortHandle() {
527
+ this.#abortDispose?.();
528
+ this.#abortDispose = void 0;
529
+ this.#abortController = void 0;
530
+ }
531
+ onFocus() {
532
+ if (this.isActive() && this.isStale() && this.options.refetchOnWindowFocus) {
533
+ void this.fetch();
534
+ }
535
+ }
536
+ onOnline() {
537
+ if (this.isActive() && this.isStale() && this.options.refetchOnReconnect) {
538
+ void this.fetch();
539
+ }
540
+ }
541
+ #dispatch(action) {
542
+ this.state = queryReducer(this.state, action);
543
+ this.syncSignals();
544
+ this.#cache.emit({
545
+ type: "queryUpdated",
546
+ queryKey: this.queryKey,
547
+ hash: this.queryHash
548
+ });
549
+ for (const observer of this.observers) {
550
+ observer.onQueryUpdate();
551
+ }
552
+ }
553
+ syncSignals() {
554
+ this.$data.set(this.state.data);
555
+ this.$error.set(this.state.error);
556
+ this.$status.set(this.state.status);
557
+ this.$fetchStatus.set(this.state.fetchStatus);
558
+ this.$updatedAt.set(this.state.dataUpdatedAt || null);
559
+ this.$isInvalidated.set(this.state.isInvalidated);
560
+ }
561
+ };
562
+
563
+ // src/query/query-options.ts
564
+ var DEFAULT_CACHE_TIME_MS = 5 * 6e4;
565
+ var defaultQueryOptions = (config) => ({
566
+ staleTime: config?.defaultOptions?.queries?.staleTime ?? 0,
567
+ cacheTime: config?.defaultOptions?.queries?.cacheTime ?? DEFAULT_CACHE_TIME_MS,
568
+ retry: config?.defaultOptions?.queries?.retry ?? false,
569
+ retryDelay: config?.defaultOptions?.queries?.retryDelay ?? 1e3,
570
+ keepPreviousData: config?.defaultOptions?.queries?.keepPreviousData ?? false,
571
+ abortPrevious: config?.defaultOptions?.queries?.abortPrevious ?? true
572
+ });
573
+ var mergeQueryDefinitionOptions = (options, config, provider) => ({
574
+ ...defaultQueryOptions(config),
575
+ ...provider?.config.defaultOptions?.queries,
576
+ ...options
577
+ });
578
+ var toMs = (value, fallback) => {
579
+ if (value === void 0) return fallback;
580
+ if (!Number.isFinite(value)) return Number.POSITIVE_INFINITY;
581
+ return value;
582
+ };
583
+
584
+ // src/query/query-status.ts
585
+ var DEFAULT_CACHE_TIME_MS2 = 5 * 6e4;
586
+ var resolveQueryOptions = (options) => {
587
+ const staleTime = options.staleTime ?? 0;
588
+ const cacheTime = options.cacheTime ?? DEFAULT_CACHE_TIME_MS2;
589
+ return {
590
+ ...options,
591
+ staleTime,
592
+ cacheTime,
593
+ retry: options.retry ?? false,
594
+ retryDelay: options.retryDelay ?? 1e3,
595
+ keepPreviousData: options.keepPreviousData ?? false,
596
+ abortPrevious: options.abortPrevious ?? true,
597
+ staleTimeMs: toMs(staleTime, 0),
598
+ cacheTimeMs: toMs(cacheTime, DEFAULT_CACHE_TIME_MS2)
599
+ };
600
+ };
601
+ var resolveInstanceOptions = (definitionOptions, instanceOptions) => {
602
+ const staleTime = instanceOptions?.staleTime ?? definitionOptions.staleTime ?? 0;
603
+ const cacheTime = instanceOptions?.cacheTime ?? definitionOptions.cacheTime ?? DEFAULT_CACHE_TIME_MS2;
604
+ return {
605
+ ...definitionOptions,
606
+ ...instanceOptions,
607
+ staleTime,
608
+ cacheTime,
609
+ staleTimeMs: toMs(staleTime, 0),
610
+ cacheTimeMs: toMs(cacheTime, DEFAULT_CACHE_TIME_MS2),
611
+ enabled: instanceOptions?.enabled ?? true,
612
+ refetchOnMount: instanceOptions?.refetchOnMount ?? true,
613
+ refetchOnWindowFocus: instanceOptions?.refetchOnWindowFocus ?? true,
614
+ refetchOnReconnect: instanceOptions?.refetchOnReconnect ?? true,
615
+ keepPreviousData: instanceOptions?.keepPreviousData ?? definitionOptions.keepPreviousData ?? false,
616
+ abortPrevious: instanceOptions?.abortPrevious ?? definitionOptions.abortPrevious ?? true,
617
+ retry: instanceOptions?.retry ?? definitionOptions.retry ?? false,
618
+ retryDelay: instanceOptions?.retryDelay ?? definitionOptions.retryDelay ?? 1e3,
619
+ onStart: instanceOptions?.onStart ?? definitionOptions.onStart,
620
+ onSuccess: instanceOptions?.onSuccess ?? definitionOptions.onSuccess,
621
+ onError: instanceOptions?.onError ?? definitionOptions.onError,
622
+ onSettled: instanceOptions?.onSettled ?? definitionOptions.onSettled
623
+ };
624
+ };
625
+ var isEnabled = (enabled) => typeof enabled === "function" ? enabled() : enabled;
626
+ var isQueryPending = (status) => status === "pending";
627
+ var isQueryFetching = (fetchStatus) => fetchStatus === "fetching";
628
+ var isQuerySuccess = (status) => status === "success";
629
+ var isQueryError = (status) => status === "error";
630
+ var isQueryIdle = (status) => status === "idle";
631
+ var isQueryPaused = (fetchStatus) => fetchStatus === "paused";
632
+ var resolveDefinitionOptions = (definition) => resolveQueryOptions(definition.options);
633
+
634
+ // src/query/query-observer.ts
635
+ var QueryObserver = class {
636
+ definition;
637
+ client;
638
+ options;
639
+ #query = null;
640
+ #previousQuery = null;
641
+ #params;
642
+ #disposeParams = null;
643
+ #destroyed = false;
644
+ #listeners = /* @__PURE__ */ new Set();
645
+ #currentHash = null;
646
+ constructor(definition, client, params, instanceOptions) {
647
+ this.definition = definition;
648
+ this.client = client;
649
+ this.options = resolveInstanceOptions(
650
+ resolveDefinitionOptions(definition),
651
+ instanceOptions
652
+ );
653
+ if (typeof params === "function") {
654
+ this.#disposeParams = effect(() => {
655
+ this.setParams(params());
656
+ });
657
+ } else {
658
+ this.setParams(params);
659
+ }
660
+ }
661
+ getQuery() {
662
+ return this.#query;
663
+ }
664
+ getPreviousQuery() {
665
+ return this.#previousQuery;
666
+ }
667
+ getParams() {
668
+ return this.#params;
669
+ }
670
+ onQueryUpdate() {
671
+ for (const listener of this.#listeners) listener();
672
+ }
673
+ subscribe(listener) {
674
+ this.#listeners.add(listener);
675
+ return () => this.#listeners.delete(listener);
676
+ }
677
+ setParams(params) {
678
+ if (this.#destroyed) return;
679
+ this.#params = params;
680
+ const queryKey = this.definition.queryKey(params);
681
+ const hash = hashKey(queryKey);
682
+ if (this.#currentHash === hash) {
683
+ void this.maybeFetch(false);
684
+ return;
685
+ }
686
+ if (this.#query) {
687
+ if (this.options.abortPrevious) {
688
+ void this.#query.cancel({ silent: true });
689
+ }
690
+ this.#detach(this.#query);
691
+ this.#previousQuery = this.options.keepPreviousData ? this.#query : null;
692
+ }
693
+ this.#currentHash = hash;
694
+ this.#query = this.client.queryCache.build({
695
+ client: this.client,
696
+ cache: this.client.queryCache,
697
+ definition: this.definition,
698
+ params,
699
+ queryKey,
700
+ options: this.options
701
+ });
702
+ this.#query.addObserver(this);
703
+ void this.maybeFetch(true);
704
+ this.onQueryUpdate();
705
+ }
706
+ maybeFetch(paramsChanged) {
707
+ if (!this.#query || !isEnabled(this.options.enabled)) return;
708
+ const stale = this.#query.isStale();
709
+ const hasData = this.#query.hasData();
710
+ if (!hasData || stale) {
711
+ void this.fetch();
712
+ return;
713
+ }
714
+ if (paramsChanged && this.options.refetchOnMount === true) {
715
+ void this.fetch();
716
+ }
717
+ }
718
+ async fetch(options) {
719
+ if (!this.#query) throw new Error("QueryObserver has no active query");
720
+ try {
721
+ return await this.#query.fetch(options);
722
+ } catch (error) {
723
+ if (isCancelledError(error) && !options?.throwOnError) {
724
+ throw error;
725
+ }
726
+ if (options?.throwOnError) throw error;
727
+ throw error;
728
+ }
729
+ }
730
+ async refetch(options) {
731
+ return this.fetch(options);
732
+ }
733
+ invalidate() {
734
+ this.#query?.invalidate();
735
+ if (this.#query?.isActive()) {
736
+ void this.fetch();
737
+ }
738
+ }
739
+ cancel(options) {
740
+ return this.#query?.cancel(options) ?? Promise.resolve();
741
+ }
742
+ remove() {
743
+ if (!this.#query) return;
744
+ this.#detach(this.#query);
745
+ this.client.queryCache.remove(this.#query);
746
+ this.#query = null;
747
+ this.#currentHash = null;
748
+ this.onQueryUpdate();
749
+ }
750
+ destroy() {
751
+ if (this.#destroyed) return;
752
+ this.#destroyed = true;
753
+ this.#disposeParams?.();
754
+ if (this.#query) this.#detach(this.#query);
755
+ this.#listeners.clear();
756
+ }
757
+ #detach(query) {
758
+ query.removeObserver(this);
759
+ }
760
+ };
761
+
762
+ // src/query/query-instance.ts
763
+ var effectiveQuery = (observer) => {
764
+ const query = observer.getQuery();
765
+ if (!query) return observer.getPreviousQuery();
766
+ if (query.hasData()) return query;
767
+ const prev = observer.getPreviousQuery();
768
+ if (prev && observer.options.keepPreviousData) return prev;
769
+ return query;
770
+ };
771
+ var createQueryInstance = (definition, client, params, instanceOptions) => {
772
+ const observer = new QueryObserver(definition, client, params, instanceOptions);
773
+ const $params = signal(observer.getParams());
774
+ observer.subscribe(() => $params.set(observer.getParams()));
775
+ const readQuery = () => effectiveQuery(observer);
776
+ const $data = computed(() => readQuery()?.$data.value());
777
+ const $error = computed(() => readQuery()?.$error.value() ?? null);
778
+ const $status = computed(() => readQuery()?.$status.value() ?? "idle");
779
+ const $fetchStatus = computed(() => observer.getQuery()?.$fetchStatus.value() ?? "idle");
780
+ const $pendingCount = computed(() => observer.getQuery()?.$pendingCount.value() ?? 0);
781
+ const $updatedAt = computed(() => observer.getQuery()?.$updatedAt.value() ?? null);
782
+ const $isStale = computed(() => observer.getQuery()?.isStale() ?? true);
783
+ const $abortSignal = computed(() => readQuery()?.getAbortSignal() ?? null);
784
+ return {
785
+ kind: "query-instance",
786
+ value: () => $data.value(),
787
+ data: () => $data.value(),
788
+ error: () => $error.value(),
789
+ params: () => $params.value(),
790
+ status: () => $status.value(),
791
+ fetchStatus: () => $fetchStatus.value(),
792
+ pending: () => isQueryPending($status.value()),
793
+ isPending: () => isQueryPending($status.value()),
794
+ isFirstPending: () => {
795
+ const q = observer.getQuery();
796
+ return q ? q.state.status === "pending" && !q.state.hadSuccess : false;
797
+ },
798
+ isRefetching: () => {
799
+ const q = observer.getQuery();
800
+ return q ? q.state.fetchStatus === "fetching" && q.hasData() : false;
801
+ },
802
+ isFetching: () => isQueryFetching($fetchStatus.value()),
803
+ isSuccess: () => isQuerySuccess($status.value()),
804
+ isError: () => isQueryError($status.value()),
805
+ isIdle: () => isQueryIdle($status.value()),
806
+ isStale: () => $isStale.value(),
807
+ isPaused: () => isQueryPaused($fetchStatus.value()),
808
+ hasData: () => $data.value() !== void 0,
809
+ hasError: () => $error.value() !== null,
810
+ refetch: (options) => observer.refetch(options),
811
+ invalidate: () => observer.invalidate(),
812
+ cancel: (options) => observer.cancel(options),
813
+ abort: (reason) => observer.cancel({ reason }),
814
+ abortController: () => observer.getQuery()?.getAbortController() ?? null,
815
+ abortSignal: () => observer.getQuery()?.getAbortSignal() ?? null,
816
+ remove: () => {
817
+ observer.remove();
818
+ observer.destroy();
819
+ },
820
+ subscribe(listener) {
821
+ return observer.subscribe(() => listener($data.value()));
822
+ },
823
+ $data,
824
+ $error,
825
+ $params,
826
+ $status,
827
+ $fetchStatus,
828
+ $pendingCount,
829
+ $isStale,
830
+ $updatedAt,
831
+ $abortSignal
832
+ };
833
+ };
834
+
835
+ // src/query/create-query.ts
836
+ var createQuery = (options, meta) => {
837
+ const provider = meta?.provider ?? getQueryProvider();
838
+ const mergedOptions = mergeQueryDefinitionOptions(
839
+ options,
840
+ provider?.config,
841
+ provider
842
+ );
843
+ resolveQueryOptions(mergedOptions);
844
+ const definition = {
845
+ kind: "query-definition",
846
+ name: options.name,
847
+ options: mergedOptions,
848
+ queryKey(params) {
849
+ return mergedOptions.queryKey(params);
850
+ },
851
+ with(params, instanceOptions) {
852
+ const client = instanceOptions?.client ?? provider?.client ?? getDefaultQueryClient();
853
+ return createQueryInstance(definition, client, params, instanceOptions);
854
+ },
855
+ withStore(store, map, instanceOptions) {
856
+ const client = instanceOptions?.client ?? provider?.client ?? getDefaultQueryClient();
857
+ return createQueryInstance(
858
+ definition,
859
+ client,
860
+ () => map(store.value()),
861
+ instanceOptions
862
+ );
863
+ }
864
+ };
865
+ return definition;
866
+ };
867
+
868
+ // src/core/infinite-query-state.ts
869
+ var defaultInfiniteQueryState = () => ({
870
+ data: void 0,
871
+ error: null,
872
+ status: "idle",
873
+ fetchStatus: "idle",
874
+ dataUpdatedAt: 0,
875
+ errorUpdatedAt: 0,
876
+ fetchFailureCount: 0,
877
+ isInvalidated: false,
878
+ hadSuccess: false,
879
+ fetchingNextPage: false,
880
+ fetchingPreviousPage: false
881
+ });
882
+ var infiniteQueryReducer = (state, action) => {
883
+ switch (action.type) {
884
+ case "fetch":
885
+ return {
886
+ ...state,
887
+ fetchStatus: "fetching",
888
+ fetchingNextPage: action.direction === "next" || action.direction === "initial",
889
+ fetchingPreviousPage: action.direction === "previous",
890
+ ...state.data === void 0 && state.status === "idle" ? { status: "pending", error: null } : {}
891
+ };
892
+ case "success":
893
+ return {
894
+ ...state,
895
+ data: action.data,
896
+ error: null,
897
+ status: "success",
898
+ fetchStatus: "idle",
899
+ dataUpdatedAt: Date.now(),
900
+ fetchFailureCount: 0,
901
+ isInvalidated: false,
902
+ hadSuccess: true,
903
+ fetchingNextPage: false,
904
+ fetchingPreviousPage: false
905
+ };
906
+ case "error":
907
+ return {
908
+ ...state,
909
+ error: action.error,
910
+ status: "error",
911
+ fetchStatus: "idle",
912
+ errorUpdatedAt: Date.now(),
913
+ fetchFailureCount: state.fetchFailureCount + 1,
914
+ isInvalidated: true,
915
+ fetchingNextPage: false,
916
+ fetchingPreviousPage: false
917
+ };
918
+ case "failed":
919
+ return {
920
+ ...state,
921
+ fetchFailureCount: action.failureCount,
922
+ error: action.error
923
+ };
924
+ case "invalidate":
925
+ return { ...state, isInvalidated: true };
926
+ case "reset":
927
+ return defaultInfiniteQueryState();
928
+ case "setState":
929
+ return { ...state, ...action.state };
930
+ default:
931
+ return state;
932
+ }
933
+ };
934
+
935
+ // src/core/infinite-query.ts
936
+ var hasInfiniteNextPage = (data, getNextPageParam) => {
937
+ if (!data || data.pages.length === 0) return true;
938
+ const lastPage = data.pages[data.pages.length - 1];
939
+ const next = getNextPageParam(lastPage, data.pages);
940
+ return next !== void 0 && next !== null;
941
+ };
942
+ var hasInfinitePreviousPage = (data, getPreviousPageParam) => {
943
+ if (!getPreviousPageParam || !data || data.pages.length === 0) return false;
944
+ const firstPage = data.pages[0];
945
+ const prev = getPreviousPageParam(firstPage, data.pages);
946
+ return prev !== void 0 && prev !== null;
947
+ };
948
+ var InfiniteQuery = class extends Removable {
949
+ queryKey;
950
+ queryHash;
951
+ definition;
952
+ client;
953
+ params;
954
+ options;
955
+ state;
956
+ observers = /* @__PURE__ */ new Set();
957
+ $data;
958
+ $error;
959
+ $status;
960
+ $fetchStatus;
961
+ $pendingCount;
962
+ $updatedAt;
963
+ $isInvalidated;
964
+ $fetchingNextPage;
965
+ $fetchingPreviousPage;
966
+ #retryer;
967
+ #abortController;
968
+ #abortDispose;
969
+ #cache;
970
+ #requestId = 0;
971
+ constructor(config) {
972
+ super();
973
+ this.client = config.client;
974
+ this.#cache = config.cache;
975
+ this.definition = config.definition;
976
+ this.params = config.params;
977
+ this.queryKey = config.queryKey;
978
+ this.queryHash = hashKey(config.queryKey);
979
+ this.options = config.options;
980
+ this.state = defaultInfiniteQueryState();
981
+ this.updateGcTime(this.options.cacheTimeMs);
982
+ this.$data = signal(void 0);
983
+ this.$error = signal(null);
984
+ this.$status = signal("idle");
985
+ this.$fetchStatus = signal("idle");
986
+ this.$pendingCount = signal(0);
987
+ this.$updatedAt = signal(null);
988
+ this.$isInvalidated = signal(false);
989
+ this.$fetchingNextPage = signal(false);
990
+ this.$fetchingPreviousPage = signal(false);
991
+ }
992
+ isActive() {
993
+ return this.observers.size > 0;
994
+ }
995
+ isStale() {
996
+ return isStaleByTime(
997
+ this.state.dataUpdatedAt,
998
+ this.options.staleTimeMs,
999
+ this.state.isInvalidated,
1000
+ this.state.data !== void 0
1001
+ );
1002
+ }
1003
+ hasData() {
1004
+ return this.state.data !== void 0 && this.state.data.pages.length > 0;
1005
+ }
1006
+ hasNextPage() {
1007
+ return hasInfiniteNextPage(this.state.data, this.definition.options.getNextPageParam);
1008
+ }
1009
+ hasPreviousPage() {
1010
+ return hasInfinitePreviousPage(this.state.data, this.definition.options.getPreviousPageParam);
1011
+ }
1012
+ addObserver(observer) {
1013
+ if (!this.observers.has(observer)) {
1014
+ this.observers.add(observer);
1015
+ this.clearGcTimeout();
1016
+ }
1017
+ }
1018
+ removeObserver(observer) {
1019
+ if (this.observers.delete(observer) && this.observers.size === 0) {
1020
+ this.scheduleGc(() => this.#cache.remove(this));
1021
+ }
1022
+ }
1023
+ reset() {
1024
+ this.#requestId += 1;
1025
+ void this.cancel({ silent: true });
1026
+ this.#dispatch({ type: "reset" });
1027
+ }
1028
+ getAbortController() {
1029
+ return this.#abortController;
1030
+ }
1031
+ getAbortSignal() {
1032
+ return this.#abortController?.signal;
1033
+ }
1034
+ cancel(options) {
1035
+ this.#requestId += 1;
1036
+ abortWithReason(this.#abortController, options?.reason);
1037
+ const promise = this.#retryer?.promise;
1038
+ this.#retryer?.cancel(options);
1039
+ this.#retryer = void 0;
1040
+ this.#clearAbortHandle();
1041
+ this.#dispatch({
1042
+ type: "setState",
1043
+ state: {
1044
+ fetchStatus: "idle",
1045
+ fetchingNextPage: false,
1046
+ fetchingPreviousPage: false
1047
+ }
1048
+ });
1049
+ return promise ? promise.then(() => void 0).catch(() => void 0) : Promise.resolve();
1050
+ }
1051
+ async refetch(options) {
1052
+ await this.cancel({ silent: true });
1053
+ this.#dispatch({ type: "reset" });
1054
+ await this.fetchPage("initial", options);
1055
+ if (!this.state.data) {
1056
+ throw new Error("Infinite query refetch failed");
1057
+ }
1058
+ return this.state.data;
1059
+ }
1060
+ async fetchNextPage(options) {
1061
+ if (!this.hasNextPage()) return null;
1062
+ const direction = this.hasData() ? "next" : "initial";
1063
+ return this.fetchPage(direction, options);
1064
+ }
1065
+ async fetchPreviousPage(options) {
1066
+ if (!this.hasPreviousPage()) return null;
1067
+ return this.fetchPage("previous", options);
1068
+ }
1069
+ async fetchPage(direction, abortSource) {
1070
+ if (direction === "next" && !this.hasNextPage()) return null;
1071
+ if (direction === "previous" && !this.hasPreviousPage()) return null;
1072
+ const requestId = ++this.#requestId;
1073
+ const abortHandle = createFetchAbortHandle(
1074
+ mergeFetchAbortSource(this.options, abortSource)
1075
+ );
1076
+ this.#abortController = abortHandle.controller;
1077
+ this.#abortDispose = abortHandle.dispose;
1078
+ const { controller: abortController, signal: signal8 } = abortHandle;
1079
+ const { initialPageParam, getNextPageParam, getPreviousPageParam } = this.definition.options;
1080
+ const current = this.state.data;
1081
+ let pageParam;
1082
+ if (direction === "initial") {
1083
+ pageParam = initialPageParam;
1084
+ } else if (direction === "next") {
1085
+ const lastPage = current.pages[current.pages.length - 1];
1086
+ pageParam = getNextPageParam(lastPage, current.pages);
1087
+ } else {
1088
+ const firstPage = current.pages[0];
1089
+ pageParam = getPreviousPageParam(firstPage, current.pages);
1090
+ }
1091
+ const lifecycleCtx = {
1092
+ params: this.params,
1093
+ queryKey: this.queryKey,
1094
+ queryClient: this.client
1095
+ };
1096
+ this.#dispatch({ type: "fetch", direction });
1097
+ this.$pendingCount.set(this.$pendingCount.peek() + 1);
1098
+ void runLifecycle(this.options, "start", lifecycleCtx);
1099
+ this.#retryer = createRetryer({
1100
+ fn: async () => {
1101
+ const page = await this.definition.options.queryFn({
1102
+ params: this.params,
1103
+ pageParam,
1104
+ signal: signal8,
1105
+ abortController,
1106
+ queryClient: this.client,
1107
+ queryKey: this.queryKey
1108
+ });
1109
+ if (signal8.aborted) {
1110
+ throw new CancelledError({ silent: true });
1111
+ }
1112
+ return page;
1113
+ },
1114
+ onCancel: () => abortHandle.abort(),
1115
+ onFail: (failureCount, error) => {
1116
+ const err = error instanceof Error ? error : new Error(String(error));
1117
+ this.#dispatch({ type: "failed", failureCount, error: err });
1118
+ },
1119
+ retry: this.options.retry,
1120
+ retryDelay: this.options.retryDelay
1121
+ });
1122
+ try {
1123
+ const page = await this.#retryer.start();
1124
+ if (requestId !== this.#requestId) {
1125
+ return null;
1126
+ }
1127
+ const nextData = this.#mergePage(direction, pageParam, page);
1128
+ this.#dispatch({ type: "success", data: nextData });
1129
+ this.#cache.emit({
1130
+ type: "infiniteQueryFetched",
1131
+ queryKey: this.queryKey,
1132
+ hash: this.queryHash
1133
+ });
1134
+ await runLifecycle(this.options, "success", { ...lifecycleCtx, data: nextData });
1135
+ await runLifecycle(this.options, "settled", { ...lifecycleCtx, data: nextData });
1136
+ return page;
1137
+ } catch (error) {
1138
+ if (requestId !== this.#requestId) {
1139
+ return null;
1140
+ }
1141
+ if (isCancelledError(error)) {
1142
+ if (error.silent) {
1143
+ return null;
1144
+ }
1145
+ throw error;
1146
+ }
1147
+ const err = error instanceof Error ? error : new Error(String(error));
1148
+ this.#dispatch({ type: "error", error: err });
1149
+ await runLifecycle(this.options, "error", { ...lifecycleCtx, error: err });
1150
+ await runLifecycle(this.options, "settled", { ...lifecycleCtx, error: err });
1151
+ throw error;
1152
+ } finally {
1153
+ if (requestId === this.#requestId) {
1154
+ this.$pendingCount.set(Math.max(0, this.$pendingCount.peek() - 1));
1155
+ this.#retryer = void 0;
1156
+ this.#clearAbortHandle();
1157
+ this.scheduleGc(() => {
1158
+ if (this.observers.size === 0) this.#cache.remove(this);
1159
+ });
1160
+ }
1161
+ }
1162
+ }
1163
+ #clearAbortHandle() {
1164
+ this.#abortDispose?.();
1165
+ this.#abortDispose = void 0;
1166
+ this.#abortController = void 0;
1167
+ }
1168
+ onFocus() {
1169
+ if (this.isActive() && this.isStale() && this.options.refetchOnWindowFocus) {
1170
+ void this.refetch();
1171
+ }
1172
+ }
1173
+ onOnline() {
1174
+ if (this.isActive() && this.isStale() && this.options.refetchOnReconnect) {
1175
+ void this.refetch();
1176
+ }
1177
+ }
1178
+ #mergePage(direction, pageParam, page) {
1179
+ const current = this.state.data;
1180
+ if (direction === "initial" || !current) {
1181
+ return { pages: [page], pageParams: [pageParam] };
1182
+ }
1183
+ if (direction === "next") {
1184
+ return {
1185
+ pages: [...current.pages, page],
1186
+ pageParams: [...current.pageParams, pageParam]
1187
+ };
1188
+ }
1189
+ return {
1190
+ pages: [page, ...current.pages],
1191
+ pageParams: [pageParam, ...current.pageParams]
1192
+ };
1193
+ }
1194
+ #dispatch(action) {
1195
+ this.state = infiniteQueryReducer(this.state, action);
1196
+ this.syncSignals();
1197
+ this.#cache.emit({
1198
+ type: "infiniteQueryUpdated",
1199
+ queryKey: this.queryKey,
1200
+ hash: this.queryHash
1201
+ });
1202
+ for (const observer of this.observers) {
1203
+ observer.onInfiniteQueryUpdate();
1204
+ }
1205
+ }
1206
+ syncSignals() {
1207
+ this.$data.set(this.state.data);
1208
+ this.$error.set(this.state.error);
1209
+ this.$status.set(this.state.status);
1210
+ this.$fetchStatus.set(this.state.fetchStatus);
1211
+ this.$updatedAt.set(this.state.dataUpdatedAt || null);
1212
+ this.$isInvalidated.set(this.state.isInvalidated);
1213
+ this.$fetchingNextPage.set(this.state.fetchingNextPage);
1214
+ this.$fetchingPreviousPage.set(this.state.fetchingPreviousPage);
1215
+ }
1216
+ };
1217
+
1218
+ // src/query/infinite-query-status.ts
1219
+ var DEFAULT_CACHE_TIME_MS3 = 5 * 6e4;
1220
+ var resolveInfiniteQueryOptions = (options) => {
1221
+ const staleTime = options.staleTime ?? 0;
1222
+ const cacheTime = options.cacheTime ?? DEFAULT_CACHE_TIME_MS3;
1223
+ return {
1224
+ ...options,
1225
+ staleTime,
1226
+ cacheTime,
1227
+ retry: options.retry ?? false,
1228
+ retryDelay: options.retryDelay ?? 1e3,
1229
+ keepPreviousData: options.keepPreviousData ?? false,
1230
+ abortPrevious: options.abortPrevious ?? true,
1231
+ staleTimeMs: toMs(staleTime, 0),
1232
+ cacheTimeMs: toMs(cacheTime, DEFAULT_CACHE_TIME_MS3)
1233
+ };
1234
+ };
1235
+ var resolveInfiniteInstanceOptions = (definitionOptions, instanceOptions) => {
1236
+ const staleTime = instanceOptions?.staleTime ?? definitionOptions.staleTime ?? 0;
1237
+ const cacheTime = instanceOptions?.cacheTime ?? definitionOptions.cacheTime ?? DEFAULT_CACHE_TIME_MS3;
1238
+ return {
1239
+ ...definitionOptions,
1240
+ ...instanceOptions,
1241
+ staleTime,
1242
+ cacheTime,
1243
+ staleTimeMs: toMs(staleTime, 0),
1244
+ cacheTimeMs: toMs(cacheTime, DEFAULT_CACHE_TIME_MS3),
1245
+ enabled: instanceOptions?.enabled ?? true,
1246
+ refetchOnMount: instanceOptions?.refetchOnMount ?? true,
1247
+ refetchOnWindowFocus: instanceOptions?.refetchOnWindowFocus ?? true,
1248
+ refetchOnReconnect: instanceOptions?.refetchOnReconnect ?? true,
1249
+ keepPreviousData: instanceOptions?.keepPreviousData ?? definitionOptions.keepPreviousData ?? false,
1250
+ abortPrevious: instanceOptions?.abortPrevious ?? definitionOptions.abortPrevious ?? true,
1251
+ retry: instanceOptions?.retry ?? definitionOptions.retry ?? false,
1252
+ retryDelay: instanceOptions?.retryDelay ?? definitionOptions.retryDelay ?? 1e3,
1253
+ onStart: instanceOptions?.onStart ?? definitionOptions.onStart,
1254
+ onSuccess: instanceOptions?.onSuccess ?? definitionOptions.onSuccess,
1255
+ onError: instanceOptions?.onError ?? definitionOptions.onError,
1256
+ onSettled: instanceOptions?.onSettled ?? definitionOptions.onSettled
1257
+ };
1258
+ };
1259
+ var resolveInfiniteDefinitionOptions = (definition) => resolveInfiniteQueryOptions(definition.options);
1260
+
1261
+ // src/query/infinite-query-observer.ts
1262
+ var InfiniteQueryObserver = class {
1263
+ definition;
1264
+ client;
1265
+ options;
1266
+ #query = null;
1267
+ #previousQuery = null;
1268
+ #params;
1269
+ #disposeParams = null;
1270
+ #destroyed = false;
1271
+ #listeners = /* @__PURE__ */ new Set();
1272
+ #currentHash = null;
1273
+ constructor(definition, client, params, instanceOptions) {
1274
+ this.definition = definition;
1275
+ this.client = client;
1276
+ this.options = resolveInfiniteInstanceOptions(
1277
+ resolveInfiniteDefinitionOptions(definition),
1278
+ instanceOptions
1279
+ );
1280
+ if (typeof params === "function") {
1281
+ this.#disposeParams = effect(() => {
1282
+ this.setParams(params());
1283
+ });
1284
+ } else {
1285
+ this.setParams(params);
1286
+ }
1287
+ }
1288
+ getQuery() {
1289
+ return this.#query;
1290
+ }
1291
+ getPreviousQuery() {
1292
+ return this.#previousQuery;
1293
+ }
1294
+ getParams() {
1295
+ return this.#params;
1296
+ }
1297
+ onInfiniteQueryUpdate() {
1298
+ for (const listener of this.#listeners) listener();
1299
+ }
1300
+ subscribe(listener) {
1301
+ this.#listeners.add(listener);
1302
+ return () => this.#listeners.delete(listener);
1303
+ }
1304
+ setParams(params) {
1305
+ if (this.#destroyed) return;
1306
+ this.#params = params;
1307
+ const queryKey = this.definition.queryKey(params);
1308
+ const hash = hashKey(queryKey);
1309
+ if (this.#currentHash === hash) {
1310
+ void this.maybeFetch(false);
1311
+ return;
1312
+ }
1313
+ if (this.#query) {
1314
+ if (this.options.abortPrevious) {
1315
+ void this.#query.cancel({ silent: true });
1316
+ }
1317
+ this.#detach(this.#query);
1318
+ this.#previousQuery = this.options.keepPreviousData ? this.#query : null;
1319
+ }
1320
+ this.#currentHash = hash;
1321
+ this.#query = this.client.infiniteQueryCache.build({
1322
+ client: this.client,
1323
+ cache: this.client.infiniteQueryCache,
1324
+ definition: this.definition,
1325
+ params,
1326
+ queryKey,
1327
+ options: this.options
1328
+ });
1329
+ this.#query.addObserver(this);
1330
+ void this.maybeFetch(true);
1331
+ this.onInfiniteQueryUpdate();
1332
+ }
1333
+ maybeFetch(paramsChanged) {
1334
+ if (!this.#query || !isEnabled(this.options.enabled)) return;
1335
+ const stale = this.#query.isStale();
1336
+ const hasData = this.#query.hasData();
1337
+ if (!hasData || stale) {
1338
+ void this.#query.fetchNextPage();
1339
+ return;
1340
+ }
1341
+ if (paramsChanged && this.options.refetchOnMount === true) {
1342
+ void this.#query.refetch();
1343
+ }
1344
+ }
1345
+ cancel(options) {
1346
+ void this.#query?.cancel(options);
1347
+ }
1348
+ remove() {
1349
+ if (!this.#query) return;
1350
+ this.#detach(this.#query);
1351
+ this.client.infiniteQueryCache.remove(this.#query);
1352
+ this.#query = null;
1353
+ this.#currentHash = null;
1354
+ this.onInfiniteQueryUpdate();
1355
+ }
1356
+ destroy() {
1357
+ if (this.#destroyed) return;
1358
+ this.#destroyed = true;
1359
+ this.#disposeParams?.();
1360
+ if (this.#query) this.#detach(this.#query);
1361
+ this.#listeners.clear();
1362
+ }
1363
+ #detach(query) {
1364
+ query.removeObserver(this);
1365
+ }
1366
+ };
1367
+
1368
+ // src/query/infinite-query-instance.ts
1369
+ var effectiveInfiniteQuery = (observer) => {
1370
+ const query = observer.getQuery();
1371
+ if (!query) return observer.getPreviousQuery();
1372
+ if (query.hasData()) return query;
1373
+ const prev = observer.getPreviousQuery();
1374
+ if (prev && observer.options.keepPreviousData) return prev;
1375
+ return query;
1376
+ };
1377
+ var createInfiniteQueryInstance = (definition, client, params, instanceOptions) => {
1378
+ const observer = new InfiniteQueryObserver(definition, client, params, instanceOptions);
1379
+ const $params = signal(observer.getParams());
1380
+ observer.subscribe(() => $params.set(observer.getParams()));
1381
+ const readQuery = () => effectiveInfiniteQuery(observer);
1382
+ const readData = () => {
1383
+ const data = readQuery()?.$data.value();
1384
+ return data ?? null;
1385
+ };
1386
+ const $data = computed(() => readData());
1387
+ const $pages = computed(() => readData()?.pages ?? []);
1388
+ const $pageParams = computed(() => readData()?.pageParams ?? []);
1389
+ const $error = computed(() => readQuery()?.$error.value() ?? null);
1390
+ const $pending = computed(() => {
1391
+ const q = readQuery();
1392
+ return q ? isQueryPending(q.$status.value()) : false;
1393
+ });
1394
+ const $fetching = computed(() => readQuery()?.$fetchStatus.value() === "fetching");
1395
+ const $fetchingNextPage = computed(() => readQuery()?.$fetchingNextPage.value() ?? false);
1396
+ const $fetchingPreviousPage = computed(
1397
+ () => readQuery()?.$fetchingPreviousPage.value() ?? false
1398
+ );
1399
+ const $abortSignal = computed(() => readQuery()?.getAbortSignal() ?? null);
1400
+ const getQuery = () => {
1401
+ const q = observer.getQuery();
1402
+ if (!q) throw new Error("InfiniteQueryObserver has no active query");
1403
+ return q;
1404
+ };
1405
+ return {
1406
+ kind: "infinite-query",
1407
+ pages: () => $pages.value(),
1408
+ pageParams: () => $pageParams.value(),
1409
+ data: () => $data.value(),
1410
+ flatMap: (selector) => $pages.value().flatMap((page) => selector(page)),
1411
+ fetchNextPage: (options) => getQuery().fetchNextPage(options),
1412
+ fetchPreviousPage: (options) => getQuery().fetchPreviousPage(options),
1413
+ refetch: (options) => getQuery().refetch(options),
1414
+ reset: () => getQuery().reset(),
1415
+ cancel: (options) => observer.cancel(options),
1416
+ abort: (reason) => observer.cancel({ reason }),
1417
+ abortController: () => readQuery()?.getAbortController() ?? null,
1418
+ abortSignal: () => readQuery()?.getAbortSignal() ?? null,
1419
+ remove: () => {
1420
+ observer.remove();
1421
+ observer.destroy();
1422
+ },
1423
+ hasNextPage: () => readQuery()?.hasNextPage() ?? true,
1424
+ hasPreviousPage: () => readQuery()?.hasPreviousPage() ?? false,
1425
+ pending: () => $pending.value(),
1426
+ fetching: () => $fetching.value(),
1427
+ fetchingNextPage: () => $fetchingNextPage.value(),
1428
+ fetchingPreviousPage: () => $fetchingPreviousPage.value(),
1429
+ error: () => $error.value(),
1430
+ params: () => $params.value(),
1431
+ subscribe(listener) {
1432
+ return observer.subscribe(() => listener($data.value()));
1433
+ },
1434
+ $data,
1435
+ $pages,
1436
+ $pageParams,
1437
+ $pending,
1438
+ $fetching,
1439
+ $fetchingNextPage,
1440
+ $fetchingPreviousPage,
1441
+ $error,
1442
+ $params,
1443
+ $abortSignal
1444
+ };
1445
+ };
1446
+
1447
+ // src/query/infinite-query-options.ts
1448
+ var mergeInfiniteQueryDefinitionOptions = (options, config, provider) => {
1449
+ const queryDefaults = defaultQueryOptions(config);
1450
+ const providerDefaults = provider?.config.defaultOptions?.queries;
1451
+ return {
1452
+ staleTime: queryDefaults.staleTime,
1453
+ cacheTime: queryDefaults.cacheTime,
1454
+ retry: queryDefaults.retry,
1455
+ retryDelay: queryDefaults.retryDelay,
1456
+ keepPreviousData: queryDefaults.keepPreviousData,
1457
+ abortPrevious: queryDefaults.abortPrevious,
1458
+ ...providerDefaults,
1459
+ ...options
1460
+ };
1461
+ };
1462
+
1463
+ // src/query/create-infinite-query.ts
1464
+ var createInfiniteQuery = (options, meta) => {
1465
+ const provider = meta?.provider ?? getQueryProvider();
1466
+ const mergedOptions = mergeInfiniteQueryDefinitionOptions(
1467
+ options,
1468
+ provider?.config,
1469
+ provider
1470
+ );
1471
+ resolveInfiniteQueryOptions(mergedOptions);
1472
+ const definition = {
1473
+ kind: "infinite-query-definition",
1474
+ name: options.name,
1475
+ options: mergedOptions,
1476
+ queryKey(params) {
1477
+ return mergedOptions.queryKey(params);
1478
+ },
1479
+ with(params, instanceOptions) {
1480
+ const client = instanceOptions?.client ?? provider?.client ?? getDefaultQueryClient();
1481
+ return createInfiniteQueryInstance(definition, client, params, instanceOptions);
1482
+ },
1483
+ withStore(store, map, instanceOptions) {
1484
+ const client = instanceOptions?.client ?? provider?.client ?? getDefaultQueryClient();
1485
+ return createInfiniteQueryInstance(
1486
+ definition,
1487
+ client,
1488
+ () => map(store.value()),
1489
+ instanceOptions
1490
+ );
1491
+ }
1492
+ };
1493
+ return definition;
1494
+ };
1495
+
1496
+ // src/core/subscribable.ts
1497
+ var Subscribable = class {
1498
+ listeners = /* @__PURE__ */ new Set();
1499
+ subscribe(listener) {
1500
+ this.listeners.add(listener);
1501
+ return () => this.listeners.delete(listener);
1502
+ }
1503
+ notify(event) {
1504
+ for (const listener of this.listeners) {
1505
+ listener(event);
1506
+ }
1507
+ }
1508
+ hasListeners() {
1509
+ return this.listeners.size > 0;
1510
+ }
1511
+ };
1512
+
1513
+ // src/utils/match-query.ts
1514
+ var matchQuery = (filters, query) => {
1515
+ const { exact, fetchStatus, predicate, queryKey, stale } = filters;
1516
+ if (queryKey) {
1517
+ if (exact) {
1518
+ if (query.queryHash !== hashKey(queryKey)) return false;
1519
+ } else if (!partialMatchKey(query.queryKey, queryKey)) {
1520
+ return false;
1521
+ }
1522
+ }
1523
+ if (typeof stale === "boolean" && query.isStale() !== stale) return false;
1524
+ if (fetchStatus && fetchStatus !== query.state.fetchStatus) return false;
1525
+ if (predicate && !predicate(query)) return false;
1526
+ return true;
1527
+ };
1528
+
1529
+ // src/core/query-cache.ts
1530
+ var QueryCache = class extends Subscribable {
1531
+ #queries = /* @__PURE__ */ new Map();
1532
+ get(queryHash) {
1533
+ return this.#queries.get(queryHash);
1534
+ }
1535
+ getByKey(queryKey) {
1536
+ return this.#queries.get(hashKey(queryKey));
1537
+ }
1538
+ getAll() {
1539
+ return [...this.#queries.values()];
1540
+ }
1541
+ build(config) {
1542
+ const hash = hashKey(config.queryKey);
1543
+ const cached = this.#queries.get(hash);
1544
+ if (cached) return cached;
1545
+ const query = new Query(config);
1546
+ this.add(query);
1547
+ return query;
1548
+ }
1549
+ add(query) {
1550
+ if (!this.#queries.has(query.queryHash)) {
1551
+ this.#queries.set(
1552
+ query.queryHash,
1553
+ query
1554
+ );
1555
+ this.emit({
1556
+ type: "queryAdded",
1557
+ queryKey: query.queryKey,
1558
+ hash: query.queryHash
1559
+ });
1560
+ }
1561
+ }
1562
+ remove(query) {
1563
+ const cached = this.#queries.get(query.queryHash);
1564
+ if (cached && cached.queryHash === query.queryHash) {
1565
+ void query.cancel({ silent: true });
1566
+ this.#queries.delete(query.queryHash);
1567
+ this.emit({
1568
+ type: "queryRemoved",
1569
+ queryKey: query.queryKey,
1570
+ hash: query.queryHash
1571
+ });
1572
+ }
1573
+ }
1574
+ find(filters) {
1575
+ return this.getAll().find((query) => matchQuery(filters, query));
1576
+ }
1577
+ findAll(filter = []) {
1578
+ if (Array.isArray(filter)) {
1579
+ if (filter.length === 0) return this.getAll();
1580
+ return this.getAll().filter(
1581
+ (query) => matchQuery({ queryKey: filter }, query)
1582
+ );
1583
+ }
1584
+ const objectFilter = filter;
1585
+ return this.getAll().filter(
1586
+ (query) => matchQuery(
1587
+ { queryKey: objectFilter.queryKey, exact: objectFilter.exact },
1588
+ query
1589
+ )
1590
+ );
1591
+ }
1592
+ clear() {
1593
+ for (const query of [...this.getAll()]) {
1594
+ this.remove(query);
1595
+ }
1596
+ }
1597
+ emit(event) {
1598
+ this.notify(event);
1599
+ }
1600
+ onFocus() {
1601
+ for (const query of this.getAll()) {
1602
+ query.onFocus();
1603
+ }
1604
+ }
1605
+ onOnline() {
1606
+ for (const query of this.getAll()) {
1607
+ query.onOnline();
1608
+ }
1609
+ }
1610
+ };
1611
+ var createQueryCache = () => new QueryCache();
1612
+
1613
+ // src/core/infinite-query-cache.ts
1614
+ var InfiniteQueryCache = class extends Subscribable {
1615
+ #queries = /* @__PURE__ */ new Map();
1616
+ get(queryHash) {
1617
+ return this.#queries.get(queryHash);
1618
+ }
1619
+ getByKey(queryKey) {
1620
+ return this.#queries.get(hashKey(queryKey));
1621
+ }
1622
+ getAll() {
1623
+ return [...this.#queries.values()];
1624
+ }
1625
+ build(config) {
1626
+ const hash = hashKey(config.queryKey);
1627
+ const cached = this.#queries.get(hash);
1628
+ if (cached) return cached;
1629
+ const query = new InfiniteQuery(config);
1630
+ this.add(query);
1631
+ return query;
1632
+ }
1633
+ add(query) {
1634
+ if (!this.#queries.has(query.queryHash)) {
1635
+ this.#queries.set(
1636
+ query.queryHash,
1637
+ query
1638
+ );
1639
+ this.emit({
1640
+ type: "infiniteQueryAdded",
1641
+ queryKey: query.queryKey,
1642
+ hash: query.queryHash
1643
+ });
1644
+ }
1645
+ }
1646
+ remove(query) {
1647
+ const cached = this.#queries.get(query.queryHash);
1648
+ if (cached && cached.queryHash === query.queryHash) {
1649
+ void query.cancel({ silent: true });
1650
+ this.#queries.delete(query.queryHash);
1651
+ this.emit({
1652
+ type: "infiniteQueryRemoved",
1653
+ queryKey: query.queryKey,
1654
+ hash: query.queryHash
1655
+ });
1656
+ }
1657
+ }
1658
+ find(filters) {
1659
+ return this.getAll().find((query) => matchQuery(filters, query));
1660
+ }
1661
+ findAll(filter = []) {
1662
+ if (Array.isArray(filter)) {
1663
+ if (filter.length === 0) return this.getAll();
1664
+ return this.getAll().filter((query) => matchQuery({ queryKey: filter }, query));
1665
+ }
1666
+ const objectFilter = filter;
1667
+ return this.getAll().filter(
1668
+ (query) => matchQuery(
1669
+ { queryKey: objectFilter.queryKey, exact: objectFilter.exact },
1670
+ query
1671
+ )
1672
+ );
1673
+ }
1674
+ clear() {
1675
+ for (const query of [...this.getAll()]) {
1676
+ this.remove(query);
1677
+ }
1678
+ }
1679
+ emit(event) {
1680
+ this.notify(event);
1681
+ }
1682
+ onFocus() {
1683
+ for (const query of this.getAll()) {
1684
+ query.onFocus();
1685
+ }
1686
+ }
1687
+ onOnline() {
1688
+ for (const query of this.getAll()) {
1689
+ query.onOnline();
1690
+ }
1691
+ }
1692
+ };
1693
+ var createInfiniteQueryCache = () => new InfiniteQueryCache();
1694
+
1695
+ // src/core/mutation-cache.ts
1696
+ var MutationCache = class extends Subscribable {
1697
+ emit(event) {
1698
+ this.notify(event);
1699
+ }
1700
+ clear() {
1701
+ this.listeners.clear();
1702
+ }
1703
+ };
1704
+ var createMutationCache = () => new MutationCache();
1705
+
1706
+ // src/managers/register-client.ts
1707
+ var clients = /* @__PURE__ */ new Set();
1708
+ var registerClientWithManagers = (client) => {
1709
+ clients.add(client);
1710
+ };
1711
+ var getRegisteredClients = () => clients;
1712
+
1713
+ // src/client/query-client.ts
1714
+ var resolveKeyAndParams = (keyOrDefinition, params) => {
1715
+ if (typeof keyOrDefinition === "object" && keyOrDefinition !== null && "kind" in keyOrDefinition) {
1716
+ return { key: keyOrDefinition.queryKey(params) };
1717
+ }
1718
+ return { key: keyOrDefinition };
1719
+ };
1720
+ var QueryClient = class {
1721
+ queryCache;
1722
+ infiniteQueryCache;
1723
+ mutationCache;
1724
+ constructor(config) {
1725
+ this.queryCache = createQueryCache();
1726
+ this.infiniteQueryCache = createInfiniteQueryCache();
1727
+ this.mutationCache = createMutationCache();
1728
+ registerClientWithManagers(this);
1729
+ }
1730
+ async fetchQuery(definition, params, options) {
1731
+ const resolvedParams = params ?? {};
1732
+ const queryKey = definition.queryKey(resolvedParams);
1733
+ const resolvedOptions = resolveInstanceOptions(
1734
+ resolveDefinitionOptions(definition),
1735
+ options
1736
+ );
1737
+ if (!isEnabled(resolvedOptions.enabled)) {
1738
+ const cached = this.getQueryData(definition, resolvedParams);
1739
+ if (cached === void 0) {
1740
+ throw new Error("Query is disabled and has no cached data");
1741
+ }
1742
+ return cached;
1743
+ }
1744
+ const query = this.queryCache.build({
1745
+ client: this,
1746
+ cache: this.queryCache,
1747
+ definition,
1748
+ params: resolvedParams,
1749
+ queryKey,
1750
+ options: resolvedOptions
1751
+ });
1752
+ if (query.hasData() && !query.isStale()) {
1753
+ return query.state.data;
1754
+ }
1755
+ return query.fetch();
1756
+ }
1757
+ async prefetchQuery(definition, params, options) {
1758
+ await this.fetchQuery(definition, params, options);
1759
+ }
1760
+ async ensureQueryData(definition, params, options) {
1761
+ return this.fetchQuery(definition, params, options);
1762
+ }
1763
+ getQueryData(keyOrDefinition, params) {
1764
+ const { key } = resolveKeyAndParams(keyOrDefinition, params);
1765
+ return this.queryCache.getByKey(key)?.state.data;
1766
+ }
1767
+ setQueryData(keyOrDefinition, paramsOrUpdater, updater) {
1768
+ let key;
1769
+ let nextUpdater;
1770
+ if (typeof keyOrDefinition === "object" && keyOrDefinition !== null && "kind" in keyOrDefinition) {
1771
+ key = keyOrDefinition.queryKey(paramsOrUpdater);
1772
+ nextUpdater = typeof updater === "function" ? updater : () => updater;
1773
+ } else {
1774
+ key = keyOrDefinition;
1775
+ nextUpdater = typeof paramsOrUpdater === "function" ? paramsOrUpdater : () => paramsOrUpdater;
1776
+ }
1777
+ const hash = hashKey(key);
1778
+ let query = this.queryCache.get(hash);
1779
+ if (!query) {
1780
+ throw new Error(`Query not found for key: ${JSON.stringify(key)}`);
1781
+ }
1782
+ query.setData(
1783
+ (prev) => functionalUpdate(nextUpdater, prev)
1784
+ );
1785
+ }
1786
+ invalidateQueries(filter, options) {
1787
+ const refetchMode = options?.refetch ?? "active";
1788
+ const shouldRefetch = refetchMode !== false && refetchMode !== "none";
1789
+ for (const query of this.queryCache.findAll(filter)) {
1790
+ query.invalidate();
1791
+ if (!shouldRefetch) continue;
1792
+ if (refetchMode === "all" || query.isActive()) {
1793
+ void query.fetch().catch(() => void 0);
1794
+ }
1795
+ }
1796
+ }
1797
+ async refetchQueries(filter) {
1798
+ await Promise.allSettled(
1799
+ this.queryCache.findAll(filter).map((query) => query.fetch())
1800
+ );
1801
+ }
1802
+ cancelQueries(filter) {
1803
+ for (const query of this.queryCache.findAll(filter)) {
1804
+ void query.cancel();
1805
+ }
1806
+ }
1807
+ removeQueries(filter) {
1808
+ for (const query of [...this.queryCache.findAll(filter)]) {
1809
+ this.queryCache.remove(query);
1810
+ }
1811
+ }
1812
+ clear() {
1813
+ this.queryCache.clear();
1814
+ this.infiniteQueryCache.clear();
1815
+ this.mutationCache.clear();
1816
+ }
1817
+ };
1818
+ var createQueryClient = (config) => {
1819
+ const client = new QueryClient(config);
1820
+ setDefaultQueryClient(client);
1821
+ registerDefaultQueryClientFactory(() => client);
1822
+ return client;
1823
+ };
1824
+ var mutationIdCounter = 0;
1825
+ var Mutation = class {
1826
+ id;
1827
+ definition;
1828
+ client;
1829
+ cache;
1830
+ $data;
1831
+ $error;
1832
+ $variables;
1833
+ $status;
1834
+ $pendingCount;
1835
+ #abortController;
1836
+ #abortDispose;
1837
+ constructor(definition, client, cache) {
1838
+ mutationIdCounter += 1;
1839
+ this.id = mutationIdCounter;
1840
+ this.definition = definition;
1841
+ this.client = client;
1842
+ this.cache = cache;
1843
+ this.$data = signal(void 0);
1844
+ this.$error = signal(null);
1845
+ this.$variables = signal(void 0);
1846
+ this.$status = signal("idle");
1847
+ this.$pendingCount = signal(0);
1848
+ }
1849
+ getAbortController() {
1850
+ return this.#abortController;
1851
+ }
1852
+ getAbortSignal() {
1853
+ return this.#abortController?.signal;
1854
+ }
1855
+ async run(variables, runOptions) {
1856
+ const abortHandle = createFetchAbortHandle(
1857
+ mergeFetchAbortSource(this.definition.options, runOptions)
1858
+ );
1859
+ this.#abortController = abortHandle.controller;
1860
+ this.#abortDispose = abortHandle.dispose;
1861
+ const { controller: abortController, signal: signal8 } = abortHandle;
1862
+ this.$variables.set(variables);
1863
+ this.$status.set("pending");
1864
+ this.$pendingCount.set(this.$pendingCount.peek() + 1);
1865
+ this.cache.emit({ type: "mutationAdded", mutationId: this.id });
1866
+ let rollback;
1867
+ const lifecycleCtx = {
1868
+ variables,
1869
+ queryClient: this.client
1870
+ };
1871
+ try {
1872
+ const mutateResult = await this.definition.options.onMutate?.({
1873
+ ...lifecycleCtx
1874
+ });
1875
+ if (typeof mutateResult !== "undefined") {
1876
+ rollback = mutateResult;
1877
+ }
1878
+ const retryer = createRetryer({
1879
+ fn: () => this.definition.options.mutationFn({
1880
+ variables,
1881
+ signal: signal8,
1882
+ abortController,
1883
+ queryClient: this.client
1884
+ }),
1885
+ onCancel: () => abortHandle.abort(),
1886
+ retry: this.definition.options.retry,
1887
+ retryDelay: this.definition.options.retryDelay
1888
+ });
1889
+ const data = await retryer.start();
1890
+ this.$data.set(data);
1891
+ this.$error.set(null);
1892
+ this.$status.set("success");
1893
+ this.definition.options.onSuccess?.({
1894
+ ...lifecycleCtx,
1895
+ data,
1896
+ rollback
1897
+ });
1898
+ this.cache.emit({ type: "mutationUpdated", mutationId: this.id });
1899
+ return data;
1900
+ } catch (error) {
1901
+ if (!isCancelledError(error) && !isAbortError(error)) {
1902
+ const err = error instanceof Error ? error : new Error(String(error));
1903
+ this.$error.set(err);
1904
+ this.$status.set("error");
1905
+ this.definition.options.onError?.({
1906
+ ...lifecycleCtx,
1907
+ error: err,
1908
+ rollback
1909
+ });
1910
+ }
1911
+ throw error;
1912
+ } finally {
1913
+ this.$pendingCount.set(Math.max(0, this.$pendingCount.peek() - 1));
1914
+ this.#clearAbortHandle();
1915
+ this.definition.options.onSettled?.({
1916
+ ...lifecycleCtx,
1917
+ data: this.$data.peek(),
1918
+ error: this.$error.peek(),
1919
+ rollback
1920
+ });
1921
+ this.cache.emit({ type: "mutationUpdated", mutationId: this.id });
1922
+ }
1923
+ }
1924
+ cancel(options) {
1925
+ abortWithReason(this.#abortController, options?.reason);
1926
+ }
1927
+ #clearAbortHandle() {
1928
+ this.#abortDispose?.();
1929
+ this.#abortDispose = void 0;
1930
+ this.#abortController = void 0;
1931
+ }
1932
+ reset() {
1933
+ this.$data.set(void 0);
1934
+ this.$error.set(null);
1935
+ this.$variables.set(void 0);
1936
+ this.$status.set("idle");
1937
+ this.$pendingCount.set(0);
1938
+ }
1939
+ toInstance() {
1940
+ const mutation = this;
1941
+ const $data = computed(() => mutation.$data.value());
1942
+ const $error = computed(() => mutation.$error.value());
1943
+ const $variables = computed(
1944
+ () => mutation.$variables.value()
1945
+ );
1946
+ const $status = computed(() => mutation.$status.value());
1947
+ const $pendingCount = computed(() => mutation.$pendingCount.value());
1948
+ const $abortSignal = computed(() => mutation.getAbortSignal() ?? null);
1949
+ return {
1950
+ kind: "mutation-instance",
1951
+ run: (variables, options) => mutation.run(variables, options),
1952
+ reset: () => mutation.reset(),
1953
+ cancel: (options) => mutation.cancel(options),
1954
+ abort: (reason) => mutation.cancel({ reason }),
1955
+ abortController: () => mutation.getAbortController() ?? null,
1956
+ abortSignal: () => mutation.getAbortSignal() ?? null,
1957
+ data: () => $data.value(),
1958
+ error: () => $error.value(),
1959
+ variables: () => $variables.value(),
1960
+ status: () => $status.value(),
1961
+ pending: () => $status.value() === "pending",
1962
+ isPending: () => $status.value() === "pending",
1963
+ isSuccess: () => $status.value() === "success",
1964
+ isError: () => $status.value() === "error",
1965
+ isIdle: () => $status.value() === "idle",
1966
+ $data,
1967
+ $error,
1968
+ $variables,
1969
+ $status,
1970
+ $pendingCount,
1971
+ $abortSignal
1972
+ };
1973
+ }
1974
+ };
1975
+
1976
+ // src/mutation/mutation-instance.ts
1977
+ var createMutationInstance = (definition, client) => {
1978
+ const mutation = new Mutation(definition, client, client.mutationCache);
1979
+ return mutation.toInstance();
1980
+ };
1981
+
1982
+ // src/mutation/create-mutation.ts
1983
+ var createMutation = (options, meta) => {
1984
+ const provider = meta?.provider ?? getQueryProvider();
1985
+ const mergedOptions = {
1986
+ ...provider?.config.defaultOptions?.mutations,
1987
+ ...options
1988
+ };
1989
+ return {
1990
+ kind: "mutation-definition",
1991
+ name: mergedOptions.name,
1992
+ options: mergedOptions,
1993
+ create(opts) {
1994
+ const client = opts?.client ?? provider?.client ?? getDefaultQueryClient();
1995
+ return createMutationInstance(
1996
+ {
1997
+ kind: "mutation-definition",
1998
+ name: mergedOptions.name,
1999
+ options: mergedOptions,
2000
+ create: this.create
2001
+ },
2002
+ client
2003
+ );
2004
+ }
2005
+ };
2006
+ };
2007
+
2008
+ // src/provider/query-provider.ts
2009
+ var QueryProvider = class {
2010
+ client;
2011
+ config;
2012
+ constructor(config = {}) {
2013
+ this.client = config.client ?? createQueryClient(config);
2014
+ this.config = { ...config, client: this.client };
2015
+ }
2016
+ createQuery = (options) => createQuery(options, { provider: this });
2017
+ createMutation = (options) => createMutation(options, { provider: this });
2018
+ createInfiniteQuery = (options) => createInfiniteQuery(options, { provider: this });
2019
+ invalidateQueries(filter, options) {
2020
+ this.client.invalidateQueries(filter, options);
2021
+ }
2022
+ refetchQueries(filter) {
2023
+ return this.client.refetchQueries(filter);
2024
+ }
2025
+ cancelQueries(filter) {
2026
+ this.client.cancelQueries(filter);
2027
+ }
2028
+ removeQueries(filter) {
2029
+ this.client.removeQueries(filter);
2030
+ }
2031
+ };
2032
+ var setQueryProvider = (provider) => {
2033
+ setActiveQueryProvider(provider);
2034
+ setDefaultQueryClient(provider.client);
2035
+ };
2036
+
2037
+ // src/plugin/query-plugin.ts
2038
+ var QUERY_PROVIDER_KEY = /* @__PURE__ */ Symbol.for("echojs.query.provider");
2039
+ var createQueryProvider = (config = {}) => {
2040
+ const provider = new QueryProvider(config);
2041
+ setQueryProvider(provider);
2042
+ return {
2043
+ name: "query",
2044
+ provider,
2045
+ setup(app) {
2046
+ app.provide?.(QUERY_PROVIDER_KEY, provider);
2047
+ }
2048
+ };
2049
+ };
2050
+ var createQueryPlugin = createQueryProvider;
2051
+ var queryPlugin = createQueryProvider;
2052
+
2053
+ // src/managers/refetch-stale.ts
2054
+ var refetchStaleActiveQueries = (_client, reason) => {
2055
+ for (const client of getRegisteredClients()) {
2056
+ if (reason === "focus") {
2057
+ client.queryCache.onFocus();
2058
+ client.infiniteQueryCache.onFocus();
2059
+ } else {
2060
+ client.queryCache.onOnline();
2061
+ client.infiniteQueryCache.onOnline();
2062
+ }
2063
+ }
2064
+ };
2065
+
2066
+ // src/managers/focus-manager.ts
2067
+ var FocusManager = class {
2068
+ #focused = signal(
2069
+ typeof document !== "undefined" ? document.visibilityState === "visible" : true
2070
+ );
2071
+ constructor() {
2072
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
2073
+ const onVisibility = () => {
2074
+ this.setFocused(document.visibilityState === "visible");
2075
+ };
2076
+ document.addEventListener("visibilitychange", onVisibility);
2077
+ window.addEventListener("focus", () => this.setFocused(true));
2078
+ }
2079
+ }
2080
+ isFocused() {
2081
+ return this.#focused.value();
2082
+ }
2083
+ setFocused(focused) {
2084
+ this.#focused.set(focused);
2085
+ if (focused) {
2086
+ for (const client of getRegisteredClients()) {
2087
+ refetchStaleActiveQueries(client, "focus");
2088
+ }
2089
+ }
2090
+ }
2091
+ subscribe(listener) {
2092
+ return this.#focused.subscribe(() => listener(this.#focused.value()));
2093
+ }
2094
+ onClientRegistered(client) {
2095
+ if (this.isFocused()) {
2096
+ refetchStaleActiveQueries(client, "focus");
2097
+ }
2098
+ }
2099
+ };
2100
+ var focusManager = new FocusManager();
2101
+ var readOnline = () => {
2102
+ if (typeof navigator !== "undefined" && typeof navigator.onLine === "boolean") {
2103
+ return navigator.onLine;
2104
+ }
2105
+ return true;
2106
+ };
2107
+ var OnlineManager = class {
2108
+ #online = signal(readOnline());
2109
+ constructor() {
2110
+ if (typeof window !== "undefined") {
2111
+ window.addEventListener("online", () => this.setOnline(true));
2112
+ window.addEventListener("offline", () => this.setOnline(false));
2113
+ }
2114
+ }
2115
+ isOnline() {
2116
+ return this.#online.value();
2117
+ }
2118
+ setOnline(online) {
2119
+ const prev = this.#online.peek();
2120
+ this.#online.set(online);
2121
+ if (!prev && online) {
2122
+ for (const client of getRegisteredClients()) {
2123
+ refetchStaleActiveQueries(client, "reconnect");
2124
+ }
2125
+ }
2126
+ }
2127
+ subscribe(listener) {
2128
+ return this.#online.subscribe(() => listener(this.#online.value()));
2129
+ }
2130
+ onClientRegistered(client) {
2131
+ if (this.isOnline()) {
2132
+ refetchStaleActiveQueries(client, "reconnect");
2133
+ }
2134
+ }
2135
+ };
2136
+ var onlineManager = new OnlineManager();
2137
+
2138
+ export { CancelledError, FocusManager, InfiniteQuery, InfiniteQueryCache, InfiniteQueryObserver, Mutation, MutationCache, OnlineManager, QUERY_PROVIDER_KEY, Query, QueryCache, QueryClient, QueryObserver, QueryProvider, abortWithReason, createFetchAbortHandle, createInfiniteQuery, createMutation, createQuery, createQueryClient, createQueryPlugin, createQueryProvider, focusManager, getDefaultQueryClient, getQueryProvider, hasInfiniteNextPage, hasInfinitePreviousPage, hashKey, isCancelledError, matchQuery, mergeFetchAbortSource, onlineManager, partialMatchKey, queryPlugin, requireQueryProvider, resetQueryProvider, resolveAbortInput, setDefaultQueryClient, setQueryProvider };
2139
+ //# sourceMappingURL=index.js.map
2140
+ //# sourceMappingURL=index.js.map