@qiaopeng/tanstack-query-plus 0.1.1 → 0.1.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/README.md ADDED
@@ -0,0 +1,625 @@
1
+ # @qiaopeng/tanstack-query-plus
2
+
3
+ 一个基于 React 与 TanStack Query v5 的增强工具包。文档以循序渐进方式介绍核心能力,参考 React Query 官网的学习路径:从 Provider 到查询,再到高级能力(Suspense/无限加载/批量/持久化/离线/Prefetch/Devtools)。
4
+
5
+ ## 目录
6
+
7
+ 1. 安装与环境
8
+ 2. 初始化与 Provider
9
+ 3. 基础查询(Queries)
10
+ 4. Suspense 与 Error 边界
11
+ 5. 变更(Mutations)与乐观更新
12
+ 6. 无限加载(Infinite Queries)
13
+ 7. 批量查询与批量操作
14
+ 8. 预取(Prefetch)
15
+ 9. 持久化与离线支持
16
+ 10. Devtools(可选)
17
+ 11. 配置与最佳实践
18
+ 12. 子路径导出与常见问题
19
+
20
+ ## 1. 安装与环境
21
+
22
+ - 要求:Node `>=16`、React 18、TanStack Query v5
23
+ - 安装:
24
+
25
+ ```bash
26
+ npm install @qiaopeng/tanstack-query-plus @tanstack/react-query @tanstack/react-query-persist-client
27
+ ```
28
+
29
+ - 可选能力(按需安装):
30
+ - Devtools:`npm install @tanstack/react-query-devtools`
31
+ - InView 预取:`npm install react-intersection-observer`
32
+
33
+ ## 2. 初始化与 Provider
34
+
35
+ 使用增强版 Provider,自动启用离线监听与持久化(浏览器环境),在 SSR 环境自动降级为普通 Provider:
36
+
37
+ ```tsx
38
+ import { QueryClient, PersistQueryClientProvider, useIsMutating } from '@qiaopeng/tanstack-query-plus'
39
+ import { GLOBAL_QUERY_CONFIG } from '@qiaopeng/tanstack-query-plus/core'
40
+
41
+ const queryClient = new QueryClient({ defaultOptions: GLOBAL_QUERY_CONFIG })
42
+
43
+ export function App() {
44
+ return (
45
+ <PersistQueryClientProvider client={queryClient} enablePersistence enableOfflineSupport>
46
+ <Root />
47
+ </PersistQueryClientProvider>
48
+ )
49
+ }
50
+
51
+ // 统一门面层:直接使用顶层导出的 React Query 运行时
52
+ // 如需类型,可从 react-query 子路径获取:
53
+ // import type { UseQueryOptions, UseInfiniteQueryOptions, QueryKey } from '@qiaopeng/tanstack-query-plus/react-query'
54
+ ```
55
+
56
+ ## 3. 基础查询(Queries)
57
+
58
+ 最简用法:
59
+
60
+ ```tsx
61
+ import { useEnhancedQuery } from '@qiaopeng/tanstack-query-plus/hooks'
62
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
63
+
64
+ function UserProfile({ id }: { id: string }) {
65
+ const result = useEnhancedQuery({
66
+ queryKey: queryKeys.user(id),
67
+ queryFn: async () => {
68
+ const res = await fetch(`/api/users/${id}`)
69
+ if (!res.ok) throw new Error('Failed to fetch user')
70
+ return res.json()
71
+ }
72
+ })
73
+
74
+ if (result.isLoading) return <div>Loading...</div>
75
+ if (result.isError) return <div>Error: {String(result.error?.message || 'unknown')}</div>
76
+ return <div>{result.data.name}</div>
77
+ }
78
+ ```
79
+
80
+ 更严格的选项工厂(统一最佳实践,例如 staleTime/gcTime、指数退避重试):
81
+
82
+ ```tsx
83
+ import { createAppQueryOptions, queryKeys } from '@qiaopeng/tanstack-query-plus/core'
84
+ import { useQuery } from '@qiaopeng/tanstack-query-plus/react-query'
85
+
86
+ const options = createAppQueryOptions({
87
+ queryKey: queryKeys.settings(),
88
+ queryFn: () => fetch('/api/settings').then(r => r.json())
89
+ })
90
+
91
+ function Settings() {
92
+ const result = useQuery(options)
93
+ return <pre>{JSON.stringify(result.data, null, 2)}</pre>
94
+ }
95
+ ```
96
+
97
+ ## 4. Suspense 与 Error 边界
98
+
99
+ 为 Suspense 查询提供更顺滑的体验,并在错误时给出可重试界面:
100
+
101
+ ```tsx
102
+ import { SuspenseWrapper, DefaultLoadingFallback } from '@qiaopeng/tanstack-query-plus/components'
103
+ import { useEnhancedSuspenseQuery } from '@qiaopeng/tanstack-query-plus/hooks'
104
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
105
+
106
+ function SuspenseUser({ id }: { id: string }) {
107
+ const result = useEnhancedSuspenseQuery({
108
+ queryKey: queryKeys.user(id),
109
+ queryFn: () => fetch(`/api/users/${id}`).then(r => r.json())
110
+ })
111
+ return <div>{result.data.name}</div>
112
+ }
113
+
114
+ export function Page({ id }: { id: string }) {
115
+ return (
116
+ <SuspenseWrapper fallback={<DefaultLoadingFallback />}>
117
+ <SuspenseUser id={id} />
118
+ </SuspenseWrapper>
119
+ )
120
+ }
121
+ ```
122
+
123
+ ## 5. 变更(Mutations)与乐观更新
124
+
125
+ 常规变更:
126
+
127
+ ```tsx
128
+ import { useMutation } from '@qiaopeng/tanstack-query-plus/hooks'
129
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
130
+ import { useQueryClient } from '@tanstack/react-query'
131
+
132
+ function UpdateUserName({ id }: { id: string }) {
133
+ const qc = useQueryClient()
134
+ const mutation = useMutation({
135
+ mutationFn: async (name: string) =>
136
+ fetch(`/api/users/${id}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name }) })
137
+ .then(r => r.json()),
138
+ onSuccess: () => { qc.invalidateQueries({ queryKey: queryKeys.user(id) }) }
139
+ })
140
+ return <button onClick={() => mutation.mutate('new name')}>Update</button>
141
+ }
142
+ ```
143
+
144
+ 乐观更新(支持字段映射、回滚与批量处理):详见 `useMutation` 与 `useConditionalOptimisticMutation` 的选项。
145
+
146
+ ## 6. 无限加载(Infinite Queries)
147
+
148
+ 提供三种分页模型的选项工厂,统一分页逻辑:
149
+
150
+ ```tsx
151
+ import { useEnhancedInfiniteQuery, createCursorPaginationOptions, createOffsetPaginationOptions, createPageNumberPaginationOptions } from '@qiaopeng/tanstack-query-plus/hooks'
152
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
153
+
154
+ const cursorOptions = createCursorPaginationOptions({
155
+ queryKey: queryKeys.posts(),
156
+ queryFn: async (cursor) => fetch(`/api/posts?cursor=${cursor ?? ''}`).then(r => r.json()),
157
+ initialCursor: null
158
+ })
159
+
160
+ const offsetOptions = createOffsetPaginationOptions({
161
+ queryKey: queryKeys.posts(),
162
+ queryFn: async (offset, limit) => fetch(`/api/posts?offset=${offset}&limit=${limit}`).then(r => r.json()),
163
+ limit: 20
164
+ })
165
+
166
+ const pageNumberOptions = createPageNumberPaginationOptions({
167
+ queryKey: queryKeys.posts(),
168
+ queryFn: async (page) => fetch(`/api/posts?page=${page}`).then(r => r.json())
169
+ })
170
+
171
+ function InfiniteList() {
172
+ const result = useEnhancedInfiniteQuery(offsetOptions)
173
+ const pages = result.data?.pages ?? []
174
+ return (
175
+ <div>
176
+ {pages.map((p, i) => (
177
+ <div key={i}>{p.items.length} items</div>
178
+ ))}
179
+ <button disabled={!result.hasNextPage || result.isFetchingNextPage} onClick={() => result.fetchNextPage()}>
180
+ 下一页
181
+ </button>
182
+ </div>
183
+ )
184
+ }
185
+ ```
186
+
187
+ ## 7. 批量查询与批量操作
188
+
189
+ 在多查询场景下聚合统计并提供批量操作工具:
190
+
191
+ ```tsx
192
+ import { useEnhancedQueries, batchQueryUtils } from '@qiaopeng/tanstack-query-plus/hooks'
193
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
194
+
195
+ function Dashboard() {
196
+ const { data: results, stats, operations } = useEnhancedQueries([
197
+ { queryKey: queryKeys.users(), queryFn: () => fetch('/api/users').then(r => r.json()) },
198
+ { queryKey: queryKeys.posts(), queryFn: () => fetch('/api/posts').then(r => r.json()) }
199
+ ])
200
+
201
+ return (
202
+ <div>
203
+ <div>成功率:{stats.successRate.toFixed(2)}%</div>
204
+ <button onClick={() => operations.refetchAll()}>刷新全部</button>
205
+ {batchQueryUtils.hasError(results) && <div>部分查询失败</div>}
206
+ </div>
207
+ )
208
+ }
209
+ ```
210
+
211
+ ## 8. 预取(Prefetch)
212
+
213
+ 提供多种预取策略:悬停、路由变化、智能预取、视口内预取(可选依赖)。
214
+
215
+ ```tsx
216
+ import { useEffect } from 'react'
217
+ import { useHoverPrefetch, useRoutePrefetch, useSmartPrefetch } from '@qiaopeng/tanstack-query-plus/hooks'
218
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
219
+
220
+ function LinkWithPrefetch({ id }: { id: string }) {
221
+ const hover = useHoverPrefetch(queryKeys.user(id), () => fetch(`/api/users/${id}`).then(r => r.json()))
222
+ return <a href={`/user/${id}`} {...hover}>用户详情</a>
223
+ }
224
+
225
+ function RouterChange() {
226
+ const prefetch = useRoutePrefetch()
227
+ useEffect(() => {
228
+ prefetch(queryKeys.settings(), () => fetch('/api/settings').then(r => r.json()))
229
+ }, [])
230
+ return null
231
+ }
232
+
233
+ function SmartCard({ id }: { id: string }) {
234
+ const { prefetch } = useSmartPrefetch()
235
+ return <div onMouseEnter={() => prefetch(queryKeys.user(id), () => fetch(`/api/users/${id}`).then(r => r.json()))}>卡片</div>
236
+ }
237
+ ```
238
+
239
+ 视口内预取(可选依赖):
240
+
241
+ ```tsx
242
+ import { useInViewPrefetch } from '@qiaopeng/tanstack-query-plus/hooks/inview'
243
+ import { queryKeys } from '@qiaopeng/tanstack-query-plus/core'
244
+
245
+ function PrefetchOnView() {
246
+ const ref = useInViewPrefetch(queryKeys.posts(), () => fetch('/api/posts').then(r => r.json()), { threshold: 0.2 })
247
+ return <div ref={ref} />
248
+ }
249
+ ```
250
+
251
+ ## 9. 持久化与离线支持
252
+
253
+ 浏览器环境下 Provider 自动启用持久化与离线状态监听;通过 features 子路径获取离线工具与持久化管理:
254
+
255
+ ```tsx
256
+ import { useEffect, useState } from 'react'
257
+ import { isOnline, subscribeToOnlineStatus, clearCache } from '@qiaopeng/tanstack-query-plus/features'
258
+
259
+ function OfflineBanner() {
260
+ const [online, setOnline] = useState(isOnline())
261
+ useEffect(() => subscribeToOnlineStatus(setOnline), [])
262
+ return online ? null : <div>当前离线,数据将使用缓存</div>
263
+ }
264
+
265
+ function ClearCacheButton() {
266
+ return <button onClick={() => clearCache()}>清空持久化缓存</button>
267
+ }
268
+ ```
269
+
270
+ ## 10. Devtools(可选)
271
+
272
+ 按需引入,避免未安装时报错:
273
+
274
+ ```tsx
275
+ import { ReactQueryDevtools } from '@qiaopeng/tanstack-query-plus/core/devtools'
276
+ ```
277
+
278
+ ## 11. 配置与最佳实践
279
+
280
+ 提供统一默认值与校验工具:
281
+
282
+ ```ts
283
+ import { GLOBAL_QUERY_CONFIG, PRODUCTION_CONFIG, DEVELOPMENT_CONFIG, ensureBestPractices, validateConfig } from '@qiaopeng/tanstack-query-plus/core'
284
+ ```
285
+
286
+ - 默认值包含合理的 `staleTime/gcTime`、重试与指数退避、焦点/重连自动刷新等
287
+ - `ensureBestPractices(config)` 会自动修正不合理配置(如 `gcTime <= staleTime`)
288
+
289
+ ## 12. 子路径导出与常见问题
290
+
291
+ - 顶层:`@qiaopeng/tanstack-query-plus`
292
+ - 核心:`@qiaopeng/tanstack-query-plus/core`
293
+ - Hooks:`@qiaopeng/tanstack-query-plus/hooks`
294
+ - 组件:`@qiaopeng/tanstack-query-plus/components`
295
+ - 工具与类型:`@qiaopeng/tanstack-query-plus/utils`、`@qiaopeng/tanstack-query-plus/types`
296
+ - React Query 直通子路径:`@qiaopeng/tanstack-query-plus/react-query`
297
+ - 运行时再导出:`QueryClient`、`QueryClientProvider`、`useQueryClient`、`skipToken`、`useIsMutating`
298
+ - 类型再导出:`UseQueryOptions`、`UseSuspenseQueryOptions`、`UseInfiniteQueryOptions`、`QueryKey`、`MutationKey`、`InfiniteData`
299
+ - 可选能力:
300
+ - Devtools:`@qiaopeng/tanstack-query-plus/core/devtools`
301
+ - InView 预取:`@qiaopeng/tanstack-query-plus/hooks/inview`
302
+
303
+ 常见问题:
304
+
305
+ - Devtools 未安装时报错?使用子路径 `core/devtools` 并安装 `@tanstack/react-query-devtools`
306
+ - InView 预取未安装时报错?使用子路径 `hooks/inview` 并安装 `react-intersection-observer`
307
+ - SSR 如何工作?Provider 会在无法持久化时自动降级;所有浏览器 API 都有守卫
308
+
309
+ ## 许可
310
+
311
+ MIT
312
+
313
+ ## API 参考
314
+
315
+ 本节对导出的 Hooks 与 TSX 组件进行逐项说明,并给出最小示例,便于快速查阅与上手。
316
+
317
+ ### Provider 与持久化/离线
318
+
319
+ - PersistQueryClientProvider(props)
320
+ - 作用:集成 TanStack Query Provider,浏览器环境自动启用持久化与离线监听;SSR 环境安全降级
321
+ - 关键 props:`client`、`cacheKey?`、`enablePersistence?`、`enableOfflineSupport?`
322
+ - 用法:参见“初始化与 Provider”章节示例
323
+ - 离线/持久化工具(features 子路径)
324
+ - `isOnline()` / `subscribeToOnlineStatus(callback)` / `configureOfflineQueries(queryClient)`
325
+ - `clearCache(key?)` / `clearExpiredCache(key?, maxAge?)` / `createPersister(key?, storage?)`
326
+ - 用法:参见“持久化与离线支持”章节示例
327
+
328
+ ### 组件(TSX)
329
+
330
+ - SuspenseWrapper({ children, fallback?, errorFallback?, onError?, resetKeys? })
331
+ - 作用:将 ErrorBoundary 与 React.Suspense 合并封装
332
+ - QueryErrorBoundary({ children, fallback?, onError?, resetKeys? })
333
+ - 作用:结合 React Query 的错误重置能力,提供查询错误兜底 UI
334
+ - LoadingFallback 族
335
+ - DefaultLoadingFallback / SmallLoadingIndicator / FullScreenLoading / TextSkeletonFallback / CardSkeletonFallback / ListSkeletonFallback / PageSkeletonFallback
336
+ - 作用:一致的加载与骨架 UI,可按需组合
337
+
338
+ ### Queries(标准与 Suspense)
339
+
340
+ - useEnhancedQuery(options)
341
+ - 作用:基于 v5 `useQuery` 的增强封装,携带统一默认最佳实践(重试、指数退避、焦点刷新等)
342
+ - 示例:参见“基础查询”章节
343
+ - useEnhancedSuspenseQuery(options)
344
+ - 作用:针对 Suspense 模式的查询封装
345
+ - createAppQueryOptions(config)
346
+ - 作用:生成带默认最佳实践的 `UseQueryOptions`;推荐与 `useQuery` 搭配
347
+ - createAppQueryOptionsWithSelect(config)
348
+ - 作用:在服务器返回数据基础上做选择/映射
349
+ - createSuspenseQuery(config)、createSuspenseInfiniteQuery(config)
350
+ - 作用:为 Suspense 场景生成标准化选项
351
+
352
+ 签名参考:
353
+
354
+ ```ts
355
+ // 标准查询
356
+ declare function useEnhancedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(
357
+ options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>
358
+ ): UseQueryResult<TData, TError>
359
+
360
+ declare function createAppQueryOptions<TData>(
361
+ config: { queryKey: QueryKey; queryFn: QueryFunction<TData, QueryKey>; staleTime?: number; gcTime?: number; enabled?: boolean }
362
+ ): UseQueryOptions<TData, DefaultError, TData, QueryKey>
363
+
364
+ declare function createAppQueryOptionsWithSelect<TData, TSelected = TData>(
365
+ config: { queryKey: QueryKey; queryFn: QueryFunction<TData, QueryKey>; select: (data: TData) => TSelected; staleTime?: number; gcTime?: number }
366
+ ): UseQueryOptions<TData, DefaultError, TSelected, QueryKey>
367
+
368
+ // Suspense 查询
369
+ declare function useEnhancedSuspenseQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(
370
+ options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>
371
+ ): UseSuspenseQueryResult<TData, TError>
372
+
373
+ declare function createSuspenseQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TVariables = void>(
374
+ getQueryKey: (variables: TVariables) => TQueryKey,
375
+ queryFn: QueryFunction<TQueryFnData, TQueryKey>,
376
+ options?: Omit<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey' | 'queryFn'>
377
+ ): (variables: TVariables) => UseSuspenseQueryResult<TData, TError>
378
+
379
+ // 说明:对于 v5 推荐在调用时将 TError 显式指定为 DefaultError,以与官方类型一致:
380
+ // useEnhancedQuery<..., DefaultError>(options)
381
+ // useEnhancedSuspenseQuery<..., DefaultError>(options)
382
+ ```
383
+
384
+ ### Infinite Queries(三种分页模型)
385
+
386
+ - useEnhancedInfiniteQuery(options)
387
+ - 作用:增强版无限查询钩子
388
+ - createCursorPaginationOptions({ queryKey, queryFn, initialCursor?, staleTime?, gcTime? })
389
+ - createOffsetPaginationOptions({ queryKey, queryFn, limit?, staleTime?, gcTime? })
390
+ - createPageNumberPaginationOptions({ queryKey, queryFn, staleTime?, gcTime? })
391
+ - 作用:三种分页模型的统一选项工厂;示例参见“无限加载”章节
392
+
393
+ 签名参考:
394
+
395
+ ```ts
396
+ declare function useEnhancedInfiniteQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(
397
+ options: UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
398
+ ): UseInfiniteQueryResult<TData, TError>
399
+
400
+ declare function createInfiniteQueryOptions<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(
401
+ config: {
402
+ queryKey: TQueryKey
403
+ queryFn: QueryFunction<TQueryFnData, TQueryKey, TPageParam>
404
+ initialPageParam: TPageParam
405
+ getNextPageParam: (lastPage: TQueryFnData, allPages: TQueryFnData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null
406
+ getPreviousPageParam?: (firstPage: TQueryFnData, allPages: TQueryFnData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null
407
+ staleTime?: number
408
+ gcTime?: number
409
+ }
410
+ ): UseInfiniteQueryOptions<TQueryFnData, DefaultError, TQueryFnData, TQueryKey, TPageParam>
411
+
412
+ declare function createCursorPaginationOptions<T>(
413
+ config: { queryKey: QueryKey; queryFn: (cursor: string | null) => Promise<CursorPaginatedResponse<T>>; initialCursor?: string | null; staleTime?: number; gcTime?: number }
414
+ ): UseInfiniteQueryOptions<CursorPaginatedResponse<T>, DefaultError, CursorPaginatedResponse<T>, QueryKey, string | null>
415
+
416
+ declare function createOffsetPaginationOptions<T>(
417
+ config: { queryKey: QueryKey; queryFn: (offset: number, limit: number) => Promise<OffsetPaginatedResponse<T>>; limit?: number; staleTime?: number; gcTime?: number }
418
+ ): UseInfiniteQueryOptions<OffsetPaginatedResponse<T>, DefaultError, OffsetPaginatedResponse<T>, QueryKey, number>
419
+
420
+ declare function createPageNumberPaginationOptions<T>(
421
+ config: { queryKey: QueryKey; queryFn: (page: number) => Promise<PageNumberPaginatedResponse<T>>; staleTime?: number; gcTime?: number }
422
+ ): UseInfiniteQueryOptions<PageNumberPaginatedResponse<T>, DefaultError, PageNumberPaginatedResponse<T>, QueryKey, number>
423
+ ```
424
+
425
+ ### 批量查询与操作
426
+
427
+ - useEnhancedQueries(queries, config?) / useEnhancedSuspenseQueries(queries, config?)
428
+ - 作用:批量执行查询并返回聚合统计与批量操作
429
+ - useCombinedQueries({ queries, combine? })
430
+ - 作用:自定义组合函数,得到合并后的结果
431
+ - useDashboardQueries(queriesMap)
432
+ - 作用:以对象映射驱动多查询,返回 `combinedData`
433
+ - useDependentBatchQueries({ primaryQuery, dependentQueries, config? })
434
+ - 作用:依赖查询链路(先主查询,再基于结果构造从查询集合)
435
+ - useDynamicBatchQueries({ items, queryKeyPrefix, queryFn, enabled?, staleTime?, gcTime?, config? })
436
+ - 作用:根据动态 items 批量生成查询
437
+ - usePaginatedBatchQueries({ pageNumbers, queryKeyPrefix, queryFn, staleTime?, config? })
438
+ - 作用:分页编号驱动的批量查询
439
+ - useConditionalBatchQueries(queries)
440
+ - 作用:对 `enabled !== false` 的查询执行批量
441
+ - useRetryBatchQueries({ queries, retry?, retryDelay?, config? })
442
+ - 作用:统一设置批量查询的重试策略
443
+ - batchQueryUtils
444
+ - 常用聚合工具:`isAllLoading/isAllSuccess/hasError/hasStale/getAllErrors/getAllData/...`
445
+ - calculateBatchStats(results)
446
+ - 返回成功率/错误率等批量统计
447
+ - createBatchQueryConfig(config?)
448
+ - 作用:构建批量查询配置的默认值
449
+ - useBatchQueryPerformance(results)
450
+ - 作用:统计平均拉取时间等性能指标
451
+
452
+ 签名参考:
453
+
454
+ ```ts
455
+ declare function useEnhancedQueries(
456
+ queries: UseQueryOptions[],
457
+ config?: BatchQueryConfig
458
+ ): { data: UseQueryResult[]; stats: BatchQueryStats; operations: InternalBatchQueryOperations; config: BatchQueryConfig }
459
+
460
+ declare function useEnhancedSuspenseQueries(
461
+ queries: UseSuspenseQueryOptions[],
462
+ config?: BatchQueryConfig
463
+ ): { data: UseSuspenseQueryResult[]; stats: BatchQueryStats; operations: InternalBatchQueryOperations; config: BatchQueryConfig }
464
+
465
+ declare function useCombinedQueries<TCombinedResult = UseQueryResult[]>(
466
+ options: { queries: UseQueryOptions[]; combine?: (results: UseQueryResult[]) => TCombinedResult }
467
+ ): TCombinedResult
468
+
469
+ declare function useDashboardQueries<T extends Record<string, UseQueryOptions>>(
470
+ queriesMap: T
471
+ ): { data: { [K in keyof T]: T[K] extends UseQueryOptions<infer D> ? D : unknown }; results: UseQueryResult[]; stats: BatchQueryStats; isLoading: boolean; isError: boolean; isSuccess: boolean }
472
+
473
+ declare function useDependentBatchQueries<TPrimaryData>(
474
+ options: { primaryQuery: UseQueryOptions<TPrimaryData>; dependentQueries: (data: TPrimaryData) => UseQueryOptions[]; config?: BatchQueryConfig }
475
+ ): { primaryResult: UseQueryResult<TPrimaryData, DefaultError>; results: UseQueryResult[]; stats: BatchQueryStats; operations: InternalBatchQueryOperations }
476
+ ```
477
+
478
+ ### Prefetch(预取)
479
+
480
+ - useHoverPrefetch(queryKey, queryFn, options?)
481
+ - useRoutePrefetch()
482
+ - 返回:`prefetch(queryKey, queryFn, options?)`
483
+ - useSmartPrefetch()
484
+ - 返回:`{ prefetch, shouldPrefetch, clearPrefetchHistory }`
485
+ - useConditionalPrefetch(queryKey, queryFn, condition, options?)
486
+ - useIdlePrefetch(queryKey, queryFn, { timeout?, ...options })
487
+ - usePeriodicPrefetch(queryKey, queryFn, { interval?, ...options })
488
+ - useBatchPrefetch([{ queryKey, queryFn, staleTime? }, ...])
489
+ - usePredictivePrefetch()
490
+ - 返回:`{ recordInteraction, getPredictions, prefetchPredicted, clearHistory }`
491
+ - usePriorityPrefetch()
492
+ - 返回:队列化按优先级执行预取任务
493
+ - useInViewPrefetch(queryKey, queryFn, options?)(子路径 `hooks/inview`)
494
+ - 需安装 `react-intersection-observer`
495
+
496
+ 签名参考:
497
+
498
+ ```ts
499
+ declare function useHoverPrefetch<TData = unknown>(
500
+ queryKey: QueryKey,
501
+ queryFn: QueryFunction<TData>,
502
+ options?: { delay?: number; enabled?: boolean; staleTime?: number; hoverDelay?: number }
503
+ ): { onMouseEnter: () => void; onMouseLeave: () => void; onFocus: () => void }
504
+
505
+ declare function useRoutePrefetch(): <TData = unknown>(
506
+ queryKey: QueryKey,
507
+ queryFn: QueryFunction<TData>,
508
+ options?: { enabled?: boolean; staleTime?: number }
509
+ ) => void
510
+
511
+ declare function useSmartPrefetch(): {
512
+ prefetch: <TData = unknown>(queryKey: QueryKey, queryFn: QueryFunction<TData>, options?: { staleTime?: number }) => void
513
+ shouldPrefetch: boolean
514
+ clearPrefetchHistory: () => void
515
+ }
516
+
517
+ declare function useInViewPrefetch<TData = unknown>(
518
+ queryKey: QueryKey,
519
+ queryFn: QueryFunction<TData>,
520
+ options?: { threshold?: number; rootMargin?: string; triggerOnce?: boolean; enabled?: boolean; staleTime?: number }
521
+ ): (el: Element | null) => void
522
+ ```
523
+
524
+ ### 焦点管理(Focus)
525
+
526
+ - useFocusRefetch(options?) / useConditionalFocusRefetch(condition, options?)
527
+ - 作用:基于页面焦点变化自动刷新
528
+ - useFocusCallback(callback)
529
+ - 作用:焦点恢复时执行回调
530
+ - useFocusState()
531
+ - 返回:当前是否处于焦点(布尔值)
532
+ - usePageVisibility()
533
+ - 返回:页面是否可见(布尔值)
534
+ - usePauseFocus(options?) / useSmartFocusManager()
535
+ - 作用:暂停/恢复全局焦点管理与最小间隔刷新的辅助
536
+
537
+ 签名参考:
538
+
539
+ ```ts
540
+ declare function useFocusRefetch(options?: { enabled?: boolean; minInterval?: number; queryKeys?: QueryKey[] }): void
541
+ declare function useConditionalFocusRefetch(queryKey: QueryKey, condition: () => boolean, options?: { minInterval?: number; enabled?: boolean }): void
542
+ declare function useFocusCallback(callback: () => void, options?: { minInterval?: number; enabled?: boolean; queryKey?: QueryKey }): void
543
+ declare function useFocusState(): boolean
544
+ declare function usePageVisibility(): boolean
545
+ declare function usePauseFocus(options?: { autoPause?: boolean; pauseWhen?: boolean }): { pause: () => void; resume: () => void }
546
+ declare function useSmartFocusManager(): { pause: () => void; resume: () => void; getStats: () => { isPaused: boolean; pauseCount: number; isFocused: boolean }; stats: { isPaused: boolean; pauseCount: number; isFocused: boolean } }
547
+ ```
548
+
549
+ ### Mutations(变更)
550
+
551
+ - useMutation(options)
552
+ - 作用:增强版 `useMutation`,内置乐观更新支持(字段映射、回滚、用户上下文)
553
+ - useConditionalOptimisticMutation(mutationFn, condition, options?)
554
+ - 作用:满足条件时才执行乐观更新
555
+ - useListMutation(mutationFn, queryKey, options?)
556
+ - 作用:列表场景的简化变更(完成后自动 `invalidateQueries`)
557
+ - useBatchMutation(mutationFn, options?)
558
+ - 作用:批量数据变更
559
+ - setupMutationDefaults(queryClient, config)
560
+ - 作用:按 mutationKey 设置全局默认变更选项
561
+ - cancelQueriesBatch(queryClient, queryKeys)
562
+ - setQueryDataBatch(queryClient, updates)
563
+ - invalidateQueriesBatch(queryClient, queryKeys)
564
+ - 作用:批量取消/更新/失效查询便捷工具
565
+
566
+ 签名参考:
567
+
568
+ ```ts
569
+ declare function useMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(
570
+ options: MutationOptions<TData, TError, TVariables, TContext>
571
+ ): UseMutationResult<TData, TError, TVariables, TContext>
572
+
573
+ declare function useConditionalOptimisticMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(
574
+ mutationFn: MutationFunction<TData, TVariables>,
575
+ condition: (variables: TVariables) => boolean,
576
+ options?: Omit<MutationOptions<TData, TError, TVariables, TContext>, 'mutationFn'> & { mutationKey?: readonly unknown[] }
577
+ ): UseMutationResult<TData, TError, TVariables, TContext>
578
+
579
+ declare function useListMutation<T extends EntityWithId>(
580
+ mutationFn: MutationFunction<T, { operation: string; data: Partial<T> }>,
581
+ queryKey: QueryKey,
582
+ options?: UseMutationOptions<T, Error, { operation: string; data: Partial<T> }> & { mutationKey?: readonly unknown[] }
583
+ ): UseMutationResult<T, Error, { operation: string; data: Partial<T> }>
584
+
585
+ declare function useBatchMutation<TData = unknown, TError = Error, TVariables = unknown[]>(
586
+ mutationFn: MutationFunction<TData[], TVariables>,
587
+ options?: UseMutationOptions<TData[], TError, TVariables> & { mutationKey?: readonly unknown[] }
588
+ ): UseMutationResult<TData[], TError, TVariables>
589
+
590
+ declare function setupMutationDefaults(queryClient: QueryClient, config: { [key: string]: UseMutationOptions<any, any, any, any> }): void
591
+ declare function cancelQueriesBatch(queryClient: QueryClient, queryKeys: Array<Parameters<QueryClient['cancelQueries']>[0]>): Promise<void>
592
+ declare function setQueryDataBatch(queryClient: QueryClient, updates: Array<{ queryKey: Parameters<QueryClient['setQueryData']>[0]; updater: Parameters<QueryClient['setQueryData']>[1] }>): void
593
+ declare function invalidateQueriesBatch(queryClient: QueryClient, queryKeys: Array<Parameters<QueryClient['invalidateQueries']>[0]>): Promise<void>
594
+ ```
595
+
596
+ ### 组件错误与加载(TSX)
597
+
598
+ - QueryErrorBoundary / ErrorBoundary
599
+ - 作用:错误显示与重试,支持 `fallback` 自定义
600
+ - SuspenseWrapper
601
+ - 作用:Suspense + 错误边界组合
602
+ - LoadingFallback 族
603
+ - 作用:加载与骨架 UI,按需选择与组合
604
+
605
+ 示例:
606
+
607
+ ```tsx
608
+ import { DefaultLoadingFallback, FullScreenLoading, TextSkeletonFallback } from '@qiaopeng/tanstack-query-plus/components'
609
+
610
+ function LoadingExamples() {
611
+ return (
612
+ <div>
613
+ <DefaultLoadingFallback />
614
+ <FullScreenLoading message="加载中..." />
615
+ <TextSkeletonFallback lines={4} />
616
+ </div>
617
+ )
618
+ }
619
+ ```
620
+
621
+ ### 说明与约定
622
+
623
+ - 错误类型默认对齐 v5:`DefaultError`
624
+ - 配置的默认值遵循最佳实践,必要时用 `ensureBestPractices` 自动纠正
625
+ - 可选依赖通过子路径导出按需使用,避免未安装造成解析失败
@@ -1,5 +1,6 @@
1
1
  export { createCustomConfig, DEFAULT_GC_TIME, DEFAULT_MUTATION_CONFIG, DEFAULT_QUERY_CONFIG, DEFAULT_STALE_TIME, defaultMutationRetryStrategy, defaultQueryRetryStrategy, DEVELOPMENT_CONFIG, ensureBestPractices, exponentialBackoff, getConfigByEnvironment, GLOBAL_QUERY_CONFIG, LONG_CACHE_CONFIG, PRODUCTION_CONFIG, REALTIME_CONFIG, SMART_RETRY_MUTATION_CONFIG, TIME_CONSTANTS, validateConfig, validateGcTime } from "./config.js";
2
2
  export { createDevToolsConfig, defaultDevToolsConfig, type DevToolsConfig, isDevToolsEnabled } from "./devtools.js";
3
+ export { ReactQueryDevtools } from "./devtools.js";
3
4
  export { focusManager, type FocusManagerConfig, getSmartFocusManager, pauseFocusManager, resetSmartFocusManager, resumeFocusManager, setupFocusManager, SmartFocusManager } from "./focusManager.js";
4
5
  export { areKeysEqual, containsEntity, createComplexKey, createDomainKeyFactory, createFilteredKey, createMutationKeyFactory, createPaginatedKey, createSearchKey, createSortedKey, extractEntityId, matchesKeyPattern, normalizeQueryKey, queryKeys, validateQueryKey } from "./keys.js";
5
6
  export { createAppQueryOptions, createAppQueryOptionsWithSelect } from "./queryOptions.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,cAAc,EACd,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,cAAc,EACd,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { createCustomConfig, DEFAULT_GC_TIME, DEFAULT_MUTATION_CONFIG, DEFAULT_QUERY_CONFIG, DEFAULT_STALE_TIME, defaultMutationRetryStrategy, defaultQueryRetryStrategy, DEVELOPMENT_CONFIG, ensureBestPractices, exponentialBackoff, getConfigByEnvironment, GLOBAL_QUERY_CONFIG, LONG_CACHE_CONFIG, PRODUCTION_CONFIG, REALTIME_CONFIG, SMART_RETRY_MUTATION_CONFIG, TIME_CONSTANTS, validateConfig, validateGcTime } from "./config.js";
2
2
  export { createDevToolsConfig, defaultDevToolsConfig, isDevToolsEnabled } from "./devtools.js";
3
+ export { ReactQueryDevtools } from "./devtools.js";
3
4
  export { focusManager, getSmartFocusManager, pauseFocusManager, resetSmartFocusManager, resumeFocusManager, setupFocusManager, SmartFocusManager } from "./focusManager.js";
4
5
  export { areKeysEqual, containsEntity, createComplexKey, createDomainKeyFactory, createFilteredKey, createMutationKeyFactory, createPaginatedKey, createSearchKey, createSortedKey, extractEntityId, matchesKeyPattern, normalizeQueryKey, queryKeys, validateQueryKey } from "./keys.js";
5
6
  export { createAppQueryOptions, createAppQueryOptionsWithSelect } from "./queryOptions.js";
@@ -1 +1 @@
1
- {"version":3,"file":"usePrefetch.d.ts","sourceRoot":"","sources":["../../src/hooks/usePrefetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAMrE,MAAM,WAAW,eAAe;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AAC1F,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAAG,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AACrF,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAAG,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE;AAEjI,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,GAAE,oBAAyB;;;;EAkBtI;AAGD,wBAAgB,gBAAgB,KAEV,KAAK,sBAAsB,QAAQ,WAAW,aAAa,CAAC,KAAK,CAAC,YAAY,eAAe,UAKlH;AAED,wBAAgB,gBAAgB,KAEV,KAAK,qBAAqB,KAAK,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,UAK/H;AAED,wBAAgB,gBAAgB;eASA,KAAK,sBAAsB,QAAQ,WAAW,aAAa,CAAC,KAAK,CAAC,YAAY,eAAe;;;EAS5H;AAED,wBAAgB,sBAAsB,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,QAcvJ;AAED,wBAAgB,eAAe,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,QAoBnJ;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,QAgBxJ;AAED,wBAAgB,qBAAqB;gCAIY,MAAM,UAAU,MAAM;;wBAa9B,KAAK,4BAA4B,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;KAAE;;EASlJ;AAED,wBAAgB,mBAAmB;sBAII,KAAK,sBAAsB,QAAQ,WAAW,aAAa,CAAC,KAAK,CAAC,aAAY,MAAM,GAAG,QAAQ,GAAG,KAAK;;;;EAmB7I"}
1
+ {"version":3,"file":"usePrefetch.d.ts","sourceRoot":"","sources":["../../src/hooks/usePrefetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAMrE,MAAM,WAAW,eAAe;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AAC1F,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAAG,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AACrF,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAAG,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE;AASjI,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,GAAE,oBAAyB;;;;EAmBtI;AAGD,wBAAgB,gBAAgB,KAEV,KAAK,sBAAsB,QAAQ,WAAW,aAAa,CAAC,KAAK,CAAC,YAAY,eAAe,UAMlH;AAED,wBAAgB,gBAAgB,KAEV,KAAK,qBAAqB,KAAK,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,UAO/H;AAED,wBAAgB,gBAAgB;eASA,KAAK,sBAAsB,QAAQ,WAAW,aAAa,CAAC,KAAK,CAAC,YAAY,eAAe;;;EAU5H;AAED,wBAAgB,sBAAsB,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,QAgBvJ;AAED,wBAAgB,eAAe,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,QAwBnJ;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,QAkBxJ;AAED,wBAAgB,qBAAqB;gCAIY,MAAM,UAAU,MAAM;;wBAa9B,KAAK,4BAA4B,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;KAAE;;EASlJ;AAED,wBAAgB,mBAAmB;sBAII,KAAK,sBAAsB,QAAQ,WAAW,aAAa,CAAC,KAAK,CAAC,aAAY,MAAM,GAAG,QAAQ,GAAG,KAAK;;;;EAmB7I"}
@@ -2,6 +2,13 @@ import { useQueryClient } from "@tanstack/react-query";
2
2
  import { useCallback, useEffect, useRef, useState } from "react";
3
3
  import { DEFAULT_STALE_TIME } from "../core/config.js";
4
4
  import { isSlowNetwork } from "../utils/network.js";
5
+ function isMissingOrStale(queryClient, queryKey, staleTime) {
6
+ const state = queryClient.getQueryState(queryKey);
7
+ if (!state || state.data === undefined)
8
+ return true;
9
+ const updatedAt = state.dataUpdatedAt ?? 0;
10
+ return Date.now() - updatedAt > staleTime;
11
+ }
5
12
  export function useHoverPrefetch(queryKey, queryFn, options = {}) {
6
13
  const queryClient = useQueryClient();
7
14
  const timeoutRef = useRef(undefined);
@@ -11,6 +18,8 @@ export function useHoverPrefetch(queryKey, queryFn, options = {}) {
11
18
  const prefetch = useCallback(() => {
12
19
  if (!enabled)
13
20
  return;
21
+ if (!isMissingOrStale(queryClient, queryKey, staleTime))
22
+ return;
14
23
  queryClient.prefetchQuery({ queryKey, queryFn: queryFnRef.current, staleTime });
15
24
  }, [queryClient, queryKey, enabled, staleTime]);
16
25
  const handleMouseEnter = useCallback(() => {
@@ -35,6 +44,8 @@ export function useRoutePrefetch() {
35
44
  const { enabled = true, staleTime = DEFAULT_STALE_TIME } = options || {};
36
45
  if (!enabled)
37
46
  return;
47
+ if (!isMissingOrStale(queryClient, queryKey, staleTime))
48
+ return;
38
49
  queryClient.prefetchQuery({ queryKey, queryFn, staleTime });
39
50
  }, [queryClient]);
40
51
  }
@@ -42,7 +53,9 @@ export function useBatchPrefetch() {
42
53
  const queryClient = useQueryClient();
43
54
  return useCallback((queries) => {
44
55
  queries.forEach(({ queryKey, queryFn, staleTime = DEFAULT_STALE_TIME }) => {
45
- queryClient.prefetchQuery({ queryKey, queryFn, staleTime });
56
+ if (isMissingOrStale(queryClient, queryKey, staleTime)) {
57
+ queryClient.prefetchQuery({ queryKey, queryFn, staleTime });
58
+ }
46
59
  });
47
60
  }, [queryClient]);
48
61
  }
@@ -61,6 +74,8 @@ export function useSmartPrefetch() {
61
74
  if (!shouldPrefetchQuery(queryKey))
62
75
  return;
63
76
  const { staleTime = DEFAULT_STALE_TIME } = options || {};
77
+ if (!isMissingOrStale(queryClient, queryKey, staleTime))
78
+ return;
64
79
  const key = JSON.stringify(queryKey);
65
80
  prefetchedRef.current.add(key);
66
81
  queryClient.prefetchQuery({ queryKey, queryFn, staleTime });
@@ -81,7 +96,9 @@ export function useConditionalPrefetch(queryKey, queryFn, condition, options) {
81
96
  if (!condition)
82
97
  return;
83
98
  const timeoutId = setTimeout(() => {
84
- queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
99
+ if (isMissingOrStale(queryClient, stableQueryKey.current, staleTime)) {
100
+ queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
101
+ }
85
102
  }, delay);
86
103
  return () => clearTimeout(timeoutId);
87
104
  }, [condition, queryClient, staleTime, delay]);
@@ -100,12 +117,16 @@ export function useIdlePrefetch(queryKey, queryFn, options) {
100
117
  return;
101
118
  if (typeof window === "undefined" || !("requestIdleCallback" in window)) {
102
119
  const timeoutId = setTimeout(() => {
103
- queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
120
+ if (isMissingOrStale(queryClient, stableQueryKey.current, staleTime)) {
121
+ queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
122
+ }
104
123
  }, timeout);
105
124
  return () => clearTimeout(timeoutId);
106
125
  }
107
126
  const idleCallbackId = window.requestIdleCallback(() => {
108
- queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
127
+ if (isMissingOrStale(queryClient, stableQueryKey.current, staleTime)) {
128
+ queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
129
+ }
109
130
  }, { timeout });
110
131
  return () => window.cancelIdleCallback(idleCallbackId);
111
132
  }, [queryClient, staleTime, enabled, timeout]);
@@ -123,7 +144,9 @@ export function usePeriodicPrefetch(queryKey, queryFn, options) {
123
144
  if (!enabled)
124
145
  return;
125
146
  const prefetchData = () => {
126
- queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
147
+ if (isMissingOrStale(queryClient, stableQueryKey.current, staleTime)) {
148
+ queryClient.prefetchQuery({ queryKey: stableQueryKey.current, queryFn: queryFnRef.current, staleTime });
149
+ }
127
150
  };
128
151
  prefetchData();
129
152
  const intervalId = setInterval(prefetchData, interval);
@@ -1,5 +1,5 @@
1
- import type { QueryKey, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
1
+ import type { DefaultError, QueryKey, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
2
2
  import { skipToken } from "@tanstack/react-query";
3
- export declare function useEnhancedQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>): UseQueryResult<TData, TError>;
3
+ export declare function useEnhancedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>): UseQueryResult<TData, TError>;
4
4
  export { skipToken };
5
5
  //# sourceMappingURL=useQuery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAY,MAAM,uBAAuB,CAAC;AAC5D,wBAAgB,gBAAgB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,OAAO,EAAE,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAErO;AACD,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrG,OAAO,EAAE,SAAS,EAAY,MAAM,uBAAuB,CAAC;AAC5D,wBAAgB,gBAAgB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,OAAO,EAAE,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAE5O;AACD,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,11 +1,11 @@
1
- import type { QueryFunction, QueryFunctionContext, QueryKey, UseSuspenseInfiniteQueryOptions, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
1
+ import type { DefaultError, QueryFunction, QueryFunctionContext, QueryKey, UseSuspenseInfiniteQueryOptions, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
2
2
  type InfiniteQueryFunction<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown> = (context: QueryFunctionContext<TQueryKey, TPageParam>) => Promise<TQueryFnData>;
3
- export declare function createSuspenseQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TVariables = void>(getQueryKey: (variables: TVariables) => TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: Omit<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryKey" | "queryFn">): (variables: TVariables) => UseSuspenseQueryResult<TData, TError>;
4
- export declare function createSuspenseInfiniteQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown, TVariables = void>(getQueryKey: (variables: TVariables) => TQueryKey, queryFn: InfiniteQueryFunction<TQueryFnData, TQueryKey, TPageParam>, options: Omit<UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>, "queryKey" | "queryFn"> & {
3
+ export declare function createSuspenseQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TVariables = void>(getQueryKey: (variables: TVariables) => TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: Omit<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryKey" | "queryFn">): (variables: TVariables) => UseSuspenseQueryResult<TData, TError>;
4
+ export declare function createSuspenseInfiniteQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown, TVariables = void>(getQueryKey: (variables: TVariables) => TQueryKey, queryFn: InfiniteQueryFunction<TQueryFnData, TQueryKey, TPageParam>, options: Omit<UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>, "queryKey" | "queryFn"> & {
5
5
  getNextPageParam: (lastPage: TQueryFnData, allPages: TQueryFnData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null;
6
6
  initialPageParam: TPageParam;
7
7
  }): (variables: TVariables) => UseSuspenseInfiniteQueryResult<TData, TError>;
8
- export declare function useEnhancedSuspenseQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>): UseSuspenseQueryResult<TData, TError>;
9
- export declare function useEnhancedSuspenseInfiniteQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(options: UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>): UseSuspenseInfiniteQueryResult<TData, TError>;
8
+ export declare function useEnhancedSuspenseQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>): UseSuspenseQueryResult<TData, TError>;
9
+ export declare function useEnhancedSuspenseInfiniteQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(options: UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>): UseSuspenseInfiniteQueryResult<TData, TError>;
10
10
  export {};
11
11
  //# sourceMappingURL=useSuspenseQuery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSuspenseQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useSuspenseQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,+BAA+B,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE7M,KAAK,qBAAqB,CAAC,YAAY,GAAG,OAAO,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,SAAS,EAAE,UAAU,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAClM,wBAAgB,mBAAmB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,IAAI,EACxJ,WAAW,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,SAAS,EACjD,OAAO,EAAE,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,EAC/C,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,IAE/F,WAAW,UAAU,KAAG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAItE;AACD,wBAAgB,2BAA2B,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,EAAE,UAAU,GAAG,IAAI,EACtL,WAAW,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,SAAS,EACjD,OAAO,EAAE,qBAAqB,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,EACnE,OAAO,EAAE,IAAI,CAAC,+BAA+B,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC3H,gBAAgB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC9J,gBAAgB,EAAE,UAAU,CAAC;CAC9B,IAEO,WAAW,UAAU,KAAG,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,CAI9E;AACD,wBAAgB,wBAAwB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,OAAO,EAAE,uBAAuB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAE7P;AACD,wBAAgB,gCAAgC,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,EAAE,OAAO,EAAE,+BAA+B,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,CAEvT"}
1
+ {"version":3,"file":"useSuspenseQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useSuspenseQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,+BAA+B,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE3N,KAAK,qBAAqB,CAAC,YAAY,GAAG,OAAO,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,SAAS,EAAE,UAAU,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAClM,wBAAgB,mBAAmB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,IAAI,EAC/J,WAAW,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,SAAS,EACjD,OAAO,EAAE,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,EAC/C,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,IAE/F,WAAW,UAAU,KAAG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAItE;AACD,wBAAgB,2BAA2B,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,EAAE,UAAU,GAAG,IAAI,EAC7L,WAAW,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,SAAS,EACjD,OAAO,EAAE,qBAAqB,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,EACnE,OAAO,EAAE,IAAI,CAAC,+BAA+B,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC3H,gBAAgB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC9J,gBAAgB,EAAE,UAAU,CAAC;CAC9B,IAEO,WAAW,UAAU,KAAG,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,CAI9E;AACD,wBAAgB,wBAAwB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,OAAO,EAAE,uBAAuB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAEpQ;AACD,wBAAgB,gCAAgC,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,EAAE,OAAO,EAAE,+BAA+B,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,CAE9T"}
package/dist/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export * from "./hooks/index.js";
4
4
  export { PersistQueryClientProvider, type PersistQueryClientProviderProps } from "./PersistQueryClientProvider.js";
5
5
  export * from "./types/index.js";
6
6
  export * from "./utils/index.js";
7
- export { QueryClient, QueryClientProvider, skipToken, useQueryClient } from "@tanstack/react-query";
7
+ export { QueryClient, QueryClientProvider, skipToken, useQueryClient, useIsMutating } from "@tanstack/react-query";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,KAAK,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AACnH,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,KAAK,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AACnH,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -4,4 +4,4 @@ export * from "./hooks/index.js";
4
4
  export { PersistQueryClientProvider } from "./PersistQueryClientProvider.js";
5
5
  export * from "./types/index.js";
6
6
  export * from "./utils/index.js";
7
- export { QueryClient, QueryClientProvider, skipToken, useQueryClient } from "@tanstack/react-query";
7
+ export { QueryClient, QueryClientProvider, skipToken, useQueryClient, useIsMutating } from "@tanstack/react-query";
@@ -0,0 +1,3 @@
1
+ export { QueryClient, QueryClientProvider, useQueryClient, skipToken, useIsMutating } from "@tanstack/react-query";
2
+ export type { UseQueryOptions, UseSuspenseQueryOptions, UseInfiniteQueryOptions, QueryKey, MutationKey, InfiniteData } from "@tanstack/react-query";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-query/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,aAAa,EACd,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,YAAY,EACb,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ export { QueryClient, QueryClientProvider, useQueryClient, skipToken, useIsMutating } from "@tanstack/react-query";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qiaopeng/tanstack-query-plus",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Enhanced TanStack Query toolkit: defaults, hooks, persistence, offline, utils",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,11 +8,28 @@
8
8
  "module": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
10
  "sideEffects": false,
11
+ "engines": {
12
+ "node": ">=16"
13
+ },
14
+ "keywords": [
15
+ "tanstack",
16
+ "react-query",
17
+ "query",
18
+ "hooks",
19
+ "persistence",
20
+ "offline",
21
+ "suspense",
22
+ "devtools"
23
+ ],
11
24
  "exports": {
12
25
  ".": {
13
26
  "import": "./dist/index.js",
14
27
  "types": "./dist/index.d.ts"
15
28
  },
29
+ "./react-query": {
30
+ "import": "./dist/react-query/index.js",
31
+ "types": "./dist/react-query/index.d.ts"
32
+ },
16
33
  "./core": {
17
34
  "import": "./dist/core/index.js",
18
35
  "types": "./dist/core/index.d.ts"