@tanstack/preact-query 5.102.8 → 5.103.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.
Files changed (205) hide show
  1. package/build/legacy/HydrationBoundary.cjs +1 -1
  2. package/build/legacy/HydrationBoundary.cjs.map +1 -1
  3. package/build/legacy/HydrationBoundary.js +1 -1
  4. package/build/legacy/HydrationBoundary.js.map +1 -1
  5. package/build/legacy/QueryErrorResetBoundary.cjs +12 -12
  6. package/build/legacy/QueryErrorResetBoundary.cjs.map +1 -1
  7. package/build/legacy/QueryErrorResetBoundary.d.cts +12 -12
  8. package/build/legacy/QueryErrorResetBoundary.d.ts +12 -12
  9. package/build/legacy/QueryErrorResetBoundary.js +12 -12
  10. package/build/legacy/QueryErrorResetBoundary.js.map +1 -1
  11. package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
  12. package/build/legacy/infiniteQueryOptions.d.cts +41 -55
  13. package/build/legacy/infiniteQueryOptions.d.cts.map +1 -1
  14. package/build/legacy/infiniteQueryOptions.d.ts +41 -55
  15. package/build/legacy/infiniteQueryOptions.d.ts.map +1 -1
  16. package/build/legacy/infiniteQueryOptions.js.map +1 -1
  17. package/build/legacy/mutationOptions.cjs.map +1 -1
  18. package/build/legacy/mutationOptions.d.cts +4 -17
  19. package/build/legacy/mutationOptions.d.cts.map +1 -1
  20. package/build/legacy/mutationOptions.d.ts +4 -17
  21. package/build/legacy/mutationOptions.d.ts.map +1 -1
  22. package/build/legacy/mutationOptions.js.map +1 -1
  23. package/build/legacy/queryOptions.cjs.map +1 -1
  24. package/build/legacy/queryOptions.d.cts +51 -74
  25. package/build/legacy/queryOptions.d.cts.map +1 -1
  26. package/build/legacy/queryOptions.d.ts +51 -74
  27. package/build/legacy/queryOptions.d.ts.map +1 -1
  28. package/build/legacy/queryOptions.js.map +1 -1
  29. package/build/legacy/useInfiniteQuery.cjs.map +1 -1
  30. package/build/legacy/useInfiniteQuery.d.cts +208 -36
  31. package/build/legacy/useInfiniteQuery.d.cts.map +1 -1
  32. package/build/legacy/useInfiniteQuery.d.ts +208 -36
  33. package/build/legacy/useInfiniteQuery.d.ts.map +1 -1
  34. package/build/legacy/useInfiniteQuery.js.map +1 -1
  35. package/build/legacy/useIsFetching.cjs +8 -6
  36. package/build/legacy/useIsFetching.cjs.map +1 -1
  37. package/build/legacy/useIsFetching.d.cts +8 -6
  38. package/build/legacy/useIsFetching.d.cts.map +1 -1
  39. package/build/legacy/useIsFetching.d.ts +8 -6
  40. package/build/legacy/useIsFetching.d.ts.map +1 -1
  41. package/build/legacy/useIsFetching.js +8 -6
  42. package/build/legacy/useIsFetching.js.map +1 -1
  43. package/build/legacy/useMutation.cjs +13 -11
  44. package/build/legacy/useMutation.cjs.map +1 -1
  45. package/build/legacy/useMutation.d.cts +13 -11
  46. package/build/legacy/useMutation.d.cts.map +1 -1
  47. package/build/legacy/useMutation.d.ts +13 -11
  48. package/build/legacy/useMutation.d.ts.map +1 -1
  49. package/build/legacy/useMutation.js +13 -11
  50. package/build/legacy/useMutation.js.map +1 -1
  51. package/build/legacy/useMutationState.cjs +49 -29
  52. package/build/legacy/useMutationState.cjs.map +1 -1
  53. package/build/legacy/useMutationState.d.cts +49 -29
  54. package/build/legacy/useMutationState.d.cts.map +1 -1
  55. package/build/legacy/useMutationState.d.ts +49 -29
  56. package/build/legacy/useMutationState.d.ts.map +1 -1
  57. package/build/legacy/useMutationState.js +49 -29
  58. package/build/legacy/useMutationState.js.map +1 -1
  59. package/build/legacy/useQueries.cjs +50 -23
  60. package/build/legacy/useQueries.cjs.map +1 -1
  61. package/build/legacy/useQueries.d.cts +50 -23
  62. package/build/legacy/useQueries.d.cts.map +1 -1
  63. package/build/legacy/useQueries.d.ts +50 -23
  64. package/build/legacy/useQueries.d.ts.map +1 -1
  65. package/build/legacy/useQueries.js +50 -23
  66. package/build/legacy/useQueries.js.map +1 -1
  67. package/build/legacy/useQuery.cjs.map +1 -1
  68. package/build/legacy/useQuery.d.cts +93 -33
  69. package/build/legacy/useQuery.d.cts.map +1 -1
  70. package/build/legacy/useQuery.d.ts +93 -33
  71. package/build/legacy/useQuery.d.ts.map +1 -1
  72. package/build/legacy/useQuery.js.map +1 -1
  73. package/build/legacy/useSuspenseInfiniteQuery.cjs +57 -7
  74. package/build/legacy/useSuspenseInfiniteQuery.cjs.map +1 -1
  75. package/build/legacy/useSuspenseInfiniteQuery.d.cts +57 -7
  76. package/build/legacy/useSuspenseInfiniteQuery.d.cts.map +1 -1
  77. package/build/legacy/useSuspenseInfiniteQuery.d.ts +57 -7
  78. package/build/legacy/useSuspenseInfiniteQuery.d.ts.map +1 -1
  79. package/build/legacy/useSuspenseInfiniteQuery.js +57 -7
  80. package/build/legacy/useSuspenseInfiniteQuery.js.map +1 -1
  81. package/build/legacy/useSuspenseQueries.cjs.map +1 -1
  82. package/build/legacy/useSuspenseQueries.d.cts +244 -20
  83. package/build/legacy/useSuspenseQueries.d.cts.map +1 -1
  84. package/build/legacy/useSuspenseQueries.d.ts +244 -20
  85. package/build/legacy/useSuspenseQueries.d.ts.map +1 -1
  86. package/build/legacy/useSuspenseQueries.js.map +1 -1
  87. package/build/legacy/useSuspenseQuery.cjs +48 -8
  88. package/build/legacy/useSuspenseQuery.cjs.map +1 -1
  89. package/build/legacy/useSuspenseQuery.d.cts +48 -8
  90. package/build/legacy/useSuspenseQuery.d.cts.map +1 -1
  91. package/build/legacy/useSuspenseQuery.d.ts +48 -8
  92. package/build/legacy/useSuspenseQuery.d.ts.map +1 -1
  93. package/build/legacy/useSuspenseQuery.js +48 -8
  94. package/build/legacy/useSuspenseQuery.js.map +1 -1
  95. package/build/modern/HydrationBoundary.cjs +1 -1
  96. package/build/modern/HydrationBoundary.cjs.map +1 -1
  97. package/build/modern/HydrationBoundary.js +1 -1
  98. package/build/modern/HydrationBoundary.js.map +1 -1
  99. package/build/modern/QueryErrorResetBoundary.cjs +12 -12
  100. package/build/modern/QueryErrorResetBoundary.cjs.map +1 -1
  101. package/build/modern/QueryErrorResetBoundary.d.cts +12 -12
  102. package/build/modern/QueryErrorResetBoundary.d.ts +12 -12
  103. package/build/modern/QueryErrorResetBoundary.js +12 -12
  104. package/build/modern/QueryErrorResetBoundary.js.map +1 -1
  105. package/build/modern/infiniteQueryOptions.cjs.map +1 -1
  106. package/build/modern/infiniteQueryOptions.d.cts +41 -55
  107. package/build/modern/infiniteQueryOptions.d.cts.map +1 -1
  108. package/build/modern/infiniteQueryOptions.d.ts +41 -55
  109. package/build/modern/infiniteQueryOptions.d.ts.map +1 -1
  110. package/build/modern/infiniteQueryOptions.js.map +1 -1
  111. package/build/modern/mutationOptions.cjs.map +1 -1
  112. package/build/modern/mutationOptions.d.cts +4 -17
  113. package/build/modern/mutationOptions.d.cts.map +1 -1
  114. package/build/modern/mutationOptions.d.ts +4 -17
  115. package/build/modern/mutationOptions.d.ts.map +1 -1
  116. package/build/modern/mutationOptions.js.map +1 -1
  117. package/build/modern/queryOptions.cjs.map +1 -1
  118. package/build/modern/queryOptions.d.cts +51 -74
  119. package/build/modern/queryOptions.d.cts.map +1 -1
  120. package/build/modern/queryOptions.d.ts +51 -74
  121. package/build/modern/queryOptions.d.ts.map +1 -1
  122. package/build/modern/queryOptions.js.map +1 -1
  123. package/build/modern/useInfiniteQuery.cjs.map +1 -1
  124. package/build/modern/useInfiniteQuery.d.cts +208 -36
  125. package/build/modern/useInfiniteQuery.d.cts.map +1 -1
  126. package/build/modern/useInfiniteQuery.d.ts +208 -36
  127. package/build/modern/useInfiniteQuery.d.ts.map +1 -1
  128. package/build/modern/useInfiniteQuery.js.map +1 -1
  129. package/build/modern/useIsFetching.cjs +8 -6
  130. package/build/modern/useIsFetching.cjs.map +1 -1
  131. package/build/modern/useIsFetching.d.cts +8 -6
  132. package/build/modern/useIsFetching.d.cts.map +1 -1
  133. package/build/modern/useIsFetching.d.ts +8 -6
  134. package/build/modern/useIsFetching.d.ts.map +1 -1
  135. package/build/modern/useIsFetching.js +8 -6
  136. package/build/modern/useIsFetching.js.map +1 -1
  137. package/build/modern/useMutation.cjs +13 -11
  138. package/build/modern/useMutation.cjs.map +1 -1
  139. package/build/modern/useMutation.d.cts +13 -11
  140. package/build/modern/useMutation.d.cts.map +1 -1
  141. package/build/modern/useMutation.d.ts +13 -11
  142. package/build/modern/useMutation.d.ts.map +1 -1
  143. package/build/modern/useMutation.js +13 -11
  144. package/build/modern/useMutation.js.map +1 -1
  145. package/build/modern/useMutationState.cjs +49 -29
  146. package/build/modern/useMutationState.cjs.map +1 -1
  147. package/build/modern/useMutationState.d.cts +49 -29
  148. package/build/modern/useMutationState.d.cts.map +1 -1
  149. package/build/modern/useMutationState.d.ts +49 -29
  150. package/build/modern/useMutationState.d.ts.map +1 -1
  151. package/build/modern/useMutationState.js +49 -29
  152. package/build/modern/useMutationState.js.map +1 -1
  153. package/build/modern/useQueries.cjs +50 -23
  154. package/build/modern/useQueries.cjs.map +1 -1
  155. package/build/modern/useQueries.d.cts +50 -23
  156. package/build/modern/useQueries.d.cts.map +1 -1
  157. package/build/modern/useQueries.d.ts +50 -23
  158. package/build/modern/useQueries.d.ts.map +1 -1
  159. package/build/modern/useQueries.js +50 -23
  160. package/build/modern/useQueries.js.map +1 -1
  161. package/build/modern/useQuery.cjs.map +1 -1
  162. package/build/modern/useQuery.d.cts +93 -33
  163. package/build/modern/useQuery.d.cts.map +1 -1
  164. package/build/modern/useQuery.d.ts +93 -33
  165. package/build/modern/useQuery.d.ts.map +1 -1
  166. package/build/modern/useQuery.js.map +1 -1
  167. package/build/modern/useSuspenseInfiniteQuery.cjs +57 -7
  168. package/build/modern/useSuspenseInfiniteQuery.cjs.map +1 -1
  169. package/build/modern/useSuspenseInfiniteQuery.d.cts +57 -7
  170. package/build/modern/useSuspenseInfiniteQuery.d.cts.map +1 -1
  171. package/build/modern/useSuspenseInfiniteQuery.d.ts +57 -7
  172. package/build/modern/useSuspenseInfiniteQuery.d.ts.map +1 -1
  173. package/build/modern/useSuspenseInfiniteQuery.js +57 -7
  174. package/build/modern/useSuspenseInfiniteQuery.js.map +1 -1
  175. package/build/modern/useSuspenseQueries.cjs.map +1 -1
  176. package/build/modern/useSuspenseQueries.d.cts +244 -20
  177. package/build/modern/useSuspenseQueries.d.cts.map +1 -1
  178. package/build/modern/useSuspenseQueries.d.ts +244 -20
  179. package/build/modern/useSuspenseQueries.d.ts.map +1 -1
  180. package/build/modern/useSuspenseQueries.js.map +1 -1
  181. package/build/modern/useSuspenseQuery.cjs +48 -8
  182. package/build/modern/useSuspenseQuery.cjs.map +1 -1
  183. package/build/modern/useSuspenseQuery.d.cts +48 -8
  184. package/build/modern/useSuspenseQuery.d.cts.map +1 -1
  185. package/build/modern/useSuspenseQuery.d.ts +48 -8
  186. package/build/modern/useSuspenseQuery.d.ts.map +1 -1
  187. package/build/modern/useSuspenseQuery.js +48 -8
  188. package/build/modern/useSuspenseQuery.js.map +1 -1
  189. package/build/query-codemods/eslint.config.js +7 -0
  190. package/build/query-codemods/root.eslint.config.js +45 -0
  191. package/package.json +11 -11
  192. package/src/HydrationBoundary.tsx +0 -1
  193. package/src/QueryErrorResetBoundary.tsx +12 -12
  194. package/src/infiniteQueryOptions.ts +41 -55
  195. package/src/mutationOptions.ts +4 -17
  196. package/src/queryOptions.ts +50 -73
  197. package/src/useInfiniteQuery.ts +208 -36
  198. package/src/useIsFetching.ts +8 -6
  199. package/src/useMutation.ts +13 -11
  200. package/src/useMutationState.ts +49 -29
  201. package/src/useQueries.ts +50 -23
  202. package/src/useQuery.ts +93 -33
  203. package/src/useSuspenseInfiniteQuery.ts +57 -7
  204. package/src/useSuspenseQueries.ts +244 -20
  205. package/src/useSuspenseQuery.ts +48 -8
@@ -18,9 +18,14 @@ import { DefaultError, QueryClient, QueryKey } from "@tanstack/query-core";
18
18
  * is missing, and `status` is either `success` or `error` (with the derived flags set accordingly).
19
19
  *
20
20
  * @example
21
+ * The query error is thrown if the fetch fails and no cached data exists yet, so an error boundary is
22
+ * required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
23
+ * Use {@link QueryErrorResetBoundary} to let the user retry after such an error:
21
24
  * ```tsx
22
25
  * import { Suspense } from 'preact/compat'
23
- * import { useSuspenseQuery } from '@tanstack/preact-query'
26
+ * import { useErrorBoundary } from 'preact/hooks'
27
+ * import { QueryErrorResetBoundary, useSuspenseQuery } from '@tanstack/preact-query'
28
+ * import type { ComponentChildren } from 'preact'
24
29
  *
25
30
  * function Posts() {
26
31
  * // `data` is guaranteed to be defined here — no `isPending` check needed.
@@ -31,21 +36,56 @@ import { DefaultError, QueryClient, QueryKey } from "@tanstack/query-core";
31
36
  *
32
37
  * return (
33
38
  * <div>
34
- * <h1>Posts {isFetching ? <Spinner /> : null}</h1>
35
- * {data.map((post) => (
36
- * <p key={post.id}>{post.title}</p>
37
- * ))}
39
+ * <h1>Posts {isFetching ? '(refreshing...)' : null}</h1>
40
+ * <ul>
41
+ * {data.map((post) => (
42
+ * <li key={post.id}>{post.title}</li>
43
+ * ))}
44
+ * </ul>
38
45
  * </div>
39
46
  * )
40
47
  * }
41
48
  *
42
49
  * function App() {
43
50
  * return (
44
- * <Suspense fallback={<h1>Loading posts...</h1>}>
45
- * <Posts />
46
- * </Suspense>
51
+ * <QueryErrorResetBoundary>
52
+ * {({ reset }) => (
53
+ * <ErrorBoundary
54
+ * onReset={reset}
55
+ * fallbackRender={({ resetErrorBoundary }) => (
56
+ * <div>
57
+ * There was an error!
58
+ * <button onClick={() => resetErrorBoundary()}>Try again</button>
59
+ * </div>
60
+ * )}
61
+ * >
62
+ * <Suspense fallback={<h1>Loading posts...</h1>}>
63
+ * <Posts />
64
+ * </Suspense>
65
+ * </ErrorBoundary>
66
+ * )}
67
+ * </QueryErrorResetBoundary>
47
68
  * )
48
69
  * }
70
+ *
71
+ * function ErrorBoundary({
72
+ * children,
73
+ * onReset,
74
+ * fallbackRender,
75
+ * }: {
76
+ * children: ComponentChildren
77
+ * onReset: () => void
78
+ * fallbackRender: (props: {
79
+ * error: Error
80
+ * resetErrorBoundary: () => void
81
+ * }) => ComponentChildren
82
+ * }) {
83
+ * const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
84
+ *
85
+ * if (error) return fallbackRender({ error, resetErrorBoundary })
86
+ *
87
+ * return children
88
+ * }
49
89
  * ```
50
90
  */
51
91
  declare function useSuspenseQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: QueryClient): UseSuspenseQueryResult<TData, TError>;
@@ -1 +1 @@
1
- {"version":3,"file":"useSuspenseQuery.d.ts","names":[],"sources":["../../src/useSuspenseQuery.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDgB,iBACd,wBACA,SAAS,cACT,QAAQ,cACR,kBAAkB,WAAW,UAE7B,SAAS,wBAAwB,cAAc,QAAQ,OAAO,YAC9D,cAAc,cACb,uBAAuB,OAAO"}
1
+ {"version":3,"file":"useSuspenseQuery.d.ts","names":[],"sources":["../../src/useSuspenseQuery.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8FgB,iBACd,wBACA,SAAS,cACT,QAAQ,cACR,kBAAkB,WAAW,UAE7B,SAAS,wBAAwB,cAAc,QAAQ,OAAO,YAC9D,cAAc,cACb,uBAAuB,OAAO"}
@@ -19,9 +19,14 @@ import { QueryObserver, skipToken } from "@tanstack/query-core";
19
19
  * is missing, and `status` is either `success` or `error` (with the derived flags set accordingly).
20
20
  *
21
21
  * @example
22
+ * The query error is thrown if the fetch fails and no cached data exists yet, so an error boundary is
23
+ * required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
24
+ * Use {@link QueryErrorResetBoundary} to let the user retry after such an error:
22
25
  * ```tsx
23
26
  * import { Suspense } from 'preact/compat'
24
- * import { useSuspenseQuery } from '@tanstack/preact-query'
27
+ * import { useErrorBoundary } from 'preact/hooks'
28
+ * import { QueryErrorResetBoundary, useSuspenseQuery } from '@tanstack/preact-query'
29
+ * import type { ComponentChildren } from 'preact'
25
30
  *
26
31
  * function Posts() {
27
32
  * // `data` is guaranteed to be defined here — no `isPending` check needed.
@@ -32,21 +37,56 @@ import { QueryObserver, skipToken } from "@tanstack/query-core";
32
37
  *
33
38
  * return (
34
39
  * <div>
35
- * <h1>Posts {isFetching ? <Spinner /> : null}</h1>
36
- * {data.map((post) => (
37
- * <p key={post.id}>{post.title}</p>
38
- * ))}
40
+ * <h1>Posts {isFetching ? '(refreshing...)' : null}</h1>
41
+ * <ul>
42
+ * {data.map((post) => (
43
+ * <li key={post.id}>{post.title}</li>
44
+ * ))}
45
+ * </ul>
39
46
  * </div>
40
47
  * )
41
48
  * }
42
49
  *
43
50
  * function App() {
44
51
  * return (
45
- * <Suspense fallback={<h1>Loading posts...</h1>}>
46
- * <Posts />
47
- * </Suspense>
52
+ * <QueryErrorResetBoundary>
53
+ * {({ reset }) => (
54
+ * <ErrorBoundary
55
+ * onReset={reset}
56
+ * fallbackRender={({ resetErrorBoundary }) => (
57
+ * <div>
58
+ * There was an error!
59
+ * <button onClick={() => resetErrorBoundary()}>Try again</button>
60
+ * </div>
61
+ * )}
62
+ * >
63
+ * <Suspense fallback={<h1>Loading posts...</h1>}>
64
+ * <Posts />
65
+ * </Suspense>
66
+ * </ErrorBoundary>
67
+ * )}
68
+ * </QueryErrorResetBoundary>
48
69
  * )
49
70
  * }
71
+ *
72
+ * function ErrorBoundary({
73
+ * children,
74
+ * onReset,
75
+ * fallbackRender,
76
+ * }: {
77
+ * children: ComponentChildren
78
+ * onReset: () => void
79
+ * fallbackRender: (props: {
80
+ * error: Error
81
+ * resetErrorBoundary: () => void
82
+ * }) => ComponentChildren
83
+ * }) {
84
+ * const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
85
+ *
86
+ * if (error) return fallbackRender({ error, resetErrorBoundary })
87
+ *
88
+ * return children
89
+ * }
50
90
  * ```
51
91
  */
52
92
  function useSuspenseQuery(options, queryClient) {
@@ -1 +1 @@
1
- {"version":3,"file":"useSuspenseQuery.js","names":[],"sources":["../../src/useSuspenseQuery.ts"],"sourcesContent":["import { QueryObserver, skipToken } from '@tanstack/query-core'\nimport type { DefaultError, QueryClient, QueryKey } from '@tanstack/query-core'\n\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport { useBaseQuery } from './useBaseQuery'\n\n/**\n * The options for `useSuspenseQuery` are the same as for `useQuery`, except for `throwOnError`, `enabled`, and\n * `placeholderData`.\n *\n * Caveat: cancellation does not work.\n *\n * @remarks Multiple `useSuspenseQuery` calls in the same component suspend serially, causing a request\n * waterfall — each one blocks rendering until it resolves, so the next doesn't even start fetching until then.\n * Use {@link useSuspenseQueries} instead when you have more than one suspenseful query in a component, so they\n * fetch in parallel.\n * @param options - The {@link UseSuspenseQueryOptions} to use — the same options as `useQuery`, minus the ones listed above.\n * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will\n * be used.\n * @returns The same object as `useQuery`, except that `data` is guaranteed to be defined, `isPlaceholderData`\n * is missing, and `status` is either `success` or `error` (with the derived flags set accordingly).\n *\n * @example\n * ```tsx\n * import { Suspense } from 'preact/compat'\n * import { useSuspenseQuery } from '@tanstack/preact-query'\n *\n * function Posts() {\n * // `data` is guaranteed to be defined here — no `isPending` check needed.\n * const { data, isFetching } = useSuspenseQuery({\n * queryKey: ['posts'],\n * queryFn: fetchPosts,\n * })\n *\n * return (\n * <div>\n * <h1>Posts {isFetching ? <Spinner /> : null}</h1>\n * {data.map((post) => (\n * <p key={post.id}>{post.title}</p>\n * ))}\n * </div>\n * )\n * }\n *\n * function App() {\n * return (\n * <Suspense fallback={<h1>Loading posts...</h1>}>\n * <Posts />\n * </Suspense>\n * )\n * }\n * ```\n */\nexport function useSuspenseQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseSuspenseQueryResult<TData, TError> {\n if (process.env.NODE_ENV !== 'production') {\n if ((options.queryFn as any) === skipToken) {\n console.error('skipToken is not allowed for useSuspenseQuery')\n }\n }\n\n return useBaseQuery(\n {\n ...options,\n enabled: true,\n suspense: true,\n throwOnError: defaultThrowOnError,\n placeholderData: undefined,\n },\n QueryObserver,\n queryClient,\n ) as UseSuspenseQueryResult<TData, TError>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,iBAMd,SACA,aACuC;CACvC,IAAI,QAAQ,IAAI,aAAa,cACtB;MAAA,QAAQ,YAAoB,WAC/B,QAAQ,MAAM,+CAA+C;CAAA;CAIjE,OAAO,aACL;EACE,GAAG;EACH,SAAS;EACT,UAAU;EACV,cAAc;EACd,iBAAiB,KAAA;CACnB,GACA,eACA,WACF;AACF"}
1
+ {"version":3,"file":"useSuspenseQuery.js","names":[],"sources":["../../src/useSuspenseQuery.ts"],"sourcesContent":["import { QueryObserver, skipToken } from '@tanstack/query-core'\nimport type { DefaultError, QueryClient, QueryKey } from '@tanstack/query-core'\n\nimport { defaultThrowOnError } from './suspense'\nimport type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'\nimport { useBaseQuery } from './useBaseQuery'\n\n/**\n * The options for `useSuspenseQuery` are the same as for `useQuery`, except for `throwOnError`, `enabled`, and\n * `placeholderData`.\n *\n * Caveat: cancellation does not work.\n *\n * @remarks Multiple `useSuspenseQuery` calls in the same component suspend serially, causing a request\n * waterfall — each one blocks rendering until it resolves, so the next doesn't even start fetching until then.\n * Use {@link useSuspenseQueries} instead when you have more than one suspenseful query in a component, so they\n * fetch in parallel.\n * @param options - The {@link UseSuspenseQueryOptions} to use — the same options as `useQuery`, minus the ones listed above.\n * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will\n * be used.\n * @returns The same object as `useQuery`, except that `data` is guaranteed to be defined, `isPlaceholderData`\n * is missing, and `status` is either `success` or `error` (with the derived flags set accordingly).\n *\n * @example\n * The query error is thrown if the fetch fails and no cached data exists yet, so an error boundary is\n * required around `<Suspense>`. A failed background refetch instead continues to render the cached data.\n * Use {@link QueryErrorResetBoundary} to let the user retry after such an error:\n * ```tsx\n * import { Suspense } from 'preact/compat'\n * import { useErrorBoundary } from 'preact/hooks'\n * import { QueryErrorResetBoundary, useSuspenseQuery } from '@tanstack/preact-query'\n * import type { ComponentChildren } from 'preact'\n *\n * function Posts() {\n * // `data` is guaranteed to be defined here — no `isPending` check needed.\n * const { data, isFetching } = useSuspenseQuery({\n * queryKey: ['posts'],\n * queryFn: fetchPosts,\n * })\n *\n * return (\n * <div>\n * <h1>Posts {isFetching ? '(refreshing...)' : null}</h1>\n * <ul>\n * {data.map((post) => (\n * <li key={post.id}>{post.title}</li>\n * ))}\n * </ul>\n * </div>\n * )\n * }\n *\n * function App() {\n * return (\n * <QueryErrorResetBoundary>\n * {({ reset }) => (\n * <ErrorBoundary\n * onReset={reset}\n * fallbackRender={({ resetErrorBoundary }) => (\n * <div>\n * There was an error!\n * <button onClick={() => resetErrorBoundary()}>Try again</button>\n * </div>\n * )}\n * >\n * <Suspense fallback={<h1>Loading posts...</h1>}>\n * <Posts />\n * </Suspense>\n * </ErrorBoundary>\n * )}\n * </QueryErrorResetBoundary>\n * )\n * }\n *\n * function ErrorBoundary({\n * children,\n * onReset,\n * fallbackRender,\n * }: {\n * children: ComponentChildren\n * onReset: () => void\n * fallbackRender: (props: {\n * error: Error\n * resetErrorBoundary: () => void\n * }) => ComponentChildren\n * }) {\n * const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())\n *\n * if (error) return fallbackRender({ error, resetErrorBoundary })\n *\n * return children\n * }\n * ```\n */\nexport function useSuspenseQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseSuspenseQueryResult<TData, TError> {\n if (process.env.NODE_ENV !== 'production') {\n if ((options.queryFn as any) === skipToken) {\n console.error('skipToken is not allowed for useSuspenseQuery')\n }\n }\n\n return useBaseQuery(\n {\n ...options,\n enabled: true,\n suspense: true,\n throwOnError: defaultThrowOnError,\n placeholderData: undefined,\n },\n QueryObserver,\n queryClient,\n ) as UseSuspenseQueryResult<TData, TError>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8FA,SAAgB,iBAMd,SACA,aACuC;CACvC,IAAI,QAAQ,IAAI,aAAa,cACtB;MAAA,QAAQ,YAAoB,WAC/B,QAAQ,MAAM,+CAA+C;CAAA;CAIjE,OAAO,aACL;EACE,GAAG;EACH,SAAS;EACT,UAAU;EACV,cAAc;EACd,iBAAiB,KAAA;CACnB,GACA,eACA,WACF;AACF"}
@@ -15,4 +15,11 @@ export default [
15
15
  'sort-imports': 'off',
16
16
  },
17
17
  },
18
+ {
19
+ files: ['src/**/__testfixtures__/**'],
20
+ rules: {
21
+ // Codemod fixtures intentionally preserve historical QueryClient syntax.
22
+ 'no-restricted-syntax': 'off',
23
+ },
24
+ },
18
25
  ]
@@ -44,6 +44,51 @@ export default [
44
44
  '@typescript-eslint/no-empty-function': 'off',
45
45
  '@typescript-eslint/no-unsafe-function-type': 'off',
46
46
  'no-case-declarations': 'off',
47
+ /**
48
+ * Disallows direct calls to deprecated imperative query methods of `QueryClient`
49
+ * for new tests and code
50
+ *
51
+ * Existing tests that directly test the methods from before the refactoring
52
+ * will be grandfathered in and allowed to continue using the deprecated methods.
53
+ * They should not be removed, but new tests should use the new methods instead.
54
+ */
55
+ 'no-restricted-syntax': [
56
+ 'error',
57
+ {
58
+ selector:
59
+ 'CallExpression[callee.type="MemberExpression"]:matches([callee.property.name="fetchQuery"], [callee.computed=true][callee.property.value="fetchQuery"])',
60
+ message: 'Use queryClient.query(options) instead.',
61
+ },
62
+ {
63
+ selector:
64
+ 'CallExpression[callee.type="MemberExpression"]:matches([callee.property.name="prefetchQuery"], [callee.computed=true][callee.property.value="prefetchQuery"])',
65
+ message:
66
+ 'Use queryClient.query(options).catch(noop) instead if errors should be swallowed.',
67
+ },
68
+ {
69
+ selector:
70
+ 'CallExpression[callee.type="MemberExpression"]:matches([callee.property.name="ensureQueryData"], [callee.computed=true][callee.property.value="ensureQueryData"])',
71
+ message:
72
+ "Use queryClient.query({ ...options, staleTime: 'static' }) instead.",
73
+ },
74
+ {
75
+ selector:
76
+ 'CallExpression[callee.type="MemberExpression"]:matches([callee.property.name="fetchInfiniteQuery"], [callee.computed=true][callee.property.value="fetchInfiniteQuery"])',
77
+ message: 'Use queryClient.infiniteQuery(options) instead.',
78
+ },
79
+ {
80
+ selector:
81
+ 'CallExpression[callee.type="MemberExpression"]:matches([callee.property.name="prefetchInfiniteQuery"], [callee.computed=true][callee.property.value="prefetchInfiniteQuery"])',
82
+ message:
83
+ 'Use queryClient.infiniteQuery(options).catch(noop) instead if errors should be swallowed.',
84
+ },
85
+ {
86
+ selector:
87
+ 'CallExpression[callee.type="MemberExpression"]:matches([callee.property.name="ensureInfiniteQueryData"], [callee.computed=true][callee.property.value="ensureInfiniteQueryData"])',
88
+ message:
89
+ "Use queryClient.infiniteQuery({ ...options, staleTime: 'static' }) instead.",
90
+ },
91
+ ],
47
92
  'prefer-const': 'off',
48
93
  },
49
94
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/preact-query",
3
- "version": "5.102.8",
3
+ "version": "5.103.0",
4
4
  "description": "Hooks for managing, caching and syncing asynchronous and remote data in preact",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "!build/codemods/**/__tests__"
44
44
  ],
45
45
  "dependencies": {
46
- "@tanstack/query-core": "5.102.8"
46
+ "@tanstack/query-core": "5.103.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@preact/preset-vite": "^2.10.2",
@@ -55,23 +55,23 @@
55
55
  "preact-render-to-string": "^6.6.4",
56
56
  "typescript": "6.0.3",
57
57
  "typescript-eslint": "^8.54.0",
58
- "@tanstack/query-persist-client-core": "5.102.8",
58
+ "@tanstack/query-persist-client-core": "5.103.0",
59
59
  "@tanstack/query-test-utils": "0.0.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "preact": "^10.0.0"
63
63
  },
64
64
  "scripts": {
65
- "clean": "premove ./build ./coverage ./dist-ts",
66
- "compile": "tsc --build",
65
+ "clean": "premove ./build ./coverage ./dist-ts ./.cache/test-types",
66
+ "compile": "tsc --project tsconfig.json",
67
67
  "test:eslint": "eslint --concurrency=auto ./src",
68
68
  "test:types": "npm-run-all --serial test:types:*",
69
- "test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js --build tsconfig.legacy.json",
70
- "test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js --build tsconfig.legacy.json",
71
- "test:types:ts58": "node ../../node_modules/typescript58/lib/tsc.js --build tsconfig.legacy.json",
72
- "test:types:ts59": "node ../../node_modules/typescript59/lib/tsc.js --build tsconfig.legacy.json",
73
- "test:types:tscurrent": "tsc --build",
74
- "test:types:ts70": "node ../../node_modules/typescript70/lib/tsc.js --build",
69
+ "test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts56 --tsBuildInfoFile .cache/test-types/ts56.tsbuildinfo",
70
+ "test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts57 --tsBuildInfoFile .cache/test-types/ts57.tsbuildinfo",
71
+ "test:types:ts58": "node ../../node_modules/typescript58/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts58 --tsBuildInfoFile .cache/test-types/ts58.tsbuildinfo",
72
+ "test:types:ts59": "node ../../node_modules/typescript59/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts59 --tsBuildInfoFile .cache/test-types/ts59.tsbuildinfo",
73
+ "test:types:tscurrent": "tsc --project tsconfig.json --outDir .cache/test-types/tscurrent --tsBuildInfoFile .cache/test-types/tscurrent.tsbuildinfo",
74
+ "test:types:ts70": "node ../../node_modules/typescript70/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts70 --tsBuildInfoFile .cache/test-types/ts70.tsbuildinfo",
75
75
  "test:lib": "vitest",
76
76
  "test:lib:dev": "pnpm run test:lib --watch",
77
77
  "test:build": "publint --strict && attw --pack",
@@ -138,7 +138,6 @@ export const HydrationBoundary = ({
138
138
  (dehydratedQuery.promise &&
139
139
  existingQuery.state.status !== 'pending' &&
140
140
  existingQuery.state.fetchStatus !== 'fetching' &&
141
- dehydratedQuery.dehydratedAt !== undefined &&
142
141
  dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt)
143
142
 
144
143
  if (hydrationIsNewer) {
@@ -122,6 +122,18 @@ export interface QueryErrorResetBoundaryProps {
122
122
  * import type { ComponentChildren } from 'preact'
123
123
  * import { QueryErrorResetBoundary } from '@tanstack/preact-query'
124
124
  *
125
+ * function App() {
126
+ * return (
127
+ * <QueryErrorResetBoundary>
128
+ * {({ reset }) => (
129
+ * <ErrorBoundary reset={reset}>
130
+ * <Page />
131
+ * </ErrorBoundary>
132
+ * )}
133
+ * </QueryErrorResetBoundary>
134
+ * )
135
+ * }
136
+ *
125
137
  * function ErrorBoundary({
126
138
  * children,
127
139
  * reset,
@@ -142,18 +154,6 @@ export interface QueryErrorResetBoundaryProps {
142
154
  *
143
155
  * return children
144
156
  * }
145
- *
146
- * function App() {
147
- * return (
148
- * <QueryErrorResetBoundary>
149
- * {({ reset }) => (
150
- * <ErrorBoundary reset={reset}>
151
- * <Page />
152
- * </ErrorBoundary>
153
- * )}
154
- * </QueryErrorResetBoundary>
155
- * )
156
- * }
157
157
  * ```
158
158
  */
159
159
  export const QueryErrorResetBoundary = ({
@@ -74,7 +74,9 @@ export type UnusedSkipTokenInfiniteOptions<
74
74
  > & {
75
75
  /**
76
76
  * `skipToken` is not allowed as a value here — this overload is selected when no `initialData` is set. If
77
- * you don't intend to run the query yet, omit `queryFn` or use a default query function instead.
77
+ * you don't intend to run the query yet, set `enabled: false` — omitting `queryFn` alone still triggers a
78
+ * fetch that fails with "Missing queryFn" unless `enabled` is `false` or a default query function has been
79
+ * defined. A default query function only supplies `queryFn`; it doesn't defer the fetch on its own.
78
80
  */
79
81
  queryFn?: Exclude<
80
82
  UseInfiniteQueryOptions<
@@ -135,6 +137,8 @@ export type DefinedInitialDataInfiniteOptions<
135
137
  * @see {@link useInfiniteQuery} to run an infinite query with these options.
136
138
  * @param options - The {@link DefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`, with `initialData` set.
137
139
  * @returns The same options object, typed so that `queryKey` carries the inferred data type.
140
+ * @remarks See {@link useInfiniteQuery} for examples that fetch further pages, from a button click or
141
+ * automatically as the user scrolls.
138
142
  *
139
143
  * @example
140
144
  * ```tsx
@@ -149,8 +153,18 @@ export type DefinedInitialDataInfiniteOptions<
149
153
  * })
150
154
  *
151
155
  * function Projects() {
152
- * const { data } = useInfiniteQuery(projectsOptions)
153
- * return <>{data.pages.map((page) => page.projects.map((p) => <p key={p.id}>{p.name}</p>))}</>
156
+ * // `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
157
+ * // list stays visible alongside the error.
158
+ * const { data, isError, error } = useInfiniteQuery(projectsOptions)
159
+ *
160
+ * return (
161
+ * <div>
162
+ * {isError ? <span>Error: {error.message}</span> : null}
163
+ * <ul>
164
+ * {data.pages.map((page) => page.projects.map((p) => <li key={p.id}>{p.name}</li>))}
165
+ * </ul>
166
+ * </div>
167
+ * )
154
168
  * }
155
169
  * ```
156
170
  */
@@ -183,27 +197,13 @@ export function infiniteQueryOptions<
183
197
  * `options.queryKey` is required and is the query key to generate options for.
184
198
  *
185
199
  * @returns The same options object, typed so that `queryKey` carries the inferred data type.
200
+ * @remarks See {@link useInfiniteQuery} for examples that fetch further pages, from a button click or
201
+ * automatically as the user scrolls.
186
202
  *
187
203
  * @example
204
+ * A parameterized factory, so the same options object can be reused per `postId`:
188
205
  * ```tsx
189
- * import { infiniteQueryOptions } from '@tanstack/preact-query'
190
- *
191
- * export const projectsOptions = infiniteQueryOptions({
192
- * queryKey: ['projects'],
193
- * queryFn: ({ pageParam }) => fetchProjects(pageParam),
194
- * initialPageParam: 0,
195
- * getNextPageParam: (lastPage) => lastPage.nextId,
196
- * })
197
- * ```
198
- *
199
- * @example
200
- * A parameterized factory, reused across a hook and an imperative call with the same cache entry:
201
- * ```tsx
202
- * import {
203
- * infiniteQueryOptions,
204
- * noop,
205
- * useInfiniteQuery,
206
- * } from '@tanstack/preact-query'
206
+ * import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query'
207
207
  *
208
208
  * export const commentsOptions = (postId: string) =>
209
209
  * infiniteQueryOptions({
@@ -214,17 +214,17 @@ export function infiniteQueryOptions<
214
214
  * })
215
215
  *
216
216
  * function Comments({ postId }: { postId: string }) {
217
- * const result = useInfiniteQuery(commentsOptions(postId))
218
- * if (!result.isSuccess) return 'Loading...'
217
+ * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId))
218
+ *
219
+ * if (isPending) return 'Loading...'
220
+ * if (isError) return <span>Error: {error.message}</span>
221
+ *
219
222
  * return (
220
- * <>
221
- * {result.data.pages.map((page) => page.comments.map((c) => <p key={c.id}>{c.text}</p>))}
222
- * </>
223
+ * <ul>
224
+ * {data.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
225
+ * </ul>
223
226
  * )
224
227
  * }
225
- *
226
- * // Elsewhere, e.g. to warm the cache before rendering `<Comments>`:
227
- * queryClient.infiniteQuery(commentsOptions(postId)).catch(noop)
228
228
  * ```
229
229
  *
230
230
  * @see {@link useInfiniteQuery} to run an infinite query with these options.
@@ -259,27 +259,13 @@ export function infiniteQueryOptions<
259
259
  * `options.queryKey` is required and is the query key to generate options for.
260
260
  *
261
261
  * @returns The same options object, typed so that `queryKey` carries the inferred data type.
262
+ * @remarks See {@link useInfiniteQuery} for examples that fetch further pages (from a button click or
263
+ * automatically as the user scrolls) and that use `skipToken` to disable the query until `postId` is set.
262
264
  *
263
265
  * @example
266
+ * A parameterized factory, so the same options object can be reused per `postId`:
264
267
  * ```tsx
265
- * import { infiniteQueryOptions } from '@tanstack/preact-query'
266
- *
267
- * export const projectsOptions = infiniteQueryOptions({
268
- * queryKey: ['projects'],
269
- * queryFn: ({ pageParam }) => fetchProjects(pageParam),
270
- * initialPageParam: 0,
271
- * getNextPageParam: (lastPage) => lastPage.nextId,
272
- * })
273
- * ```
274
- *
275
- * @example
276
- * A parameterized factory, reused across a hook and an imperative call with the same cache entry:
277
- * ```tsx
278
- * import {
279
- * infiniteQueryOptions,
280
- * noop,
281
- * useInfiniteQuery,
282
- * } from '@tanstack/preact-query'
268
+ * import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/preact-query'
283
269
  *
284
270
  * export const commentsOptions = (postId: string) =>
285
271
  * infiniteQueryOptions({
@@ -290,17 +276,17 @@ export function infiniteQueryOptions<
290
276
  * })
291
277
  *
292
278
  * function Comments({ postId }: { postId: string }) {
293
- * const result = useInfiniteQuery(commentsOptions(postId))
294
- * if (!result.isSuccess) return 'Loading...'
279
+ * const { data, isPending, isError, error } = useInfiniteQuery(commentsOptions(postId))
280
+ *
281
+ * if (isPending) return 'Loading...'
282
+ * if (isError) return <span>Error: {error.message}</span>
283
+ *
295
284
  * return (
296
- * <>
297
- * {result.data.pages.map((page) => page.comments.map((c) => <p key={c.id}>{c.text}</p>))}
298
- * </>
285
+ * <ul>
286
+ * {data.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
287
+ * </ul>
299
288
  * )
300
289
  * }
301
- *
302
- * // Elsewhere, e.g. to warm the cache before rendering `<Comments>`:
303
- * queryClient.infiniteQuery(commentsOptions(postId)).catch(noop)
304
290
  * ```
305
291
  *
306
292
  * @see {@link useInfiniteQuery} to run an infinite query with these options.
@@ -13,21 +13,6 @@ import type { UseMutationOptions } from './types'
13
13
  * @returns The same options object, unchanged.
14
14
  *
15
15
  * @example
16
- * ```tsx
17
- * import { mutationOptions, useMutation } from '@tanstack/preact-query'
18
- *
19
- * export const createPostOptions = mutationOptions({
20
- * mutationKey: ['posts', 'create'],
21
- * mutationFn: createPost,
22
- * })
23
- *
24
- * function CreatePost() {
25
- * const mutation = useMutation(createPostOptions)
26
- * return <button onClick={() => mutation.mutate({ title: 'Hello' })}>Create</button>
27
- * }
28
- * ```
29
- *
30
- * @example
31
16
  * Looking the mutation up elsewhere via its `mutationKey`, e.g. for a global "saving…" indicator:
32
17
  * ```tsx
33
18
  * import { mutationOptions, useMutationState } from '@tanstack/preact-query'
@@ -62,13 +47,15 @@ export function mutationOptions<
62
47
  >
63
48
  /**
64
49
  * You can generally pass everything to `mutationOptions` that you can also pass to `useMutation`. No
65
- * `mutationKey` is required on this overload — use this when you don't need to look the mutation up later
66
- * (e.g. with `useMutationState`).
50
+ * `mutationKey` is required on this overload — use this when you don't need to target the mutation via a
51
+ * `mutationKey` filter later (e.g. with `useMutationState`); it can still be observed through other filters,
52
+ * such as `status`.
67
53
  *
68
54
  * @see {@link useMutation} to run the mutation these options describe.
69
55
  * @param options - The mutation options to use, identical to what you'd pass to `useMutation`, without a
70
56
  * `mutationKey`.
71
57
  * @returns The same options object, unchanged.
58
+ * @remarks See the other overload's example for looking a mutation up via `useMutationState`.
72
59
  *
73
60
  * @example
74
61
  * ```tsx