@krymskyimaksym/react-api-client 1.0.0 → 2.0.0-beta.1

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.d.mts CHANGED
@@ -1,3 +1,151 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ type QueryKey = readonly unknown[];
5
+ /**
6
+ * Стабильная сериализация ключа кэша.
7
+ * - Объекты сериализуются с сортировкой ключей.
8
+ * - Массивы сохраняют порядок.
9
+ * - Функции и symbol — недопустимы (как в TanStack Query), кидаем.
10
+ * - undefined в массиве становится null, в объекте — поле пропускается.
11
+ *
12
+ * Пример: ['orders', { sort: 'date', dir: 'asc' }] и
13
+ * ['orders', { dir: 'asc', sort: 'date' }] дают одинаковый hash.
14
+ */
15
+ declare function hashQueryKey(key: QueryKey): string;
16
+ /**
17
+ * Проверяет, начинается ли `key` с `prefix`.
18
+ * Используется для invalidateQueries по префиксу: ['orders'] матчит
19
+ * и ['orders', 'manager'], и ['orders', 960].
20
+ */
21
+ declare function matchQueryKey(prefix: QueryKey, key: QueryKey): boolean;
22
+
23
+ type QueryStatus = 'idle' | 'loading' | 'success' | 'error';
24
+ type QueryState<T> = {
25
+ data: T | undefined;
26
+ error: Error | null;
27
+ status: QueryStatus;
28
+ updatedAt: number;
29
+ isStale: boolean;
30
+ };
31
+ type Listener$2 = () => void;
32
+ type QueryEntry<T> = {
33
+ key: QueryKey;
34
+ state: QueryState<T>;
35
+ subscribers: Set<Listener$2>;
36
+ inflight: Promise<T> | null;
37
+ inflightController: AbortController | null;
38
+ gcTimer: ReturnType<typeof setTimeout> | null;
39
+ staleTime: number;
40
+ gcTime: number;
41
+ };
42
+ type QueryFnContext = {
43
+ signal: AbortSignal;
44
+ };
45
+ /**
46
+ * queryFn принимает контекст с AbortSignal. Если HTTP-клиент его
47
+ * использует — отмена будет реальной; если игнорирует — поведение
48
+ * деградирует до текущего (запрос идёт до конца, но кэш игнорирует результат).
49
+ *
50
+ * Для обратной совместимости старая сигнатура `() => Promise<T>` тоже
51
+ * принимается — пакет просто не передаст signal внутрь.
52
+ */
53
+ type QueryFn<T> = (ctx: QueryFnContext) => Promise<T>;
54
+ type FetchOptions = {
55
+ staleTime?: number;
56
+ gcTime?: number;
57
+ /** Если true — игнорируем staleTime и форсим запрос */
58
+ force?: boolean;
59
+ };
60
+ /**
61
+ * In-memory кэш запросов с подпиской по ключу, dedupe inflight-промисов
62
+ * и сборкой мусора через gcTime.
63
+ */
64
+ declare class QueryCache {
65
+ private entries;
66
+ private globalListeners;
67
+ /**
68
+ * Подписка на любое изменение кэша: setData, invalidate, remove,
69
+ * успешный/ошибочный fetch. Используется persistQueryClient и
70
+ * devtools-подобными адаптерами. Не дублирует `subscribe(key, ...)`.
71
+ */
72
+ subscribeAll(listener: Listener$2): () => void;
73
+ private notifyGlobal;
74
+ private ensureEntry;
75
+ getState<T>(key: QueryKey): QueryState<T> | undefined;
76
+ getData<T>(key: QueryKey): T | undefined;
77
+ setData<T>(key: QueryKey, updater: T | ((prev: T | undefined) => T)): void;
78
+ /**
79
+ * Подписка на изменения ключа. Возвращает unsubscribe.
80
+ * Подписка останавливает GC таймер; отписка — запускает его обратно.
81
+ */
82
+ subscribe(key: QueryKey, listener: Listener$2): () => void;
83
+ private notify;
84
+ private scheduleGc;
85
+ /**
86
+ * Запускает или присоединяется к inflight-запросу.
87
+ * Если данные свежие (не stale) и не force — отдаёт кэш без запроса.
88
+ */
89
+ fetch<T>(key: QueryKey, queryFn: QueryFn<T>, options?: FetchOptions): Promise<T>;
90
+ /**
91
+ * Помечает запись как stale. Сами по себе данные не удаляются.
92
+ * Если есть подписчики — они получат уведомление, чтобы инициировать refetch.
93
+ */
94
+ invalidate(predicate: QueryKey | ((key: QueryKey) => boolean)): string[];
95
+ /**
96
+ * Отменяет «привязку» inflight-промиса к ключу. Сам HTTP-запрос
97
+ * продолжит исполняться (executeRequest не использует AbortSignal),
98
+ * но его результат больше не попадёт в кэш и не уведомит подписчиков.
99
+ * Полезно при размонтировании / при переключении страниц.
100
+ */
101
+ cancelQueries(predicate: QueryKey | ((key: QueryKey) => boolean)): void;
102
+ /**
103
+ * Полностью удаляет записи (даже с активными подписчиками).
104
+ * Используется редко — обычно достаточно invalidate.
105
+ */
106
+ remove(predicate: QueryKey | ((key: QueryKey) => boolean)): void;
107
+ /** Только для тестов / DevTools. */
108
+ _debugEntries(): ReadonlyMap<string, QueryEntry<unknown>>;
109
+ /**
110
+ * Сериализует записи со статусом success — для persistence.
111
+ * inflight / loading / error не сохраняются, чтобы не гидратировать
112
+ * приложение в полу-загруженном состоянии.
113
+ */
114
+ dehydrate(filter?: (key: QueryKey) => boolean): DehydratedState;
115
+ hydrate(state: DehydratedState): void;
116
+ }
117
+ type DehydratedQuery = {
118
+ key: unknown[];
119
+ data: unknown;
120
+ updatedAt: number;
121
+ };
122
+ type DehydratedState = {
123
+ queries: DehydratedQuery[];
124
+ };
125
+
126
+ /**
127
+ * Высокоуровневый фасад над QueryCache: единый объект, который удобно
128
+ * прокидывать через Provider и дергать из push-handler'ов / эффектов.
129
+ *
130
+ * Сами queryFn-ы здесь не регистрируются — refetchQueries требует, чтобы
131
+ * либо подписчик сам перезапустил запрос (через subscribe), либо чтобы
132
+ * вызвали fetchQuery с queryFn вручную. Это намеренно: хук React сам
133
+ * знает, как собрать свой queryFn из endpoint/params.
134
+ */
135
+ declare class QueryClient {
136
+ readonly cache: QueryCache;
137
+ constructor(cache?: QueryCache);
138
+ getQueryData<T>(key: QueryKey): T | undefined;
139
+ setQueryData<T>(key: QueryKey, updater: T | ((prev: T | undefined) => T)): void;
140
+ fetchQuery<T>(key: QueryKey, queryFn: QueryFn<T>, options?: FetchOptions): Promise<T>;
141
+ invalidateQueries(predicate: QueryKey | ((key: QueryKey) => boolean)): void;
142
+ removeQueries(predicate: QueryKey | ((key: QueryKey) => boolean)): void;
143
+ cancelQueries(predicate: QueryKey | ((key: QueryKey) => boolean)): void;
144
+ }
145
+ /** Singleton-доступ для тех мест, где Provider недоступен (push-handler и т.п.). */
146
+ declare function getQueryClient(): QueryClient;
147
+ declare function setQueryClient(client: QueryClient): void;
148
+
1
149
  type RequestConfig = {
2
150
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
3
151
  requestParams?: Record<string, string>;
@@ -7,9 +155,40 @@ type ResponseWrapper<DataType, ErrorsType = unknown> = {
7
155
  message?: string;
8
156
  errors?: ErrorsType;
9
157
  } & DataType;
10
- type UseFetchOptions<T> = {
158
+ type UseFetchOptions<T, TSelected = T> = {
159
+ /**
160
+ * При `false`:
161
+ * - запрос НЕ инициируется (ни на mount, ни на focus/reconnect/poll);
162
+ * - но хук **подписан на ключ кэша** и перерисуется, если данные
163
+ * обновит другой источник (другой `useFetch` с тем же ключом,
164
+ * `setQueryData` / `invalidateQueries`, мутация, push-handler).
165
+ *
166
+ * То есть `enabled: false` превращает хук в read-only слушателя.
167
+ * Если нужно полностью «потушить» хук — просто не вызывай его.
168
+ *
169
+ * По умолчанию `true`.
170
+ */
11
171
  enabled?: boolean;
12
172
  refetchOnMount?: boolean;
173
+ /** Refetch при возврате на экран / в браузерное окно. */
174
+ refetchOnFocus?: boolean;
175
+ /** Refetch при возврате приложения в активное состояние (RN AppState). */
176
+ refetchOnAppActive?: boolean;
177
+ /** Refetch при восстановлении сетевого соединения (offline → online). */
178
+ refetchOnReconnect?: boolean;
179
+ /** Время свежести данных в ms. Пока не истечёт — повторный mount берёт из кэша без сети. */
180
+ staleTime?: number;
181
+ /** Сколько держать запись в кэше после ухода последнего подписчика. По умолчанию 5 мин. */
182
+ gcTime?: number;
183
+ /** Интервал поллинга в ms. Поллинг автоматически останавливается, если экран не виден. */
184
+ pollingInterval?: number;
185
+ /**
186
+ * Кастомный queryKey. По умолчанию собирается как
187
+ * `['__endpoint__', endpointString, params]`.
188
+ */
189
+ queryKey?: readonly unknown[];
190
+ /** Селектор результата — пересчитывается мемоизированно. */
191
+ select?: (data: T) => TSelected;
13
192
  onSuccess?: (data: T) => void;
14
193
  onError?: (error: Error) => void;
15
194
  };
@@ -24,6 +203,16 @@ type UsePaginateOptions<T> = {
24
203
  enabled?: boolean;
25
204
  initialPage?: number;
26
205
  initialLimit?: number;
206
+ /** ms — пока страница свежая, повторный mount берёт её из кэша. */
207
+ staleTime?: number;
208
+ gcTime?: number;
209
+ /**
210
+ * Если true — при смене страницы (или params) предыдущие данные остаются
211
+ * на экране до прихода новых. Полезно для плавной пагинации.
212
+ */
213
+ keepPreviousData?: boolean;
214
+ /** Кастомный префикс ключа кэша. По умолчанию — endpoint + serialized params. */
215
+ queryKey?: readonly unknown[];
27
216
  onSuccess?: (data: T) => void;
28
217
  onError?: (error: Error) => void;
29
218
  };
@@ -36,17 +225,39 @@ type UsePaginateResult<TData extends unknown[]> = {
36
225
  hasPreviousPage: boolean;
37
226
  isLoading: boolean;
38
227
  isFetchingNextPage: boolean;
228
+ /** true если данные показываются из предыдущей страницы (keepPreviousData). */
229
+ isPlaceholderData: boolean;
39
230
  error: Error | null;
40
231
  fetchNextPage: () => Promise<void>;
41
232
  fetchPreviousPage: () => Promise<void>;
233
+ /** Префетчит следующую страницу в кэш, не меняя UI. */
234
+ prefetchNextPage: () => Promise<void>;
42
235
  refetch: () => Promise<void>;
43
236
  reset: () => void;
44
237
  };
45
- type UseMutationOptions<TData, TVariables> = {
46
- onMutate?: (variables: TVariables) => void | Promise<void>;
47
- onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;
48
- onError?: (error: Error, variables: TVariables) => void | Promise<void>;
49
- onSettled?: (data: TData | null, error: Error | null, variables: TVariables) => void | Promise<void>;
238
+
239
+ type UseMutationOptions<TData, TVariables, TContext = unknown> = {
240
+ /**
241
+ * Вызывается ДО запроса. Может вернуть context он попадёт в onError
242
+ * (для rollback) и в onSettled. Используется для optimistic updates:
243
+ * сохранить снепшот → применить оптимистичный setQueryData → в onError
244
+ * вернуть снепшот обратно.
245
+ */
246
+ onMutate?: (variables: TVariables) => void | TContext | Promise<void | TContext>;
247
+ onSuccess?: (data: TData, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
248
+ onError?: (error: Error, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
249
+ onSettled?: (data: TData | null, error: Error | null, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
250
+ /**
251
+ * Ключи кэша, которые надо инвалидировать после успеха.
252
+ * Может быть массивом ключей или функцией, считающей их по vars/data.
253
+ * Каждый ключ матчится по префиксу (см. matchQueryKey).
254
+ */
255
+ invalidateKeys?: QueryKey[] | ((vars: TVariables, data: TData) => QueryKey[]);
256
+ /**
257
+ * Точечно патчит кэш после успеха — до invalidate. Удобно для
258
+ * «сервер вернул свежий объект, положим его прямо в ['orders', id]».
259
+ */
260
+ setQueryData?: (client: QueryClient, variables: TVariables, data: TData) => void;
50
261
  };
51
262
  type UseMutationResult<TData, TVariables> = {
52
263
  data: TData | null;
@@ -61,23 +272,33 @@ type UseMutationResult<TData, TVariables> = {
61
272
  interface IHttpClient {
62
273
  get<T>(url: string, config?: {
63
274
  params?: Record<string, unknown>;
275
+ signal?: AbortSignal;
64
276
  }): Promise<T>;
65
277
  request<T>(url: string, config: {
66
278
  method?: string;
67
279
  data?: Record<string, unknown>;
280
+ signal?: AbortSignal;
68
281
  }): Promise<T>;
69
282
  }
70
283
  type ApiClientConfig = {
71
284
  httpClient: IHttpClient;
72
285
  onUnauthorized?: () => void | Promise<void>;
286
+ /**
287
+ * Когда true — любая ошибка (HTTP >= 400, сеть, тело с `{ status: false }`)
288
+ * приводит к `throw new ApiError(...)`. По умолчанию false — пакет
289
+ * сохраняет старое поведение (ошибки приходят как `{ status: false }`).
290
+ * Включать только после того, как все вызовы `await *.mutate()` /
291
+ * `await *.fetch()` обёрнуты в try/catch.
292
+ */
293
+ throwOnError?: boolean;
73
294
  };
74
295
  type ApiClientReturn<ResponseType, RequestParamsType, ErrorResponseType = unknown> = {
75
296
  fetch: (params?: RequestParamsType) => Promise<ResponseWrapper<ResponseType, ErrorResponseType>>;
76
- useFetch: (params?: RequestParamsType, options?: UseFetchOptions<ResponseWrapper<ResponseType, ErrorResponseType>>) => UseFetchResult<ResponseWrapper<ResponseType, ErrorResponseType>>;
297
+ useFetch: <TSelected = ResponseWrapper<ResponseType, ErrorResponseType>>(params?: RequestParamsType, options?: UseFetchOptions<ResponseWrapper<ResponseType, ErrorResponseType>, TSelected>) => UseFetchResult<TSelected>;
77
298
  };
78
299
  type ApiMutationReturn<ResponseType, RequestParamsType, ErrorResponseType = unknown> = {
79
300
  mutate: (params?: RequestParamsType) => Promise<ResponseWrapper<ResponseType, ErrorResponseType>>;
80
- useMutation: (options?: UseMutationOptions<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>) => UseMutationResult<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>;
301
+ useMutation: <TContext = unknown>(options?: UseMutationOptions<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType, TContext>) => UseMutationResult<ResponseWrapper<ResponseType, ErrorResponseType>, RequestParamsType>;
81
302
  };
82
303
  type ApiPaginateReturn<ResponseType, RequestParamsType, DataArrayType extends unknown[], ErrorResponseType = unknown> = {
83
304
  usePaginate: (params?: Omit<RequestParamsType, 'page' | 'limit'>, options?: UsePaginateOptions<ResponseWrapper<ResponseType, ErrorResponseType>>) => UsePaginateResult<DataArrayType>;
@@ -107,6 +328,182 @@ declare function getConfig(): ApiClientConfig;
107
328
  */
108
329
  declare function isConfigured(): boolean;
109
330
 
331
+ /**
332
+ * Унифицированная ошибка API. Кидается из `executeRequest` (а значит,
333
+ * из `fetch`/`mutate`/хуков) только когда в `configureApiClient` включён
334
+ * `throwOnError: true`. По умолчанию поведение пакета не меняется —
335
+ * ошибки приходят как `{ status: false }` (см. CHANGELOG, Фаза 3.5).
336
+ */
337
+ type ApiErrorInit<E = unknown> = {
338
+ message: string;
339
+ status: number;
340
+ code?: string;
341
+ errors?: E;
342
+ isNetworkError?: boolean;
343
+ isUnauthorized?: boolean;
344
+ isValidationError?: boolean;
345
+ raw?: unknown;
346
+ };
347
+ declare class ApiError<E = unknown> extends Error {
348
+ readonly status: number;
349
+ readonly code?: string;
350
+ readonly errors?: E;
351
+ readonly isNetworkError: boolean;
352
+ readonly isUnauthorized: boolean;
353
+ readonly isValidationError: boolean;
354
+ readonly raw: unknown;
355
+ constructor(init: ApiErrorInit<E>);
356
+ }
357
+ /**
358
+ * Конвертация произвольного throw'нутого значения в `ApiError`.
359
+ * Покрывает 4 кейса:
360
+ * - `ApiError` → passthrough
361
+ * - axios-like `{ response: { status, data } }` → ApiError с полями из data
362
+ * - `Error` (сетевая ошибка, таймаут) → ApiError(isNetworkError, status: 0)
363
+ * - неизвестный объект → ApiError(message: 'Unknown error', status: 0)
364
+ */
365
+ declare function toApiError(thrown: unknown): ApiError;
366
+ /**
367
+ * Для 2xx ответа, в теле которого Laravel-style `{ status: false }`.
368
+ * Возвращает ApiError(status: 200, ...). Вызывается из executeRequest
369
+ * только при `throwOnError: true`.
370
+ */
371
+ declare function businessErrorToApiError(response: unknown): ApiError;
372
+
373
+ /**
374
+ * Storage-адаптер. Совместим с AsyncStorage и expo-secure-store:
375
+ * { getItem(key): Promise<string|null>, setItem(key, value): Promise<void>,
376
+ * removeItem(key): Promise<void> }.
377
+ */
378
+ interface PersistStorage {
379
+ getItem(key: string): Promise<string | null>;
380
+ setItem(key: string, value: string): Promise<void>;
381
+ removeItem(key: string): Promise<void>;
382
+ }
383
+ type PersistOptions = {
384
+ client: QueryClient;
385
+ storage: PersistStorage;
386
+ /** Ключ в storage. По умолчанию 'react-api-client:cache'. */
387
+ storageKey?: string;
388
+ /** Дросселирование записи (ms). По умолчанию 1000. */
389
+ throttleMs?: number;
390
+ /** Фильтр ключей: что вообще сохранять. По умолчанию — всё. */
391
+ allowList?: (key: QueryKey) => boolean;
392
+ /** Максимальный возраст сохранённого снэпшота (ms). Старее — выбрасываем. */
393
+ maxAge?: number;
394
+ /**
395
+ * Версия снэпшота. При несовпадении — снэпшот игнорируется и удаляется.
396
+ * Поднимай при изменении формата данных в кэше.
397
+ */
398
+ version?: string | number;
399
+ };
400
+ /**
401
+ * Подключает QueryClient к persistent storage.
402
+ *
403
+ * С версии 2.0.0 — подписан на `cache.subscribeAll`, поэтому
404
+ * автоматически сохраняет состояние через `throttleMs` после любого
405
+ * изменения (setData, успешный fetch, invalidate, remove). Ручной
406
+ * `persist()` остаётся доступным для критичных моментов (logout,
407
+ * shutdown), но в обычном потоке не нужен.
408
+ *
409
+ * Возвращает:
410
+ * - `restore()` — гидратирует кэш из storage. Вызывать на старте.
411
+ * - `persist()` — форс-запись текущего состояния.
412
+ * - `unsubscribe()` — отключить авто-сохранение.
413
+ */
414
+ declare function persistQueryClient(options: PersistOptions): {
415
+ restore: () => Promise<void>;
416
+ persist: () => Promise<void>;
417
+ unsubscribe: () => void;
418
+ };
419
+
420
+ type CacheEntrySnapshot = {
421
+ key: QueryKey;
422
+ hash: string;
423
+ status: QueryStatus;
424
+ isStale: boolean;
425
+ updatedAt: number;
426
+ hasData: boolean;
427
+ subscribers: number;
428
+ hasInflight: boolean;
429
+ errorMessage: string | null;
430
+ };
431
+ /**
432
+ * Снимок состояния всего кэша — без приватных полей и без данных.
433
+ * Удобно выводить в debug-экране или логировать.
434
+ */
435
+ declare function inspectCache(cache: QueryCache): CacheEntrySnapshot[];
436
+ /** «invalidate all» — пометить весь кэш как stale. */
437
+ declare function invalidateAll(client: QueryClient): void;
438
+ /** Краткая сводка для логов: сколько записей, активных подписчиков, inflight. */
439
+ declare function summarizeCache(cache: QueryCache): {
440
+ total: number;
441
+ withSubscribers: number;
442
+ inflight: number;
443
+ stale: number;
444
+ byStatus: Record<QueryStatus, number>;
445
+ };
446
+
447
+ /**
448
+ * Глобальный менеджер «фокуса» приложения.
449
+ * - В вебе автоматически подключается к window focus/visibilitychange.
450
+ * - В React Native интеграцию ставит сам потребитель через
451
+ * `focusManager.setFocused(state === 'active')` из AppState.
452
+ *
453
+ * Подписчики (useFetch с refetchOnFocus / refetchOnAppActive) получают
454
+ * уведомление при переходе в focused == true.
455
+ */
456
+ type Listener$1 = (focused: boolean) => void;
457
+ declare class FocusManager {
458
+ private focused;
459
+ private listeners;
460
+ private cleanup;
461
+ subscribe(listener: Listener$1): () => void;
462
+ isFocused(): boolean;
463
+ setFocused(focused: boolean): void;
464
+ private setupBrowserListeners;
465
+ private teardownBrowserListeners;
466
+ }
467
+ declare const focusManager: FocusManager;
468
+
469
+ /**
470
+ * Глобальный менеджер сетевого статуса.
471
+ * - В браузере подключается к window online/offline.
472
+ * - В React Native интеграция — через NetInfo (опционально):
473
+ * `NetInfo.addEventListener(s => onlineManager.setOnline(!!s.isConnected))`.
474
+ * Жёсткой зависимости от NetInfo нет — без него по умолчанию online: true.
475
+ *
476
+ * Подписчики (useFetch с refetchOnReconnect) получают уведомление при
477
+ * переходе offline → online.
478
+ */
479
+ type Listener = (online: boolean) => void;
480
+ declare class OnlineManager {
481
+ private online;
482
+ private listeners;
483
+ private cleanup;
484
+ subscribe(listener: Listener): () => void;
485
+ isOnline(): boolean;
486
+ setOnline(online: boolean): void;
487
+ private setupBrowserListeners;
488
+ private teardownBrowserListeners;
489
+ }
490
+ declare const onlineManager: OnlineManager;
491
+
492
+ type ApiClientProviderProps = {
493
+ client?: QueryClient;
494
+ children: ReactNode;
495
+ };
496
+ /**
497
+ * Корневой Provider пакета. Создаёт (или принимает) QueryClient и кладёт
498
+ * его в React Context. Хуки достают клиент через useQueryClient().
499
+ *
500
+ * Также синхронизирует переданный client с singleton'ом
501
+ * getQueryClient() — чтобы push-handler'ы вне React-дерева могли дергать
502
+ * `getQueryClient().invalidateQueries(...)`.
503
+ */
504
+ declare function ApiClientProvider({ client, children, }: ApiClientProviderProps): react.FunctionComponentElement<react.ProviderProps<QueryClient | null>>;
505
+ declare function useQueryClient(): QueryClient;
506
+
110
507
  /**
111
508
  * Creates an API client for GET requests
112
509
  * @param endpoint - URL string or function that generates URL from params
@@ -149,4 +546,4 @@ declare function apiPaginate<ResponseType extends {
149
546
  totalExtractor?: (response: ResponseType) => number;
150
547
  }): ApiPaginateReturn<ResponseType, RequestParamsType, TData, ErrorResponseType>;
151
548
 
152
- export { type ApiClientConfig, type IHttpClient, type ResponseWrapper, type UseFetchOptions, type UseFetchResult, type UseMutationOptions, type UseMutationResult, type UsePaginateOptions, type UsePaginateResult, apiMutation, apiPaginate, configureApiClient, apiClient as default, getConfig, isConfigured };
549
+ export { type ApiClientConfig, ApiClientProvider, type ApiClientProviderProps, ApiError, type ApiErrorInit, type CacheEntrySnapshot, type DehydratedQuery, type DehydratedState, type FetchOptions, type IHttpClient, type PersistOptions, type PersistStorage, QueryCache, QueryClient, type QueryFn, type QueryKey, type QueryState, type QueryStatus, type ResponseWrapper, type UseFetchOptions, type UseFetchResult, type UseMutationOptions, type UseMutationResult, type UsePaginateOptions, type UsePaginateResult, apiMutation, apiPaginate, businessErrorToApiError, configureApiClient, apiClient as default, focusManager, getConfig, getQueryClient, hashQueryKey, inspectCache, invalidateAll, isConfigured, matchQueryKey, onlineManager, persistQueryClient, setQueryClient, summarizeCache, toApiError, useQueryClient };