@krymskyimaksym/react-api-client 2.0.0-beta.0 → 2.0.0-beta.2

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useMemo, createElement, useContext, useCallback, useState, useEffect, useRef } from 'react';
1
+ import { createContext, useCallback, useState, useEffect, useMemo, createElement, useContext, useRef } from 'react';
2
2
 
3
3
  // src/config.ts
4
4
  var globalConfig = null;
@@ -32,6 +32,52 @@ var ApiError = class _ApiError extends Error {
32
32
  Object.setPrototypeOf(this, _ApiError.prototype);
33
33
  }
34
34
  };
35
+ var isObject = (v) => typeof v === "object" && v !== null;
36
+ function toApiError(thrown) {
37
+ if (thrown instanceof ApiError) return thrown;
38
+ if (isObject(thrown) && "response" in thrown && isObject(thrown.response)) {
39
+ const r = thrown.response;
40
+ const status = typeof r.status === "number" ? r.status : 0;
41
+ const data = isObject(r.data) ? r.data : void 0;
42
+ const message = (data && typeof data.message === "string" ? data.message : void 0) ?? (thrown instanceof Error ? thrown.message : void 0) ?? `HTTP ${status}`;
43
+ return new ApiError({
44
+ message,
45
+ status,
46
+ code: data && typeof data.code === "string" ? data.code : void 0,
47
+ errors: data?.errors,
48
+ isNetworkError: status === 0,
49
+ isUnauthorized: status === 401,
50
+ isValidationError: status === 422 || data?.errors !== void 0,
51
+ raw: r.data ?? thrown
52
+ });
53
+ }
54
+ if (thrown instanceof Error) {
55
+ return new ApiError({
56
+ message: thrown.message,
57
+ status: 0,
58
+ isNetworkError: true,
59
+ raw: thrown
60
+ });
61
+ }
62
+ return new ApiError({
63
+ message: "Unknown error",
64
+ status: 0,
65
+ raw: thrown
66
+ });
67
+ }
68
+ function businessErrorToApiError(response) {
69
+ if (!isObject(response)) {
70
+ return new ApiError({ message: "Request failed", status: 200, raw: response });
71
+ }
72
+ return new ApiError({
73
+ message: typeof response.message === "string" ? response.message : "Request failed",
74
+ status: 200,
75
+ code: typeof response.code === "string" ? response.code : void 0,
76
+ errors: response.errors,
77
+ isValidationError: response.errors !== void 0,
78
+ raw: response
79
+ });
80
+ }
35
81
 
36
82
  // src/utils.ts
37
83
  function buildEndpoint(endpoint, params) {
@@ -40,7 +86,7 @@ function buildEndpoint(endpoint, params) {
40
86
  }
41
87
  return endpoint;
42
88
  }
43
- async function executeRequest(endpoint, fetchConfig, params) {
89
+ async function executeRequest(endpoint, fetchConfig, params, signal) {
44
90
  const url = buildEndpoint(endpoint, params);
45
91
  const config = getConfig();
46
92
  try {
@@ -51,7 +97,8 @@ async function executeRequest(endpoint, fetchConfig, params) {
51
97
  params: {
52
98
  ...requestConfig.requestParams,
53
99
  ...params
54
- }
100
+ },
101
+ signal
55
102
  });
56
103
  } else {
57
104
  response = await config.httpClient.request(url, {
@@ -59,38 +106,29 @@ async function executeRequest(endpoint, fetchConfig, params) {
59
106
  data: {
60
107
  ...requestConfig.requestParams,
61
108
  ...params
62
- }
109
+ },
110
+ signal
63
111
  });
64
112
  }
65
113
  const hasExplicitStatus = response && typeof response === "object" && "status" in response && typeof response.status === "boolean";
66
114
  if (config.throwOnError && hasExplicitStatus && response.status === false) {
67
- const body = response;
68
- throw new ApiError({
69
- message: body.message ?? "Request failed",
70
- status: 200,
71
- errors: body.errors,
72
- raw: response
73
- });
115
+ throw businessErrorToApiError(response);
74
116
  }
75
117
  return { ...response, status: true };
76
118
  } catch (e) {
77
- if (e instanceof ApiError) throw e;
119
+ if (e instanceof ApiError) {
120
+ if (e.status === 401 && config.onUnauthorized) {
121
+ await config.onUnauthorized();
122
+ }
123
+ throw e;
124
+ }
78
125
  const error = e;
79
126
  const httpStatus = error.response?.status;
80
127
  if (httpStatus === 401 && config.onUnauthorized) {
81
128
  await config.onUnauthorized();
82
129
  }
83
130
  if (config.throwOnError) {
84
- const data = error.response?.data;
85
- const isNetwork = httpStatus === void 0;
86
- throw new ApiError({
87
- message: data?.message ?? (e instanceof Error ? e.message : void 0) ?? (isNetwork ? "Network error" : "Request error"),
88
- status: httpStatus ?? 0,
89
- code: data?.code,
90
- errors: data,
91
- isNetworkError: isNetwork,
92
- raw: e
93
- });
131
+ throw toApiError(e);
94
132
  }
95
133
  if (error.response?.data) {
96
134
  return {
@@ -113,6 +151,21 @@ function handleResponse(result, onSuccess, onError) {
113
151
  }
114
152
  }
115
153
 
154
+ // src/logger.ts
155
+ function getLogger() {
156
+ if (!isConfigured()) return void 0;
157
+ return getConfig().logger;
158
+ }
159
+ function callLogger(method, ...args) {
160
+ const logger = getLogger();
161
+ const fn = logger?.[method];
162
+ if (!fn) return;
163
+ try {
164
+ fn(...args);
165
+ } catch {
166
+ }
167
+ }
168
+
116
169
  // src/query/focus-manager.ts
117
170
  var FocusManager = class {
118
171
  constructor() {
@@ -251,6 +304,21 @@ var DEFAULT_STALE_TIME = 0;
251
304
  var QueryCache = class {
252
305
  constructor() {
253
306
  this.entries = /* @__PURE__ */ new Map();
307
+ this.globalListeners = /* @__PURE__ */ new Set();
308
+ }
309
+ /**
310
+ * Подписка на любое изменение кэша: setData, invalidate, remove,
311
+ * успешный/ошибочный fetch. Используется persistQueryClient и
312
+ * devtools-подобными адаптерами. Не дублирует `subscribe(key, ...)`.
313
+ */
314
+ subscribeAll(listener) {
315
+ this.globalListeners.add(listener);
316
+ return () => {
317
+ this.globalListeners.delete(listener);
318
+ };
319
+ }
320
+ notifyGlobal() {
321
+ for (const listener of this.globalListeners) listener();
254
322
  }
255
323
  ensureEntry(key, staleTime, gcTime) {
256
324
  const hash = hashQueryKey(key);
@@ -267,7 +335,9 @@ var QueryCache = class {
267
335
  },
268
336
  subscribers: /* @__PURE__ */ new Set(),
269
337
  inflight: null,
338
+ inflightController: null,
270
339
  gcTimer: null,
340
+ lastQueryFn: null,
271
341
  staleTime: staleTime ?? DEFAULT_STALE_TIME,
272
342
  gcTime: gcTime ?? DEFAULT_GC_TIME
273
343
  };
@@ -315,6 +385,7 @@ var QueryCache = class {
315
385
  }
316
386
  notify(entry) {
317
387
  for (const listener of entry.subscribers) listener();
388
+ this.notifyGlobal();
318
389
  }
319
390
  scheduleGc(entry) {
320
391
  if (entry.gcTimer) clearTimeout(entry.gcTimer);
@@ -337,18 +408,21 @@ var QueryCache = class {
337
408
  const gcTime = options.gcTime ?? DEFAULT_GC_TIME;
338
409
  const entry = this.ensureEntry(key, staleTime, gcTime);
339
410
  const isFresh = entry.state.status === "success" && !entry.state.isStale && Date.now() - entry.state.updatedAt < staleTime;
411
+ entry.lastQueryFn = queryFn;
340
412
  if (!options.force && isFresh && entry.state.data !== void 0) {
341
413
  return entry.state.data;
342
414
  }
343
415
  if (entry.inflight) return entry.inflight;
344
416
  entry.state = { ...entry.state, status: "loading", error: null };
345
417
  this.notify(entry);
418
+ const controller = new AbortController();
346
419
  const token = Symbol("inflight");
347
420
  entry.inflightToken = token;
421
+ entry.inflightController = controller;
348
422
  const isCurrent = () => entry.inflightToken === token;
349
423
  const myPromise = (async () => {
350
424
  try {
351
- const data = await queryFn();
425
+ const data = await queryFn({ signal: controller.signal });
352
426
  if (!isCurrent()) return data;
353
427
  entry.state = {
354
428
  data,
@@ -369,7 +443,10 @@ var QueryCache = class {
369
443
  this.notify(entry);
370
444
  throw err;
371
445
  } finally {
372
- if (isCurrent()) entry.inflight = null;
446
+ if (isCurrent()) {
447
+ entry.inflight = null;
448
+ entry.inflightController = null;
449
+ }
373
450
  }
374
451
  })();
375
452
  entry.inflight = myPromise;
@@ -391,6 +468,26 @@ var QueryCache = class {
391
468
  }
392
469
  return invalidated;
393
470
  }
471
+ /**
472
+ * Перезапускает все записи, матчинг predicate, у которых сохранён
473
+ * `lastQueryFn` (т.е. их хоть раз кто-то загрузил через `fetch`).
474
+ * Возвращает promise, который резолвится когда все запросы завершились.
475
+ * Ошибки отдельных запросов проглатываются — общий promise успешный.
476
+ */
477
+ refetchQueries(predicate) {
478
+ const match = typeof predicate === "function" ? predicate : (k) => matchQueryKey(predicate, k);
479
+ const promises = [];
480
+ for (const entry of this.entries.values()) {
481
+ if (!match(entry.key)) continue;
482
+ if (!entry.lastQueryFn) continue;
483
+ promises.push(
484
+ this.fetch(entry.key, entry.lastQueryFn, { force: true }).catch(
485
+ () => void 0
486
+ )
487
+ );
488
+ }
489
+ return Promise.all(promises).then(() => void 0);
490
+ }
394
491
  /**
395
492
  * Отменяет «привязку» inflight-промиса к ключу. Сам HTTP-запрос
396
493
  * продолжит исполняться (executeRequest не использует AbortSignal),
@@ -401,6 +498,8 @@ var QueryCache = class {
401
498
  const match = typeof predicate === "function" ? predicate : (k) => matchQueryKey(predicate, k);
402
499
  for (const entry of this.entries.values()) {
403
500
  if (match(entry.key) && entry.inflight) {
501
+ entry.inflightController?.abort();
502
+ entry.inflightController = null;
404
503
  entry.inflight = null;
405
504
  entry.inflightToken = void 0;
406
505
  if (entry.state.status === "loading") {
@@ -416,12 +515,28 @@ var QueryCache = class {
416
515
  */
417
516
  remove(predicate) {
418
517
  const match = typeof predicate === "function" ? predicate : (k) => matchQueryKey(predicate, k);
518
+ let removed = false;
419
519
  for (const [hash, entry] of [...this.entries]) {
420
520
  if (match(entry.key)) {
421
521
  if (entry.gcTimer) clearTimeout(entry.gcTimer);
422
522
  this.entries.delete(hash);
523
+ removed = true;
423
524
  }
424
525
  }
526
+ if (removed) this.notifyGlobal();
527
+ }
528
+ /**
529
+ * Количество inflight-запросов в кэше, опционально отфильтрованных
530
+ * по predicate. Используется `useIsFetching()` для глобального
531
+ * индикатора загрузки.
532
+ */
533
+ countFetching(predicate) {
534
+ const match = !predicate ? () => true : typeof predicate === "function" ? predicate : (k) => matchQueryKey(predicate, k);
535
+ let n = 0;
536
+ for (const entry of this.entries.values()) {
537
+ if (entry.state.status === "loading" && match(entry.key)) n++;
538
+ }
539
+ return n;
425
540
  }
426
541
  /** Только для тестов / DevTools. */
427
542
  _debugEntries() {
@@ -480,7 +595,8 @@ var QueryClient = class {
480
595
  return this.cache.fetch(key, queryFn, options);
481
596
  }
482
597
  invalidateQueries(predicate) {
483
- this.cache.invalidate(predicate);
598
+ const hashes = this.cache.invalidate(predicate);
599
+ if (hashes.length > 0) callLogger("onInvalidate", hashes);
484
600
  }
485
601
  removeQueries(predicate) {
486
602
  this.cache.remove(predicate);
@@ -488,6 +604,19 @@ var QueryClient = class {
488
604
  cancelQueries(predicate) {
489
605
  this.cache.cancelQueries(predicate);
490
606
  }
607
+ refetchQueries(predicate) {
608
+ return this.cache.refetchQueries(predicate);
609
+ }
610
+ /**
611
+ * Кладёт запрос в кэш, не пробрасывая ошибки. Подходит для оптимистичной
612
+ * подгрузки следующего экрана при наведении / долгом тапе.
613
+ */
614
+ prefetchQuery(key, queryFn, options) {
615
+ return this.cache.fetch(key, queryFn, options).then(
616
+ () => void 0,
617
+ () => void 0
618
+ );
619
+ }
491
620
  };
492
621
  var globalClient = null;
493
622
  function getQueryClient() {
@@ -526,27 +655,37 @@ function createUseFetch(endpoint, fetchConfig) {
526
655
  }, [customKey ? hashQueryKey(customKey) : null, serializedParams]);
527
656
  const client = getQueryClient();
528
657
  const cache = client.cache;
529
- const queryFn = useCallback(() => {
530
- const parsedParams = serializedParams ? JSON.parse(serializedParams) : void 0;
531
- return executeRequest(endpoint, fetchConfig, parsedParams);
532
- }, [serializedParams]);
658
+ const queryFn = useCallback(
659
+ ({ signal }) => {
660
+ const parsedParams = serializedParams ? JSON.parse(serializedParams) : void 0;
661
+ return executeRequest(endpoint, fetchConfig, parsedParams, signal);
662
+ },
663
+ [serializedParams]
664
+ );
533
665
  const initialState = cache.getState(queryKey);
534
666
  const [, forceRender] = useState(0);
535
667
  const rerender = useCallback(() => forceRender((v) => v + 1), []);
536
668
  useEffect(() => {
537
- if (!enabled) return;
538
669
  const unsub = cache.subscribe(queryKey, rerender);
539
- return unsub;
540
- }, [cache, enabled, hashQueryKey(queryKey), rerender]);
670
+ return () => {
671
+ unsub();
672
+ const state2 = cache._debugEntries().get(hashQueryKey(queryKey));
673
+ if (state2 && state2.subscribers.size === 0 && state2.inflight) {
674
+ cache.cancelQueries(queryKey);
675
+ }
676
+ };
677
+ }, [cache, hashQueryKey(queryKey), rerender]);
541
678
  const lastNotifiedRef = useRef({});
542
679
  const runFetch = useCallback(
543
680
  async (force) => {
681
+ callLogger("onFetchStart", queryKey);
544
682
  try {
545
683
  const data = await cache.fetch(queryKey, queryFn, {
546
684
  staleTime,
547
685
  gcTime,
548
686
  force
549
687
  });
688
+ callLogger("onFetchSuccess", queryKey, data);
550
689
  if (lastNotifiedRef.current.success !== data) {
551
690
  lastNotifiedRef.current.success = data;
552
691
  handleResponse(
@@ -556,6 +695,7 @@ function createUseFetch(endpoint, fetchConfig) {
556
695
  );
557
696
  }
558
697
  } catch (err) {
698
+ callLogger("onFetchError", queryKey, err);
559
699
  const e = err;
560
700
  const hash = `${e.name}:${e.message}`;
561
701
  if (lastNotifiedRef.current.errorHash !== hash) {
@@ -639,6 +779,47 @@ function createUseFetch(endpoint, fetchConfig) {
639
779
  };
640
780
  };
641
781
  }
782
+
783
+ // src/query/mutation-counter.ts
784
+ var MutationCounter = class {
785
+ constructor() {
786
+ this.active = /* @__PURE__ */ new Map();
787
+ this.listeners = /* @__PURE__ */ new Set();
788
+ }
789
+ start(scope) {
790
+ const id = Symbol("mutation");
791
+ this.active.set(id, scope);
792
+ this.notify();
793
+ return id;
794
+ }
795
+ stop(id) {
796
+ if (this.active.delete(id)) this.notify();
797
+ }
798
+ count(predicate) {
799
+ if (!predicate) return this.active.size;
800
+ let n = 0;
801
+ for (const scope of this.active.values()) {
802
+ if (typeof predicate === "function") {
803
+ if (predicate(scope)) n++;
804
+ } else {
805
+ if (scope && matchQueryKey(predicate, scope)) n++;
806
+ }
807
+ }
808
+ return n;
809
+ }
810
+ subscribe(listener) {
811
+ this.listeners.add(listener);
812
+ return () => {
813
+ this.listeners.delete(listener);
814
+ };
815
+ }
816
+ notify() {
817
+ for (const l of this.listeners) l();
818
+ }
819
+ };
820
+ var mutationCounter = new MutationCounter();
821
+
822
+ // src/hooks/use-mutation.ts
642
823
  function createUseMutation(endpoint, fetchConfig) {
643
824
  return (options = {}) => {
644
825
  const {
@@ -665,10 +846,21 @@ function createUseMutation(endpoint, fetchConfig) {
665
846
  (vars, result) => {
666
847
  if (!invalidateKeys) return;
667
848
  const client = getQueryClient();
668
- const keys = typeof invalidateKeys === "function" ? invalidateKeys(vars, result) : invalidateKeys;
669
- if (keys.length === 0) return;
849
+ if (Array.isArray(invalidateKeys)) {
850
+ if (invalidateKeys.length === 0) return;
851
+ client.invalidateQueries(
852
+ (k) => invalidateKeys.some((prefix) => matchQueryKey(prefix, k))
853
+ );
854
+ return;
855
+ }
856
+ const out = invalidateKeys(vars, result);
857
+ if (typeof out === "function") {
858
+ client.invalidateQueries(out);
859
+ return;
860
+ }
861
+ if (out.length === 0) return;
670
862
  client.invalidateQueries(
671
- (k) => keys.some((prefix) => matchQueryKey(prefix, k))
863
+ (k) => out.some((prefix) => matchQueryKey(prefix, k))
672
864
  );
673
865
  },
674
866
  [invalidateKeys]
@@ -679,6 +871,10 @@ function createUseMutation(endpoint, fetchConfig) {
679
871
  setIsSuccess(false);
680
872
  setIsError(false);
681
873
  setError(null);
874
+ const scope = Array.isArray(invalidateKeys) && invalidateKeys.length > 0 ? invalidateKeys[0] : void 0;
875
+ const mutationId = mutationCounter.start(scope);
876
+ const endpointId = buildEndpoint(endpoint, variables);
877
+ callLogger("onMutationStart", endpointId, variables);
682
878
  let context;
683
879
  try {
684
880
  if (onMutate) {
@@ -689,6 +885,7 @@ function createUseMutation(endpoint, fetchConfig) {
689
885
  setData(result);
690
886
  if (result.status) {
691
887
  setIsSuccess(true);
888
+ callLogger("onMutationSuccess", endpointId, variables, result);
692
889
  if (setQueryData) {
693
890
  setQueryData(getQueryClient(), variables, result);
694
891
  }
@@ -700,6 +897,7 @@ function createUseMutation(endpoint, fetchConfig) {
700
897
  const err = new Error(result.message ?? "Mutation failed");
701
898
  setIsError(true);
702
899
  setError(err);
900
+ callLogger("onMutationError", endpointId, variables, err);
703
901
  if (onError) {
704
902
  await onError(err, variables, context);
705
903
  }
@@ -713,6 +911,7 @@ function createUseMutation(endpoint, fetchConfig) {
713
911
  setError(error2);
714
912
  setIsError(true);
715
913
  setIsSuccess(false);
914
+ callLogger("onMutationError", endpointId, variables, error2);
716
915
  if (onError) {
717
916
  await onError(error2, variables, context);
718
917
  }
@@ -721,6 +920,7 @@ function createUseMutation(endpoint, fetchConfig) {
721
920
  }
722
921
  throw error2;
723
922
  } finally {
923
+ mutationCounter.stop(mutationId);
724
924
  setIsLoading(false);
725
925
  }
726
926
  },
@@ -797,14 +997,14 @@ function createUsePaginate(endpoint, fetchConfig, options) {
797
997
  [keyPrefix, limit]
798
998
  );
799
999
  const pageQueryFn = useCallback(
800
- (page) => () => {
1000
+ (page) => ({ signal }) => {
801
1001
  const parsedParams = serializedParams ? JSON.parse(serializedParams) : {};
802
1002
  const requestParams = {
803
1003
  ...parsedParams,
804
1004
  page,
805
1005
  limit
806
1006
  };
807
- return executeRequest(endpoint, fetchConfig, requestParams);
1007
+ return executeRequest(endpoint, fetchConfig, requestParams, signal);
808
1008
  },
809
1009
  [serializedParams, limit]
810
1010
  );
@@ -923,6 +1123,33 @@ function createUsePaginate(endpoint, fetchConfig, options) {
923
1123
  };
924
1124
  };
925
1125
  }
1126
+ function useIsFetching(predicate) {
1127
+ const client = getQueryClient();
1128
+ const get = useCallback(
1129
+ () => client.cache.countFetching(predicate),
1130
+ [client.cache, predicate]
1131
+ );
1132
+ const [count, setCount] = useState(get);
1133
+ useEffect(() => {
1134
+ setCount(get());
1135
+ const unsub = client.cache.subscribeAll(() => setCount(get()));
1136
+ return unsub;
1137
+ }, [client.cache, get]);
1138
+ return count;
1139
+ }
1140
+ function useIsMutating(predicate) {
1141
+ const get = useCallback(
1142
+ () => mutationCounter.count(predicate),
1143
+ [predicate]
1144
+ );
1145
+ const [count, setCount] = useState(get);
1146
+ useEffect(() => {
1147
+ setCount(get());
1148
+ const unsub = mutationCounter.subscribe(() => setCount(get()));
1149
+ return unsub;
1150
+ }, [get]);
1151
+ return count;
1152
+ }
926
1153
 
927
1154
  // src/query/persist.ts
928
1155
  function persistQueryClient(options) {
@@ -935,19 +1162,26 @@ function persistQueryClient(options) {
935
1162
  maxAge,
936
1163
  version
937
1164
  } = options;
938
- let timer = null;
1165
+ let pendingTimer = null;
939
1166
  let lastSerialized = null;
1167
+ let unsubscribed = false;
940
1168
  const persist = async () => {
941
1169
  const state = client.cache.dehydrate(allowList);
942
- if (state.queries.length === 0) {
943
- return;
944
- }
1170
+ if (state.queries.length === 0) return;
945
1171
  const snap = { version, savedAt: Date.now(), state };
946
1172
  const serialized = JSON.stringify(snap);
947
1173
  if (serialized === lastSerialized) return;
948
1174
  lastSerialized = serialized;
949
1175
  await storage.setItem(storageKey, serialized);
950
1176
  };
1177
+ const scheduleWrite = () => {
1178
+ if (unsubscribed) return;
1179
+ if (pendingTimer) return;
1180
+ pendingTimer = setTimeout(() => {
1181
+ pendingTimer = null;
1182
+ void persist();
1183
+ }, throttleMs);
1184
+ };
951
1185
  const restore = async () => {
952
1186
  const raw = await storage.getItem(storageKey);
953
1187
  if (!raw) return;
@@ -966,15 +1200,17 @@ function persistQueryClient(options) {
966
1200
  await storage.removeItem(storageKey);
967
1201
  }
968
1202
  };
969
- timer = setInterval(() => {
970
- void persist();
971
- }, throttleMs);
1203
+ const unsubscribeFromCache = client.cache.subscribeAll(scheduleWrite);
972
1204
  return {
973
1205
  restore,
974
1206
  persist,
975
1207
  unsubscribe: () => {
976
- if (timer) clearInterval(timer);
977
- timer = null;
1208
+ unsubscribed = true;
1209
+ unsubscribeFromCache();
1210
+ if (pendingTimer) {
1211
+ clearTimeout(pendingTimer);
1212
+ pendingTimer = null;
1213
+ }
978
1214
  }
979
1215
  };
980
1216
  }
@@ -1075,6 +1311,6 @@ function apiPaginate(endpoint, fetchConfig = {}, options) {
1075
1311
  }
1076
1312
  var index_default = apiClient;
1077
1313
 
1078
- export { ApiClientProvider, ApiError, QueryCache, QueryClient, apiMutation, apiPaginate, configureApiClient, index_default as default, focusManager, getConfig, getQueryClient, hashQueryKey, inspectCache, invalidateAll, isConfigured, matchQueryKey, onlineManager, persistQueryClient, setQueryClient, summarizeCache, useQueryClient };
1314
+ export { ApiClientProvider, ApiError, QueryCache, QueryClient, apiMutation, apiPaginate, businessErrorToApiError, configureApiClient, index_default as default, focusManager, getConfig, getQueryClient, hashQueryKey, inspectCache, invalidateAll, isConfigured, matchQueryKey, onlineManager, persistQueryClient, setQueryClient, summarizeCache, toApiError, useIsFetching, useIsMutating, useQueryClient };
1079
1315
  //# sourceMappingURL=index.mjs.map
1080
1316
  //# sourceMappingURL=index.mjs.map