@krymskyimaksym/react-api-client 2.0.0-beta.2 → 2.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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useCallback, useState, useEffect, useMemo, createElement, useContext, useRef } from 'react';
1
+ import { createContext, useCallback, useState, useEffect, useRef, useMemo, createElement, useContext } from 'react';
2
2
 
3
3
  // src/config.ts
4
4
  var globalConfig = null;
@@ -110,6 +110,19 @@ async function executeRequest(endpoint, fetchConfig, params, signal) {
110
110
  signal
111
111
  });
112
112
  }
113
+ if (config.responseAdapter) {
114
+ const adapter = config.responseAdapter;
115
+ if (adapter.isBusinessError?.(response)) {
116
+ const err = adapter.toError?.(response, 200) ?? new ApiError({
117
+ message: "Business error",
118
+ status: 200,
119
+ raw: response
120
+ });
121
+ throw err;
122
+ }
123
+ const unwrapped = adapter.unwrap ? adapter.unwrap(response) : response;
124
+ return unwrapped;
125
+ }
113
126
  const hasExplicitStatus = response && typeof response === "object" && "status" in response && typeof response.status === "boolean";
114
127
  if (config.throwOnError && hasExplicitStatus && response.status === false) {
115
128
  throw businessErrorToApiError(response);
@@ -127,6 +140,13 @@ async function executeRequest(endpoint, fetchConfig, params, signal) {
127
140
  if (httpStatus === 401 && config.onUnauthorized) {
128
141
  await config.onUnauthorized();
129
142
  }
143
+ if (config.responseAdapter) {
144
+ const adapter = config.responseAdapter;
145
+ const body = error.response?.data ?? void 0;
146
+ const status = httpStatus ?? 0;
147
+ const err = adapter.toError?.(body, status) ?? toApiError(e);
148
+ throw err;
149
+ }
130
150
  if (config.throwOnError) {
131
151
  throw toApiError(e);
132
152
  }
@@ -366,6 +386,7 @@ var QueryCache = class {
366
386
  isStale: false
367
387
  };
368
388
  this.notify(entry);
389
+ return next;
369
390
  }
370
391
  /**
371
392
  * Подписка на изменения ключа. Возвращает unsubscribe.
@@ -489,10 +510,16 @@ var QueryCache = class {
489
510
  return Promise.all(promises).then(() => void 0);
490
511
  }
491
512
  /**
492
- * Отменяет «привязку» inflight-промиса к ключу. Сам HTTP-запрос
493
- * продолжит исполняться (executeRequest не использует AbortSignal),
494
- * но его результат больше не попадёт в кэш и не уведомит подписчиков.
495
- * Полезно при размонтировании / при переключении страниц.
513
+ * Отменяет inflight-запрос: пробрасывает abort через `AbortSignal`
514
+ * в `queryFn` (т.е. в `executeRequest` `httpClient`) и отвязывает
515
+ * результат от ключа.
516
+ *
517
+ * Если `httpClient` уважает `signal` (`fetch` нативный, axios v1+
518
+ * с `signal`, и т.п.) — HTTP-запрос реально прерывается. Если
519
+ * игнорирует — поведение деградирует: запрос продолжит исполняться,
520
+ * но его ответ уже не попадёт в кэш и подписчиков не уведомит.
521
+ *
522
+ * Полезно при размонтировании / переключении страниц / logout'е.
496
523
  */
497
524
  cancelQueries(predicate) {
498
525
  const match = typeof predicate === "function" ? predicate : (k) => matchQueryKey(predicate, k);
@@ -580,6 +607,63 @@ var QueryCache = class {
580
607
  }
581
608
  };
582
609
 
610
+ // src/query/mutation-counter.ts
611
+ var MutationCounter = class {
612
+ constructor() {
613
+ this.active = /* @__PURE__ */ new Map();
614
+ this.listeners = /* @__PURE__ */ new Set();
615
+ }
616
+ start(scope, controller) {
617
+ const id = Symbol("mutation");
618
+ this.active.set(id, { scope, controller: controller ?? new AbortController() });
619
+ this.notify();
620
+ return id;
621
+ }
622
+ stop(id) {
623
+ if (this.active.delete(id)) this.notify();
624
+ }
625
+ /**
626
+ * Отменяет inflight-мутации. Без predicate — все.
627
+ * С predicate (префикс QueryKey или функция-предикат scope'а) —
628
+ * только матчинг.
629
+ */
630
+ cancel(predicate) {
631
+ for (const rec of this.active.values()) {
632
+ if (!predicate) {
633
+ rec.controller.abort();
634
+ continue;
635
+ }
636
+ if (typeof predicate === "function") {
637
+ if (predicate(rec.scope)) rec.controller.abort();
638
+ } else if (rec.scope && matchQueryKey(predicate, rec.scope)) {
639
+ rec.controller.abort();
640
+ }
641
+ }
642
+ }
643
+ count(predicate) {
644
+ if (!predicate) return this.active.size;
645
+ let n = 0;
646
+ for (const rec of this.active.values()) {
647
+ if (typeof predicate === "function") {
648
+ if (predicate(rec.scope)) n++;
649
+ } else {
650
+ if (rec.scope && matchQueryKey(predicate, rec.scope)) n++;
651
+ }
652
+ }
653
+ return n;
654
+ }
655
+ subscribe(listener) {
656
+ this.listeners.add(listener);
657
+ return () => {
658
+ this.listeners.delete(listener);
659
+ };
660
+ }
661
+ notify() {
662
+ for (const l of this.listeners) l();
663
+ }
664
+ };
665
+ var mutationCounter = new MutationCounter();
666
+
583
667
  // src/query/client.ts
584
668
  var QueryClient = class {
585
669
  constructor(cache) {
@@ -588,8 +672,12 @@ var QueryClient = class {
588
672
  getQueryData(key) {
589
673
  return this.cache.getData(key);
590
674
  }
675
+ /**
676
+ * Точечно патчит данные под ключом. Возвращает новое значение —
677
+ * удобно для «пропатчил → передал дальше».
678
+ */
591
679
  setQueryData(key, updater) {
592
- this.cache.setData(key, updater);
680
+ return this.cache.setData(key, updater);
593
681
  }
594
682
  fetchQuery(key, queryFn, options) {
595
683
  return this.cache.fetch(key, queryFn, options);
@@ -604,12 +692,37 @@ var QueryClient = class {
604
692
  cancelQueries(predicate) {
605
693
  this.cache.cancelQueries(predicate);
606
694
  }
695
+ /**
696
+ * Отменяет inflight-мутации через `AbortSignal`. Без аргумента — все.
697
+ * С префиксом QueryKey или функцией-предикатом — только матчинг
698
+ * (scope мутации = первый ключ из её `invalidateKeys`, если задан массив).
699
+ *
700
+ * Если `httpClient` уважает `signal` — HTTP-запрос реально прерывается;
701
+ * иначе результат отменённой мутации просто не повлияет на UI
702
+ * (`useMutation` останется в текущем состоянии).
703
+ *
704
+ * Типичный кейс — logout: `client.cancelMutations()` перед очисткой
705
+ * сессии, чтобы поздние ответы не сработали.
706
+ */
707
+ cancelMutations(predicate) {
708
+ mutationCounter.cancel(predicate);
709
+ }
607
710
  refetchQueries(predicate) {
608
711
  return this.cache.refetchQueries(predicate);
609
712
  }
610
713
  /**
611
- * Кладёт запрос в кэш, не пробрасывая ошибки. Подходит для оптимистичной
612
- * подгрузки следующего экрана при наведении / долгом тапе.
714
+ * Кладёт запрос в кэш, не пробрасывая ошибки. Подходит для
715
+ * оптимистичной подгрузки следующего экрана при наведении / долгом тапе.
716
+ *
717
+ * Поведение:
718
+ * - **`staleTime`**: учитывается. Если данные ещё свежие — запрос не
719
+ * отправляется, promise резолвится сразу.
720
+ * - **`inflight`**: если по ключу уже идёт запрос, prefetch присоединяется
721
+ * к нему (dedupe). Не создаёт второй HTTP-вызов.
722
+ * - **Подписчики**: если на ключ подписан `useFetch`, успешный prefetch
723
+ * обновит его `data` (через notify подписчиков). При ошибке — статус
724
+ * подписчика тоже обновится (`error`).
725
+ * - **Возвращаемый promise**: всегда успешный — ошибки не пробрасываются.
613
726
  */
614
727
  prefetchQuery(key, queryFn, options) {
615
728
  return this.cache.fetch(key, queryFn, options).then(
@@ -636,11 +749,12 @@ function createUseFetch(endpoint, fetchConfig) {
636
749
  refetchOnFocus = false,
637
750
  refetchOnAppActive = false,
638
751
  refetchOnReconnect = false,
639
- staleTime = 0,
752
+ staleTime = isConfigured() ? getConfig().defaultStaleTime ?? 0 : 0,
640
753
  gcTime,
641
754
  pollingInterval,
642
755
  queryKey: customKey,
643
756
  select,
757
+ selectIsEqual,
644
758
  onSuccess,
645
759
  onError
646
760
  } = options;
@@ -757,11 +871,19 @@ function createUseFetch(endpoint, fetchConfig) {
757
871
  }, [enabled, pollingInterval, runFetch]);
758
872
  const state = cache.getState(queryKey) ?? initialState;
759
873
  const rawData = state?.data ?? null;
874
+ const lastSelectedRef = useRef(null);
760
875
  const selectedData = useMemo(() => {
761
- if (rawData === null) return null;
762
- if (!select) return rawData;
763
- return select(rawData);
764
- }, [rawData, select]);
876
+ if (rawData === null) {
877
+ lastSelectedRef.current = null;
878
+ return null;
879
+ }
880
+ const next = select ? select(rawData) : rawData;
881
+ const prev = lastSelectedRef.current;
882
+ const isEqual = selectIsEqual ?? Object.is;
883
+ if (prev !== null && isEqual(prev, next)) return prev;
884
+ lastSelectedRef.current = next;
885
+ return next;
886
+ }, [rawData, select, selectIsEqual]);
765
887
  const status = state?.status ?? "idle";
766
888
  const hasData = rawData !== null;
767
889
  const isLoading = status === "loading" && !hasData;
@@ -779,47 +901,6 @@ function createUseFetch(endpoint, fetchConfig) {
779
901
  };
780
902
  };
781
903
  }
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
823
904
  function createUseMutation(endpoint, fetchConfig) {
824
905
  return (options = {}) => {
825
906
  const {
@@ -872,7 +953,8 @@ function createUseMutation(endpoint, fetchConfig) {
872
953
  setIsError(false);
873
954
  setError(null);
874
955
  const scope = Array.isArray(invalidateKeys) && invalidateKeys.length > 0 ? invalidateKeys[0] : void 0;
875
- const mutationId = mutationCounter.start(scope);
956
+ const controller = new AbortController();
957
+ const mutationId = mutationCounter.start(scope, controller);
876
958
  const endpointId = buildEndpoint(endpoint, variables);
877
959
  callLogger("onMutationStart", endpointId, variables);
878
960
  let context;
@@ -881,7 +963,7 @@ function createUseMutation(endpoint, fetchConfig) {
881
963
  const ctx = await onMutate(variables);
882
964
  context = ctx;
883
965
  }
884
- const result = await executeRequest(endpoint, fetchConfig, variables);
966
+ const result = await executeRequest(endpoint, fetchConfig, variables, controller.signal);
885
967
  setData(result);
886
968
  if (result.status) {
887
969
  setIsSuccess(true);
@@ -957,10 +1039,12 @@ function createUsePaginate(endpoint, fetchConfig, options) {
957
1039
  enabled = true,
958
1040
  initialPage = 1,
959
1041
  initialLimit = 20,
960
- staleTime = 0,
1042
+ staleTime = isConfigured() ? getConfig().defaultStaleTime ?? 0 : 0,
961
1043
  gcTime,
962
1044
  keepPreviousData = false,
963
1045
  queryKey: customKey,
1046
+ select,
1047
+ selectIsEqual,
964
1048
  onSuccess,
965
1049
  onError
966
1050
  } = hookOptions;
@@ -1061,7 +1145,16 @@ function createUsePaginate(endpoint, fetchConfig, options) {
1061
1145
  const currentResult = currentState?.data;
1062
1146
  const usingPlaceholder = keepPreviousData && !currentResult && previousPageKeyRef.current !== null;
1063
1147
  const effectiveResult = usingPlaceholder ? cache.getData(previousPageKeyRef.current) : currentResult;
1064
- const data = effectiveResult && effectiveResult.status ? dataExtractor(effectiveResult) : [];
1148
+ const rawData = effectiveResult && effectiveResult.status ? dataExtractor(effectiveResult) : [];
1149
+ const lastSelectedRef = useRef(null);
1150
+ const data = useMemo(() => {
1151
+ const next = select ? select(rawData) : rawData;
1152
+ const prev = lastSelectedRef.current;
1153
+ const isEqual = selectIsEqual ?? Object.is;
1154
+ if (prev !== null && isEqual(prev, next)) return prev;
1155
+ lastSelectedRef.current = next;
1156
+ return next;
1157
+ }, [rawData, select, selectIsEqual]);
1065
1158
  const totalCount = effectiveResult && effectiveResult.status ? totalExtractor(effectiveResult) : null;
1066
1159
  const total = totalCount;
1067
1160
  const totalPages = totalCount !== null ? Math.ceil(totalCount / limit) : null;
@@ -1150,6 +1243,226 @@ function useIsMutating(predicate) {
1150
1243
  }, [get]);
1151
1244
  return count;
1152
1245
  }
1246
+ function useQuery(queryKey, queryFn, options = {}) {
1247
+ const {
1248
+ enabled = true,
1249
+ refetchOnMount = true,
1250
+ refetchOnFocus = false,
1251
+ refetchOnAppActive = false,
1252
+ refetchOnReconnect = false,
1253
+ staleTime = 0,
1254
+ gcTime,
1255
+ pollingInterval,
1256
+ select,
1257
+ selectIsEqual
1258
+ } = options;
1259
+ const client = getQueryClient();
1260
+ const cache = client.cache;
1261
+ const [, forceRender] = useState(0);
1262
+ const rerender = useCallback(() => forceRender((v) => v + 1), []);
1263
+ useEffect(() => {
1264
+ const unsub = cache.subscribe(queryKey, rerender);
1265
+ return () => {
1266
+ unsub();
1267
+ const state2 = cache._debugEntries().get(hashQueryKey(queryKey));
1268
+ if (state2 && state2.subscribers.size === 0 && state2.inflight) {
1269
+ cache.cancelQueries(queryKey);
1270
+ }
1271
+ };
1272
+ }, [cache, hashQueryKey(queryKey), rerender]);
1273
+ const runFetch = useCallback(
1274
+ async (force) => {
1275
+ callLogger("onFetchStart", queryKey);
1276
+ try {
1277
+ const data = await cache.fetch(queryKey, queryFn, {
1278
+ staleTime,
1279
+ gcTime,
1280
+ force
1281
+ });
1282
+ callLogger("onFetchSuccess", queryKey, data);
1283
+ } catch (err) {
1284
+ callLogger("onFetchError", queryKey, err);
1285
+ }
1286
+ },
1287
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1288
+ [cache, hashQueryKey(queryKey), queryFn, staleTime, gcTime]
1289
+ );
1290
+ useEffect(() => {
1291
+ if (!enabled || !refetchOnMount) return;
1292
+ void runFetch(false);
1293
+ }, [enabled, refetchOnMount, runFetch]);
1294
+ const stateForEffect = cache.getState(queryKey);
1295
+ const isStale = stateForEffect?.isStale ?? false;
1296
+ const hasFetchedData = stateForEffect?.data !== void 0;
1297
+ useEffect(() => {
1298
+ if (!enabled) return;
1299
+ if (isStale && hasFetchedData) void runFetch(true);
1300
+ }, [enabled, isStale, hasFetchedData, runFetch]);
1301
+ useEffect(() => {
1302
+ if (!enabled) return;
1303
+ if (!refetchOnFocus && !refetchOnAppActive) return;
1304
+ const unsub = focusManager.subscribe((focused) => {
1305
+ if (focused) void runFetch(false);
1306
+ });
1307
+ return unsub;
1308
+ }, [enabled, refetchOnFocus, refetchOnAppActive, runFetch]);
1309
+ useEffect(() => {
1310
+ if (!enabled || !refetchOnReconnect) return;
1311
+ const unsub = onlineManager.subscribe((online) => {
1312
+ if (online) void runFetch(false);
1313
+ });
1314
+ return unsub;
1315
+ }, [enabled, refetchOnReconnect, runFetch]);
1316
+ useEffect(() => {
1317
+ if (!enabled || !pollingInterval || pollingInterval <= 0) return;
1318
+ let timer = null;
1319
+ const start = () => {
1320
+ if (timer) return;
1321
+ timer = setInterval(() => {
1322
+ if (focusManager.isFocused()) void runFetch(true);
1323
+ }, pollingInterval);
1324
+ };
1325
+ const stop = () => {
1326
+ if (timer) clearInterval(timer);
1327
+ timer = null;
1328
+ };
1329
+ start();
1330
+ const unsub = focusManager.subscribe((focused) => {
1331
+ if (focused) start();
1332
+ else stop();
1333
+ });
1334
+ return () => {
1335
+ stop();
1336
+ unsub();
1337
+ };
1338
+ }, [enabled, pollingInterval, runFetch]);
1339
+ const state = cache.getState(queryKey);
1340
+ const rawData = state?.data ?? null;
1341
+ const lastSelectedRef = useRef(null);
1342
+ const selectedData = useMemo(() => {
1343
+ if (rawData === null) {
1344
+ lastSelectedRef.current = null;
1345
+ return null;
1346
+ }
1347
+ const next = select ? select(rawData) : rawData;
1348
+ const prev = lastSelectedRef.current;
1349
+ const isEqual = selectIsEqual ?? Object.is;
1350
+ if (prev !== null && isEqual(prev, next)) return prev;
1351
+ lastSelectedRef.current = next;
1352
+ return next;
1353
+ }, [rawData, select, selectIsEqual]);
1354
+ const status = state?.status ?? "idle";
1355
+ const hasData = rawData !== null;
1356
+ const isLoading = status === "loading" && !hasData;
1357
+ const isRefetching = status === "loading" && hasData;
1358
+ const error = state?.error ?? null;
1359
+ const refetch = useCallback(async () => {
1360
+ await runFetch(true);
1361
+ }, [runFetch]);
1362
+ return {
1363
+ data: selectedData,
1364
+ isLoading: enabled ? isLoading : false,
1365
+ isRefetching,
1366
+ error,
1367
+ refetch
1368
+ };
1369
+ }
1370
+ function useQueriesData(keys) {
1371
+ const client = getQueryClient();
1372
+ const get = useCallback(
1373
+ () => keys.map((k) => client.getQueryData(k)),
1374
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1375
+ [client, keys.map((k) => JSON.stringify(k)).join("|")]
1376
+ );
1377
+ const [snapshot, setSnapshot] = useState(get);
1378
+ useEffect(() => {
1379
+ setSnapshot(get());
1380
+ const unsubs = keys.map(
1381
+ (k) => client.cache.subscribe(k, () => setSnapshot(get()))
1382
+ );
1383
+ return () => {
1384
+ for (const u of unsubs) u();
1385
+ };
1386
+ }, [client, get]);
1387
+ return snapshot;
1388
+ }
1389
+
1390
+ // src/adapters.ts
1391
+ var isObject2 = (v) => typeof v === "object" && v !== null;
1392
+ var laravelAdapter = {
1393
+ isBusinessError: (r) => isObject2(r) && r.status === false,
1394
+ toError: (r, http) => {
1395
+ const body = isObject2(r) ? r : void 0;
1396
+ return new ApiError({
1397
+ message: (body && typeof body.message === "string" ? body.message : void 0) ?? `HTTP ${http}`,
1398
+ status: http,
1399
+ code: body && typeof body.code === "string" ? body.code : void 0,
1400
+ errors: body?.errors,
1401
+ isUnauthorized: http === 401,
1402
+ isValidationError: http === 422 || body?.errors !== void 0,
1403
+ raw: r
1404
+ });
1405
+ }
1406
+ };
1407
+ var jsonApiAdapter = {
1408
+ unwrap: (r) => isObject2(r) ? r.data : r,
1409
+ isBusinessError: (r) => isObject2(r) && Array.isArray(r.errors) && r.errors.length > 0,
1410
+ toError: (r, http) => {
1411
+ const errors = isObject2(r) && Array.isArray(r.errors) ? r.errors : [];
1412
+ const first = isObject2(errors[0]) ? errors[0] : void 0;
1413
+ return new ApiError({
1414
+ message: (first && typeof first.detail === "string" ? first.detail : void 0) ?? (first && typeof first.title === "string" ? first.title : void 0) ?? `HTTP ${http}`,
1415
+ status: http,
1416
+ code: first && typeof first.code === "string" ? first.code : void 0,
1417
+ errors,
1418
+ isUnauthorized: http === 401,
1419
+ isValidationError: http === 422,
1420
+ raw: r
1421
+ });
1422
+ }
1423
+ };
1424
+ var graphqlAdapter = {
1425
+ unwrap: (r) => isObject2(r) ? r.data : r,
1426
+ isBusinessError: (r) => isObject2(r) && Array.isArray(r.errors) && r.errors.length > 0,
1427
+ toError: (r, http) => {
1428
+ const errors = isObject2(r) && Array.isArray(r.errors) ? r.errors : [];
1429
+ const first = isObject2(errors[0]) ? errors[0] : void 0;
1430
+ return new ApiError({
1431
+ message: (first && typeof first.message === "string" ? first.message : void 0) ?? `HTTP ${http}`,
1432
+ status: http,
1433
+ errors,
1434
+ isUnauthorized: http === 401,
1435
+ raw: r
1436
+ });
1437
+ }
1438
+ };
1439
+ var problemJsonAdapter = {
1440
+ isBusinessError: () => false,
1441
+ toError: (r, http) => {
1442
+ const body = isObject2(r) ? r : void 0;
1443
+ return new ApiError({
1444
+ message: (body && typeof body.title === "string" ? body.title : void 0) ?? (body && typeof body.detail === "string" ? body.detail : void 0) ?? `HTTP ${http}`,
1445
+ status: http,
1446
+ code: body && typeof body.type === "string" ? body.type : void 0,
1447
+ isUnauthorized: http === 401,
1448
+ isValidationError: http === 422,
1449
+ raw: r
1450
+ });
1451
+ }
1452
+ };
1453
+ var plainAdapter = {
1454
+ isBusinessError: () => false,
1455
+ toError: (r, http) => {
1456
+ const body = isObject2(r) ? r : void 0;
1457
+ return new ApiError({
1458
+ message: (body && typeof body.message === "string" ? body.message : void 0) ?? `HTTP ${http}`,
1459
+ status: http,
1460
+ isUnauthorized: http === 401,
1461
+ isNetworkError: http === 0,
1462
+ raw: r
1463
+ });
1464
+ }
1465
+ };
1153
1466
 
1154
1467
  // src/query/persist.ts
1155
1468
  function persistQueryClient(options) {
@@ -1311,6 +1624,6 @@ function apiPaginate(endpoint, fetchConfig = {}, options) {
1311
1624
  }
1312
1625
  var index_default = apiClient;
1313
1626
 
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 };
1627
+ export { ApiClientProvider, ApiError, QueryCache, QueryClient, apiMutation, apiPaginate, businessErrorToApiError, configureApiClient, index_default as default, focusManager, getConfig, getQueryClient, graphqlAdapter, hashQueryKey, inspectCache, invalidateAll, isConfigured, jsonApiAdapter, laravelAdapter, matchQueryKey, onlineManager, persistQueryClient, plainAdapter, problemJsonAdapter, setQueryClient, summarizeCache, toApiError, useIsFetching, useIsMutating, useQueriesData, useQuery, useQueryClient };
1315
1628
  //# sourceMappingURL=index.mjs.map
1316
1629
  //# sourceMappingURL=index.mjs.map