@tanstack/react-query 5.59.10 → 5.59.12

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.
Files changed (61) hide show
  1. package/build/legacy/QueryErrorResetBoundary.cjs.map +1 -1
  2. package/build/legacy/QueryErrorResetBoundary.d.cts +9 -5
  3. package/build/legacy/QueryErrorResetBoundary.d.ts +9 -5
  4. package/build/legacy/QueryErrorResetBoundary.js.map +1 -1
  5. package/build/legacy/index.cjs.map +1 -1
  6. package/build/legacy/index.d.cts +3 -3
  7. package/build/legacy/index.d.ts +3 -3
  8. package/build/legacy/index.js.map +1 -1
  9. package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
  10. package/build/legacy/infiniteQueryOptions.d.cts +8 -2
  11. package/build/legacy/infiniteQueryOptions.d.ts +8 -2
  12. package/build/legacy/infiniteQueryOptions.js.map +1 -1
  13. package/build/legacy/queryOptions.cjs.map +1 -1
  14. package/build/legacy/queryOptions.d.cts +8 -2
  15. package/build/legacy/queryOptions.d.ts +8 -2
  16. package/build/legacy/queryOptions.js.map +1 -1
  17. package/build/legacy/types.cjs.map +1 -1
  18. package/build/legacy/types.d.cts +5 -3
  19. package/build/legacy/types.d.ts +5 -3
  20. package/build/legacy/useSuspenseInfiniteQuery.cjs.map +1 -1
  21. package/build/legacy/useSuspenseInfiniteQuery.js.map +1 -1
  22. package/build/legacy/useSuspenseQuery.cjs.map +1 -1
  23. package/build/legacy/useSuspenseQuery.js.map +1 -1
  24. package/build/modern/QueryErrorResetBoundary.cjs.map +1 -1
  25. package/build/modern/QueryErrorResetBoundary.d.cts +9 -5
  26. package/build/modern/QueryErrorResetBoundary.d.ts +9 -5
  27. package/build/modern/QueryErrorResetBoundary.js.map +1 -1
  28. package/build/modern/index.cjs.map +1 -1
  29. package/build/modern/index.d.cts +3 -3
  30. package/build/modern/index.d.ts +3 -3
  31. package/build/modern/index.js.map +1 -1
  32. package/build/modern/infiniteQueryOptions.cjs.map +1 -1
  33. package/build/modern/infiniteQueryOptions.d.cts +8 -2
  34. package/build/modern/infiniteQueryOptions.d.ts +8 -2
  35. package/build/modern/infiniteQueryOptions.js.map +1 -1
  36. package/build/modern/queryOptions.cjs.map +1 -1
  37. package/build/modern/queryOptions.d.cts +8 -2
  38. package/build/modern/queryOptions.d.ts +8 -2
  39. package/build/modern/queryOptions.js.map +1 -1
  40. package/build/modern/types.cjs.map +1 -1
  41. package/build/modern/types.d.cts +5 -3
  42. package/build/modern/types.d.ts +5 -3
  43. package/build/modern/useSuspenseInfiniteQuery.cjs.map +1 -1
  44. package/build/modern/useSuspenseInfiniteQuery.js.map +1 -1
  45. package/build/modern/useSuspenseQuery.cjs.map +1 -1
  46. package/build/modern/useSuspenseQuery.js.map +1 -1
  47. package/package.json +2 -2
  48. package/src/QueryErrorResetBoundary.tsx +12 -9
  49. package/src/__tests__/infiniteQueryOptions.test-d.tsx +13 -1
  50. package/src/__tests__/prefetch.test.tsx +7 -3
  51. package/src/__tests__/queryOptions.test-d.tsx +10 -0
  52. package/src/__tests__/suspense.test-d.tsx +29 -11
  53. package/src/__tests__/useMutationState.test.tsx +13 -1
  54. package/src/__tests__/useQuery.test.tsx +87 -0
  55. package/src/__tests__/useSuspenseQueries.test-d.tsx +41 -18
  56. package/src/index.ts +8 -0
  57. package/src/infiniteQueryOptions.ts +56 -0
  58. package/src/queryOptions.ts +28 -0
  59. package/src/types.ts +22 -4
  60. package/src/useSuspenseInfiniteQuery.ts +1 -1
  61. package/src/useSuspenseQuery.ts +1 -1
@@ -7385,5 +7385,92 @@ describe('useQuery', () => {
7385
7385
  fireEvent.click(rendered.getByText('enable'))
7386
7386
  await waitFor(() => rendered.getByText('test1'))
7387
7387
  })
7388
+
7389
+ it('should show correct data when read from cache only (staleTime)', async () => {
7390
+ const key = queryKey()
7391
+ let suspenseRenderCount = 0
7392
+ queryClient.setQueryData(key, 'initial')
7393
+
7394
+ function MyComponent(props: { promise: Promise<string> }) {
7395
+ const data = React.use(props.promise)
7396
+
7397
+ return <>{data}</>
7398
+ }
7399
+
7400
+ function Loading() {
7401
+ suspenseRenderCount++
7402
+ return <>loading..</>
7403
+ }
7404
+ function Page() {
7405
+ const query = useQuery({
7406
+ queryKey: key,
7407
+ queryFn: async () => {
7408
+ await sleep(1)
7409
+ return 'test'
7410
+ },
7411
+ staleTime: Infinity,
7412
+ })
7413
+
7414
+ return (
7415
+ <React.Suspense fallback={<Loading />}>
7416
+ <MyComponent promise={query.promise} />
7417
+ </React.Suspense>
7418
+ )
7419
+ }
7420
+
7421
+ const rendered = renderWithClient(queryClient, <Page />)
7422
+ await waitFor(() => rendered.getByText('initial'))
7423
+
7424
+ expect(suspenseRenderCount).toBe(0)
7425
+ })
7426
+
7427
+ it('should show correct data when switching between cache entries without re-fetches', async () => {
7428
+ const key = queryKey()
7429
+
7430
+ function MyComponent(props: { promise: Promise<string> }) {
7431
+ const data = React.use(props.promise)
7432
+
7433
+ return <>{data}</>
7434
+ }
7435
+
7436
+ function Loading() {
7437
+ return <>loading..</>
7438
+ }
7439
+ function Page() {
7440
+ const [count, setCount] = React.useState(0)
7441
+ const query = useQuery({
7442
+ queryKey: [key, count],
7443
+ queryFn: async () => {
7444
+ await sleep(10)
7445
+ return 'test' + count
7446
+ },
7447
+ staleTime: Infinity,
7448
+ })
7449
+
7450
+ return (
7451
+ <div>
7452
+ <React.Suspense fallback={<Loading />}>
7453
+ <MyComponent promise={query.promise} />
7454
+ </React.Suspense>
7455
+ <button onClick={() => setCount(count + 1)}>inc</button>
7456
+ <button onClick={() => setCount(count - 1)}>dec</button>
7457
+ </div>
7458
+ )
7459
+ }
7460
+
7461
+ const rendered = renderWithClient(queryClient, <Page />)
7462
+ await waitFor(() => rendered.getByText('loading..'))
7463
+ await waitFor(() => rendered.getByText('test0'))
7464
+
7465
+ fireEvent.click(rendered.getByText('inc'))
7466
+ await waitFor(() => rendered.getByText('loading..'))
7467
+
7468
+ await waitFor(() => rendered.getByText('test1'))
7469
+
7470
+ console.log('---------dec------------')
7471
+ fireEvent.click(rendered.getByText('dec'))
7472
+
7473
+ await waitFor(() => rendered.getByText('test0'))
7474
+ })
7388
7475
  })
7389
7476
  })
@@ -89,6 +89,47 @@ describe('UseSuspenseQueries config object overload', () => {
89
89
  expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
90
90
  })
91
91
 
92
+ it('should not allow skipToken in queryFn', () => {
93
+ useSuspenseQueries({
94
+ queries: [
95
+ {
96
+ queryKey: ['key'],
97
+ // @ts-expect-error
98
+ queryFn: skipToken,
99
+ },
100
+ ],
101
+ })
102
+
103
+ useSuspenseQueries({
104
+ queries: [
105
+ {
106
+ queryKey: ['key'],
107
+ // @ts-expect-error
108
+ queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
109
+ },
110
+ ],
111
+ })
112
+ })
113
+
114
+ it('TData should have correct type when conditional skipToken is passed', () => {
115
+ const queryResults = useSuspenseQueries({
116
+ queries: [
117
+ {
118
+ queryKey: ['withSkipToken'],
119
+ // @ts-expect-error
120
+ queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
121
+ },
122
+ ],
123
+ })
124
+
125
+ const firstResult = queryResults[0]
126
+
127
+ expectTypeOf(firstResult).toEqualTypeOf<
128
+ UseSuspenseQueryResult<number, Error>
129
+ >()
130
+ expectTypeOf(firstResult.data).toEqualTypeOf<number>()
131
+ })
132
+
92
133
  describe('custom hook', () => {
93
134
  it('should allow custom hooks using UseQueryOptions', () => {
94
135
  type Data = string
@@ -113,22 +154,4 @@ describe('UseSuspenseQueries config object overload', () => {
113
154
  expectTypeOf(data).toEqualTypeOf<Data>()
114
155
  })
115
156
  })
116
-
117
- it('TData should have correct type when conditional skipToken is passed', () => {
118
- const queryResults = useSuspenseQueries({
119
- queries: [
120
- {
121
- queryKey: ['withSkipToken'],
122
- queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
123
- },
124
- ],
125
- })
126
-
127
- const firstResult = queryResults[0]
128
-
129
- expectTypeOf(firstResult).toEqualTypeOf<
130
- UseSuspenseQueryResult<number, Error>
131
- >()
132
- expectTypeOf(firstResult.data).toEqualTypeOf<number>()
133
- })
134
157
  })
package/src/index.ts CHANGED
@@ -21,11 +21,13 @@ export { queryOptions } from './queryOptions'
21
21
  export type {
22
22
  DefinedInitialDataOptions,
23
23
  UndefinedInitialDataOptions,
24
+ UnusedSkipTokenOptions,
24
25
  } from './queryOptions'
25
26
  export { infiniteQueryOptions } from './infiniteQueryOptions'
26
27
  export type {
27
28
  DefinedInitialDataInfiniteOptions,
28
29
  UndefinedInitialDataInfiniteOptions,
30
+ UnusedSkipTokenInfiniteOptions,
29
31
  } from './infiniteQueryOptions'
30
32
  export {
31
33
  QueryClientContext,
@@ -36,6 +38,12 @@ export type { QueryClientProviderProps } from './QueryClientProvider'
36
38
  export type { QueryErrorResetBoundaryProps } from './QueryErrorResetBoundary'
37
39
  export { HydrationBoundary } from './HydrationBoundary'
38
40
  export type { HydrationBoundaryProps } from './HydrationBoundary'
41
+ export type {
42
+ QueryErrorClearResetFunction,
43
+ QueryErrorIsResetFunction,
44
+ QueryErrorResetBoundaryFunction,
45
+ QueryErrorResetFunction,
46
+ } from './QueryErrorResetBoundary'
39
47
  export {
40
48
  QueryErrorResetBoundary,
41
49
  useQueryErrorResetBoundary,
@@ -3,7 +3,9 @@ import type {
3
3
  DefaultError,
4
4
  InfiniteData,
5
5
  InitialDataFunction,
6
+ OmitKeyof,
6
7
  QueryKey,
8
+ SkipToken,
7
9
  } from '@tanstack/query-core'
8
10
  import type { UseInfiniteQueryOptions } from './types'
9
11
 
@@ -29,6 +31,36 @@ export type UndefinedInitialDataInfiniteOptions<
29
31
  >
30
32
  }
31
33
 
34
+ export type UnusedSkipTokenInfiniteOptions<
35
+ TQueryFnData,
36
+ TError = DefaultError,
37
+ TData = InfiniteData<TQueryFnData>,
38
+ TQueryKey extends QueryKey = QueryKey,
39
+ TPageParam = unknown,
40
+ > = OmitKeyof<
41
+ UseInfiniteQueryOptions<
42
+ TQueryFnData,
43
+ TError,
44
+ TData,
45
+ TQueryFnData,
46
+ TQueryKey,
47
+ TPageParam
48
+ >,
49
+ 'queryFn'
50
+ > & {
51
+ queryFn: Exclude<
52
+ UseInfiniteQueryOptions<
53
+ TQueryFnData,
54
+ TError,
55
+ TData,
56
+ TQueryFnData,
57
+ TQueryKey,
58
+ TPageParam
59
+ >['queryFn'],
60
+ SkipToken
61
+ >
62
+ }
63
+
32
64
  type NonUndefinedGuard<T> = T extends undefined ? never : T
33
65
 
34
66
  export type DefinedInitialDataInfiniteOptions<
@@ -75,6 +107,30 @@ export function infiniteQueryOptions<
75
107
  queryKey: DataTag<TQueryKey, InfiniteData<TQueryFnData>>
76
108
  }
77
109
 
110
+ export function infiniteQueryOptions<
111
+ TQueryFnData,
112
+ TError = DefaultError,
113
+ TData = InfiniteData<TQueryFnData>,
114
+ TQueryKey extends QueryKey = QueryKey,
115
+ TPageParam = unknown,
116
+ >(
117
+ options: UnusedSkipTokenInfiniteOptions<
118
+ TQueryFnData,
119
+ TError,
120
+ TData,
121
+ TQueryKey,
122
+ TPageParam
123
+ >,
124
+ ): UnusedSkipTokenInfiniteOptions<
125
+ TQueryFnData,
126
+ TError,
127
+ TData,
128
+ TQueryKey,
129
+ TPageParam
130
+ > & {
131
+ queryKey: DataTag<TQueryKey, InfiniteData<TQueryFnData>>
132
+ }
133
+
78
134
  export function infiniteQueryOptions<
79
135
  TQueryFnData,
80
136
  TError = DefaultError,
@@ -2,7 +2,9 @@ import type {
2
2
  DataTag,
3
3
  DefaultError,
4
4
  InitialDataFunction,
5
+ OmitKeyof,
5
6
  QueryKey,
7
+ SkipToken,
6
8
  } from '@tanstack/query-core'
7
9
  import type { UseQueryOptions } from './types'
8
10
 
@@ -18,6 +20,21 @@ export type UndefinedInitialDataOptions<
18
20
  | NonUndefinedGuard<TQueryFnData>
19
21
  }
20
22
 
23
+ export type UnusedSkipTokenOptions<
24
+ TQueryFnData = unknown,
25
+ TError = DefaultError,
26
+ TData = TQueryFnData,
27
+ TQueryKey extends QueryKey = QueryKey,
28
+ > = OmitKeyof<
29
+ UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
30
+ 'queryFn'
31
+ > & {
32
+ queryFn: Exclude<
33
+ UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>['queryFn'],
34
+ SkipToken
35
+ >
36
+ }
37
+
21
38
  type NonUndefinedGuard<T> = T extends undefined ? never : T
22
39
 
23
40
  export type DefinedInitialDataOptions<
@@ -42,6 +59,17 @@ export function queryOptions<
42
59
  queryKey: DataTag<TQueryKey, TQueryFnData>
43
60
  }
44
61
 
62
+ export function queryOptions<
63
+ TQueryFnData = unknown,
64
+ TError = DefaultError,
65
+ TData = TQueryFnData,
66
+ TQueryKey extends QueryKey = QueryKey,
67
+ >(
68
+ options: UnusedSkipTokenOptions<TQueryFnData, TError, TData, TQueryKey>,
69
+ ): UnusedSkipTokenOptions<TQueryFnData, TError, TData, TQueryKey> & {
70
+ queryKey: DataTag<TQueryKey, TQueryFnData>
71
+ }
72
+
45
73
  export function queryOptions<
46
74
  TQueryFnData = unknown,
47
75
  TError = DefaultError,
package/src/types.ts CHANGED
@@ -14,6 +14,7 @@ import type {
14
14
  QueryKey,
15
15
  QueryObserverOptions,
16
16
  QueryObserverResult,
17
+ SkipToken,
17
18
  } from '@tanstack/query-core'
18
19
 
19
20
  export interface UseBaseQueryOptions<
@@ -47,8 +48,13 @@ export interface UseSuspenseQueryOptions<
47
48
  TQueryKey extends QueryKey = QueryKey,
48
49
  > extends OmitKeyof<
49
50
  UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
50
- 'enabled' | 'throwOnError' | 'placeholderData'
51
- > {}
51
+ 'queryFn' | 'enabled' | 'throwOnError' | 'placeholderData'
52
+ > {
53
+ queryFn: Exclude<
54
+ UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>['queryFn'],
55
+ SkipToken
56
+ >
57
+ }
52
58
 
53
59
  export interface UseInfiniteQueryOptions<
54
60
  TQueryFnData = unknown,
@@ -85,8 +91,20 @@ export interface UseSuspenseInfiniteQueryOptions<
85
91
  TQueryKey,
86
92
  TPageParam
87
93
  >,
88
- 'enabled' | 'throwOnError' | 'placeholderData'
89
- > {}
94
+ 'queryFn' | 'enabled' | 'throwOnError' | 'placeholderData'
95
+ > {
96
+ queryFn: Exclude<
97
+ UseInfiniteQueryOptions<
98
+ TQueryFnData,
99
+ TError,
100
+ TData,
101
+ TQueryData,
102
+ TQueryKey,
103
+ TPageParam
104
+ >['queryFn'],
105
+ SkipToken
106
+ >
107
+ }
90
108
 
91
109
  export type UseBaseQueryResult<
92
110
  TData = unknown,
@@ -33,7 +33,7 @@ export function useSuspenseInfiniteQuery<
33
33
  queryClient?: QueryClient,
34
34
  ): UseSuspenseInfiniteQueryResult<TData, TError> {
35
35
  if (process.env.NODE_ENV !== 'production') {
36
- if (options.queryFn === skipToken) {
36
+ if ((options.queryFn as any) === skipToken) {
37
37
  console.error('skipToken is not allowed for useSuspenseInfiniteQuery')
38
38
  }
39
39
  }
@@ -15,7 +15,7 @@ export function useSuspenseQuery<
15
15
  queryClient?: QueryClient,
16
16
  ): UseSuspenseQueryResult<TData, TError> {
17
17
  if (process.env.NODE_ENV !== 'production') {
18
- if (options.queryFn === skipToken) {
18
+ if ((options.queryFn as any) === skipToken) {
19
19
  console.error('skipToken is not allowed for useSuspenseQuery')
20
20
  }
21
21
  }