@tanstack/query-core 5.102.7 → 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 (301) hide show
  1. package/build/legacy/environmentManager.cjs +15 -1
  2. package/build/legacy/environmentManager.cjs.map +1 -1
  3. package/build/legacy/environmentManager.d.cts +15 -1
  4. package/build/legacy/environmentManager.d.cts.map +1 -1
  5. package/build/legacy/environmentManager.d.ts +15 -1
  6. package/build/legacy/environmentManager.d.ts.map +1 -1
  7. package/build/legacy/environmentManager.js +15 -1
  8. package/build/legacy/environmentManager.js.map +1 -1
  9. package/build/legacy/focusManager.cjs +57 -0
  10. package/build/legacy/focusManager.cjs.map +1 -1
  11. package/build/legacy/focusManager.d.cts +57 -0
  12. package/build/legacy/focusManager.d.cts.map +1 -1
  13. package/build/legacy/focusManager.d.ts +57 -0
  14. package/build/legacy/focusManager.d.ts.map +1 -1
  15. package/build/legacy/focusManager.js +57 -0
  16. package/build/legacy/focusManager.js.map +1 -1
  17. package/build/legacy/{hydration-Bjs0MSgg.d.ts → hydration-Cq7QYAzB.d.ts} +1424 -7
  18. package/build/legacy/hydration-Cq7QYAzB.d.ts.map +1 -0
  19. package/build/legacy/{hydration-DWGr3cFC.d.cts → hydration-DwR10Hi-.d.cts} +1424 -7
  20. package/build/legacy/hydration-DwR10Hi-.d.cts.map +1 -0
  21. package/build/legacy/hydration.cjs +57 -4
  22. package/build/legacy/hydration.cjs.map +1 -1
  23. package/build/legacy/hydration.d.cts +1 -1
  24. package/build/legacy/hydration.d.ts +1 -1
  25. package/build/legacy/hydration.js +57 -4
  26. package/build/legacy/hydration.js.map +1 -1
  27. package/build/legacy/index.cjs.map +1 -1
  28. package/build/legacy/index.d.cts +5 -5
  29. package/build/legacy/index.d.ts +5 -5
  30. package/build/legacy/index.js.map +1 -1
  31. package/build/legacy/infiniteQueryBehavior.d.cts +1 -1
  32. package/build/legacy/infiniteQueryBehavior.d.ts +1 -1
  33. package/build/legacy/infiniteQueryObserver.cjs +67 -0
  34. package/build/legacy/infiniteQueryObserver.cjs.map +1 -1
  35. package/build/legacy/infiniteQueryObserver.d.cts +68 -1
  36. package/build/legacy/infiniteQueryObserver.d.cts.map +1 -1
  37. package/build/legacy/infiniteQueryObserver.d.ts +68 -1
  38. package/build/legacy/infiniteQueryObserver.d.ts.map +1 -1
  39. package/build/legacy/infiniteQueryObserver.js +67 -0
  40. package/build/legacy/infiniteQueryObserver.js.map +1 -1
  41. package/build/legacy/mutation.cjs +74 -0
  42. package/build/legacy/mutation.cjs.map +1 -1
  43. package/build/legacy/mutation.d.cts +1 -1
  44. package/build/legacy/mutation.d.ts +1 -1
  45. package/build/legacy/mutation.js +74 -0
  46. package/build/legacy/mutation.js.map +1 -1
  47. package/build/legacy/mutationCache.cjs +74 -0
  48. package/build/legacy/mutationCache.cjs.map +1 -1
  49. package/build/legacy/mutationCache.d.cts +1 -1
  50. package/build/legacy/mutationCache.d.ts +1 -1
  51. package/build/legacy/mutationCache.js +74 -0
  52. package/build/legacy/mutationCache.js.map +1 -1
  53. package/build/legacy/mutationObserver.cjs +71 -0
  54. package/build/legacy/mutationObserver.cjs.map +1 -1
  55. package/build/legacy/mutationObserver.d.cts +1 -1
  56. package/build/legacy/mutationObserver.d.ts +1 -1
  57. package/build/legacy/mutationObserver.js +71 -0
  58. package/build/legacy/mutationObserver.js.map +1 -1
  59. package/build/legacy/notifyManager.cjs +45 -1
  60. package/build/legacy/notifyManager.cjs.map +1 -1
  61. package/build/legacy/notifyManager.d.cts +83 -2
  62. package/build/legacy/notifyManager.d.cts.map +1 -1
  63. package/build/legacy/notifyManager.d.ts +83 -2
  64. package/build/legacy/notifyManager.d.ts.map +1 -1
  65. package/build/legacy/notifyManager.js +45 -1
  66. package/build/legacy/notifyManager.js.map +1 -1
  67. package/build/legacy/onlineManager.cjs +47 -0
  68. package/build/legacy/onlineManager.cjs.map +1 -1
  69. package/build/legacy/onlineManager.d.cts +47 -0
  70. package/build/legacy/onlineManager.d.cts.map +1 -1
  71. package/build/legacy/onlineManager.d.ts +47 -0
  72. package/build/legacy/onlineManager.d.ts.map +1 -1
  73. package/build/legacy/onlineManager.js +47 -0
  74. package/build/legacy/onlineManager.js.map +1 -1
  75. package/build/legacy/queriesObserver.cjs +64 -0
  76. package/build/legacy/queriesObserver.cjs.map +1 -1
  77. package/build/legacy/queriesObserver.d.cts +73 -1
  78. package/build/legacy/queriesObserver.d.cts.map +1 -1
  79. package/build/legacy/queriesObserver.d.ts +73 -1
  80. package/build/legacy/queriesObserver.d.ts.map +1 -1
  81. package/build/legacy/queriesObserver.js +64 -0
  82. package/build/legacy/queriesObserver.js.map +1 -1
  83. package/build/legacy/query.cjs +141 -0
  84. package/build/legacy/query.cjs.map +1 -1
  85. package/build/legacy/query.d.cts +1 -1
  86. package/build/legacy/query.d.ts +1 -1
  87. package/build/legacy/query.js +141 -0
  88. package/build/legacy/query.js.map +1 -1
  89. package/build/legacy/queryCache.cjs +120 -0
  90. package/build/legacy/queryCache.cjs.map +1 -1
  91. package/build/legacy/queryCache.d.cts +1 -1
  92. package/build/legacy/queryCache.d.ts +1 -1
  93. package/build/legacy/queryCache.js +120 -0
  94. package/build/legacy/queryCache.js.map +1 -1
  95. package/build/legacy/queryClient.cjs +363 -0
  96. package/build/legacy/queryClient.cjs.map +1 -1
  97. package/build/legacy/queryClient.d.cts +1 -1
  98. package/build/legacy/queryClient.d.ts +1 -1
  99. package/build/legacy/queryClient.js +363 -0
  100. package/build/legacy/queryClient.js.map +1 -1
  101. package/build/legacy/queryObserver.cjs +116 -2
  102. package/build/legacy/queryObserver.cjs.map +1 -1
  103. package/build/legacy/queryObserver.d.cts +1 -1
  104. package/build/legacy/queryObserver.d.ts +1 -1
  105. package/build/legacy/queryObserver.js +116 -2
  106. package/build/legacy/queryObserver.js.map +1 -1
  107. package/build/legacy/retryer.cjs +18 -0
  108. package/build/legacy/retryer.cjs.map +1 -1
  109. package/build/legacy/retryer.d.cts +1 -1
  110. package/build/legacy/retryer.d.ts +1 -1
  111. package/build/legacy/retryer.js +18 -0
  112. package/build/legacy/retryer.js.map +1 -1
  113. package/build/legacy/streamedQuery.cjs +10 -1
  114. package/build/legacy/streamedQuery.cjs.map +1 -1
  115. package/build/legacy/streamedQuery.d.cts +26 -2
  116. package/build/legacy/streamedQuery.d.cts.map +1 -1
  117. package/build/legacy/streamedQuery.d.ts +26 -2
  118. package/build/legacy/streamedQuery.d.ts.map +1 -1
  119. package/build/legacy/streamedQuery.js +10 -1
  120. package/build/legacy/streamedQuery.js.map +1 -1
  121. package/build/legacy/timeoutManager.cjs +99 -0
  122. package/build/legacy/timeoutManager.cjs.map +1 -1
  123. package/build/legacy/timeoutManager.d.cts +105 -0
  124. package/build/legacy/timeoutManager.d.cts.map +1 -1
  125. package/build/legacy/timeoutManager.d.ts +105 -0
  126. package/build/legacy/timeoutManager.d.ts.map +1 -1
  127. package/build/legacy/timeoutManager.js +99 -0
  128. package/build/legacy/timeoutManager.js.map +1 -1
  129. package/build/legacy/types.cjs.map +1 -1
  130. package/build/legacy/types.d.cts +1 -1
  131. package/build/legacy/types.d.ts +1 -1
  132. package/build/legacy/types.js.map +1 -1
  133. package/build/legacy/utils.cjs +76 -0
  134. package/build/legacy/utils.cjs.map +1 -1
  135. package/build/legacy/utils.d.cts +1 -1
  136. package/build/legacy/utils.d.ts +1 -1
  137. package/build/legacy/utils.js +76 -0
  138. package/build/legacy/utils.js.map +1 -1
  139. package/build/modern/environmentManager.cjs +15 -1
  140. package/build/modern/environmentManager.cjs.map +1 -1
  141. package/build/modern/environmentManager.d.cts +15 -1
  142. package/build/modern/environmentManager.d.cts.map +1 -1
  143. package/build/modern/environmentManager.d.ts +15 -1
  144. package/build/modern/environmentManager.d.ts.map +1 -1
  145. package/build/modern/environmentManager.js +15 -1
  146. package/build/modern/environmentManager.js.map +1 -1
  147. package/build/modern/focusManager.cjs +57 -0
  148. package/build/modern/focusManager.cjs.map +1 -1
  149. package/build/modern/focusManager.d.cts +57 -0
  150. package/build/modern/focusManager.d.cts.map +1 -1
  151. package/build/modern/focusManager.d.ts +57 -0
  152. package/build/modern/focusManager.d.ts.map +1 -1
  153. package/build/modern/focusManager.js +57 -0
  154. package/build/modern/focusManager.js.map +1 -1
  155. package/build/modern/{hydration-Bjs0MSgg.d.ts → hydration-Cq7QYAzB.d.ts} +1424 -7
  156. package/build/modern/hydration-Cq7QYAzB.d.ts.map +1 -0
  157. package/build/modern/{hydration-DWGr3cFC.d.cts → hydration-DwR10Hi-.d.cts} +1424 -7
  158. package/build/modern/hydration-DwR10Hi-.d.cts.map +1 -0
  159. package/build/modern/hydration.cjs +57 -4
  160. package/build/modern/hydration.cjs.map +1 -1
  161. package/build/modern/hydration.d.cts +1 -1
  162. package/build/modern/hydration.d.ts +1 -1
  163. package/build/modern/hydration.js +57 -4
  164. package/build/modern/hydration.js.map +1 -1
  165. package/build/modern/index.cjs.map +1 -1
  166. package/build/modern/index.d.cts +5 -5
  167. package/build/modern/index.d.ts +5 -5
  168. package/build/modern/index.js.map +1 -1
  169. package/build/modern/infiniteQueryBehavior.d.cts +1 -1
  170. package/build/modern/infiniteQueryBehavior.d.ts +1 -1
  171. package/build/modern/infiniteQueryObserver.cjs +67 -0
  172. package/build/modern/infiniteQueryObserver.cjs.map +1 -1
  173. package/build/modern/infiniteQueryObserver.d.cts +68 -1
  174. package/build/modern/infiniteQueryObserver.d.cts.map +1 -1
  175. package/build/modern/infiniteQueryObserver.d.ts +68 -1
  176. package/build/modern/infiniteQueryObserver.d.ts.map +1 -1
  177. package/build/modern/infiniteQueryObserver.js +67 -0
  178. package/build/modern/infiniteQueryObserver.js.map +1 -1
  179. package/build/modern/mutation.cjs +74 -0
  180. package/build/modern/mutation.cjs.map +1 -1
  181. package/build/modern/mutation.d.cts +1 -1
  182. package/build/modern/mutation.d.ts +1 -1
  183. package/build/modern/mutation.js +74 -0
  184. package/build/modern/mutation.js.map +1 -1
  185. package/build/modern/mutationCache.cjs +74 -0
  186. package/build/modern/mutationCache.cjs.map +1 -1
  187. package/build/modern/mutationCache.d.cts +1 -1
  188. package/build/modern/mutationCache.d.ts +1 -1
  189. package/build/modern/mutationCache.js +74 -0
  190. package/build/modern/mutationCache.js.map +1 -1
  191. package/build/modern/mutationObserver.cjs +71 -0
  192. package/build/modern/mutationObserver.cjs.map +1 -1
  193. package/build/modern/mutationObserver.d.cts +1 -1
  194. package/build/modern/mutationObserver.d.ts +1 -1
  195. package/build/modern/mutationObserver.js +71 -0
  196. package/build/modern/mutationObserver.js.map +1 -1
  197. package/build/modern/notifyManager.cjs +45 -1
  198. package/build/modern/notifyManager.cjs.map +1 -1
  199. package/build/modern/notifyManager.d.cts +83 -2
  200. package/build/modern/notifyManager.d.cts.map +1 -1
  201. package/build/modern/notifyManager.d.ts +83 -2
  202. package/build/modern/notifyManager.d.ts.map +1 -1
  203. package/build/modern/notifyManager.js +45 -1
  204. package/build/modern/notifyManager.js.map +1 -1
  205. package/build/modern/onlineManager.cjs +47 -0
  206. package/build/modern/onlineManager.cjs.map +1 -1
  207. package/build/modern/onlineManager.d.cts +47 -0
  208. package/build/modern/onlineManager.d.cts.map +1 -1
  209. package/build/modern/onlineManager.d.ts +47 -0
  210. package/build/modern/onlineManager.d.ts.map +1 -1
  211. package/build/modern/onlineManager.js +47 -0
  212. package/build/modern/onlineManager.js.map +1 -1
  213. package/build/modern/queriesObserver.cjs +64 -0
  214. package/build/modern/queriesObserver.cjs.map +1 -1
  215. package/build/modern/queriesObserver.d.cts +73 -1
  216. package/build/modern/queriesObserver.d.cts.map +1 -1
  217. package/build/modern/queriesObserver.d.ts +73 -1
  218. package/build/modern/queriesObserver.d.ts.map +1 -1
  219. package/build/modern/queriesObserver.js +64 -0
  220. package/build/modern/queriesObserver.js.map +1 -1
  221. package/build/modern/query.cjs +141 -0
  222. package/build/modern/query.cjs.map +1 -1
  223. package/build/modern/query.d.cts +1 -1
  224. package/build/modern/query.d.ts +1 -1
  225. package/build/modern/query.js +141 -0
  226. package/build/modern/query.js.map +1 -1
  227. package/build/modern/queryCache.cjs +120 -0
  228. package/build/modern/queryCache.cjs.map +1 -1
  229. package/build/modern/queryCache.d.cts +1 -1
  230. package/build/modern/queryCache.d.ts +1 -1
  231. package/build/modern/queryCache.js +120 -0
  232. package/build/modern/queryCache.js.map +1 -1
  233. package/build/modern/queryClient.cjs +363 -0
  234. package/build/modern/queryClient.cjs.map +1 -1
  235. package/build/modern/queryClient.d.cts +1 -1
  236. package/build/modern/queryClient.d.ts +1 -1
  237. package/build/modern/queryClient.js +363 -0
  238. package/build/modern/queryClient.js.map +1 -1
  239. package/build/modern/queryObserver.cjs +116 -2
  240. package/build/modern/queryObserver.cjs.map +1 -1
  241. package/build/modern/queryObserver.d.cts +1 -1
  242. package/build/modern/queryObserver.d.ts +1 -1
  243. package/build/modern/queryObserver.js +116 -2
  244. package/build/modern/queryObserver.js.map +1 -1
  245. package/build/modern/retryer.cjs +18 -0
  246. package/build/modern/retryer.cjs.map +1 -1
  247. package/build/modern/retryer.d.cts +1 -1
  248. package/build/modern/retryer.d.ts +1 -1
  249. package/build/modern/retryer.js +18 -0
  250. package/build/modern/retryer.js.map +1 -1
  251. package/build/modern/streamedQuery.cjs +10 -1
  252. package/build/modern/streamedQuery.cjs.map +1 -1
  253. package/build/modern/streamedQuery.d.cts +26 -2
  254. package/build/modern/streamedQuery.d.cts.map +1 -1
  255. package/build/modern/streamedQuery.d.ts +26 -2
  256. package/build/modern/streamedQuery.d.ts.map +1 -1
  257. package/build/modern/streamedQuery.js +10 -1
  258. package/build/modern/streamedQuery.js.map +1 -1
  259. package/build/modern/timeoutManager.cjs +99 -0
  260. package/build/modern/timeoutManager.cjs.map +1 -1
  261. package/build/modern/timeoutManager.d.cts +105 -0
  262. package/build/modern/timeoutManager.d.cts.map +1 -1
  263. package/build/modern/timeoutManager.d.ts +105 -0
  264. package/build/modern/timeoutManager.d.ts.map +1 -1
  265. package/build/modern/timeoutManager.js +99 -0
  266. package/build/modern/timeoutManager.js.map +1 -1
  267. package/build/modern/types.cjs.map +1 -1
  268. package/build/modern/types.d.cts +1 -1
  269. package/build/modern/types.d.ts +1 -1
  270. package/build/modern/types.js.map +1 -1
  271. package/build/modern/utils.cjs +76 -0
  272. package/build/modern/utils.cjs.map +1 -1
  273. package/build/modern/utils.d.cts +1 -1
  274. package/build/modern/utils.d.ts +1 -1
  275. package/build/modern/utils.js +76 -0
  276. package/build/modern/utils.js.map +1 -1
  277. package/package.json +9 -9
  278. package/src/environmentManager.ts +15 -1
  279. package/src/focusManager.ts +57 -0
  280. package/src/hydration.ts +82 -16
  281. package/src/index.ts +3 -0
  282. package/src/infiniteQueryObserver.ts +67 -0
  283. package/src/mutation.ts +108 -0
  284. package/src/mutationCache.ts +91 -0
  285. package/src/mutationObserver.ts +71 -0
  286. package/src/notifyManager.ts +46 -1
  287. package/src/onlineManager.ts +47 -0
  288. package/src/queriesObserver.ts +72 -0
  289. package/src/query.ts +193 -0
  290. package/src/queryCache.ts +134 -0
  291. package/src/queryClient.ts +369 -0
  292. package/src/queryObserver.ts +117 -4
  293. package/src/retryer.ts +18 -0
  294. package/src/streamedQuery.ts +25 -1
  295. package/src/timeoutManager.ts +105 -0
  296. package/src/types.ts +147 -5
  297. package/src/utils.ts +107 -0
  298. package/build/legacy/hydration-Bjs0MSgg.d.ts.map +0 -1
  299. package/build/legacy/hydration-DWGr3cFC.d.cts.map +0 -1
  300. package/build/modern/hydration-Bjs0MSgg.d.ts.map +0 -1
  301. package/build/modern/hydration-DWGr3cFC.d.cts.map +0 -1
@@ -1,7 +1,14 @@
1
- import { Ct as QueryKey, St as QueryFunctionContext, xt as QueryFunction } from "./hydration-DWGr3cFC.cjs";
1
+ import { Ct as QueryKey, St as QueryFunctionContext, xt as QueryFunction } from "./hydration-DwR10Hi-.cjs";
2
2
  //#region src/streamedQuery.d.ts
3
3
  type BaseStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = {
4
+ /** The function that returns an `AsyncIterable` to stream data from. */
4
5
  streamFn: (context: QueryFunctionContext<TQueryKey>) => AsyncIterable<TQueryFnData> | Promise<AsyncIterable<TQueryFnData>>;
6
+ /**
7
+ * Defines how refetches are handled.
8
+ * - `'reset'` (default): erases all data and puts the query back into `pending` state.
9
+ * - `'append'`: appends new data to the existing data.
10
+ * - `'replace'`: writes all data to the cache once the stream ends.
11
+ */
5
12
  refetchMode?: 'append' | 'reset' | 'replace';
6
13
  };
7
14
  type SimpleStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {
@@ -9,7 +16,15 @@ type SimpleStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = BaseS
9
16
  initialValue?: never;
10
17
  };
11
18
  type ReducibleStreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {
19
+ /**
20
+ * Reduces streamed chunks into the final data shape. Required whenever `TData` is not an
21
+ * array, since there is no default way to accumulate non-array chunks.
22
+ */
12
23
  reducer: (acc: TData, chunk: TQueryFnData) => TData;
24
+ /**
25
+ * The value used while the first chunk is being fetched, and returned if the stream yields no
26
+ * values. Required together with a custom `reducer`.
27
+ */
13
28
  initialValue: TData;
14
29
  };
15
30
  type StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = SimpleStreamedQueryParams<TQueryFnData, TQueryKey> | ReducibleStreamedQueryParams<TQueryFnData, TData, TQueryKey>;
@@ -18,7 +33,7 @@ type StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = Simp
18
33
  * Data will be an Array of all the chunks received.
19
34
  * The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.
20
35
  * The query will stay in fetchStatus 'fetching' until the stream ends.
21
- * @param queryFn - The function that returns an AsyncIterable to stream data from.
36
+ * @param streamFn - The function that returns an AsyncIterable to stream data from.
22
37
  * @param refetchMode - Defines how re-fetches are handled.
23
38
  * Defaults to `'reset'`, erases all data and puts the query back into `pending` state.
24
39
  * Set to `'append'` to append new data to the existing data.
@@ -26,6 +41,15 @@ type StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = Simp
26
41
  * @param reducer - A function to reduce the streamed chunks into the final data.
27
42
  * Defaults to a function that appends chunks to the end of the array.
28
43
  * @param initialValue - Initial value to be used while the first chunk is being fetched, and returned if the stream yields no values.
44
+ * @example
45
+ * ```ts
46
+ * await queryClient.query({
47
+ * queryKey: ['data'],
48
+ * queryFn: streamedQuery({
49
+ * streamFn: fetchDataInChunks,
50
+ * }),
51
+ * })
52
+ * ```
29
53
  */
30
54
  declare function streamedQuery<TQueryFnData = unknown, TData = Array<TQueryFnData>, TQueryKey extends QueryKey = QueryKey>({ streamFn, refetchMode, reducer, initialValue }: StreamedQueryParams<TQueryFnData, TData, TQueryKey>): QueryFunction<TData, TQueryKey>;
31
55
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"streamedQuery.d.cts","names":[],"sources":["../../src/streamedQuery.ts"],"mappings":";;KAQK,wBAAwB,cAAc,kBAAkB;EAC3D,WACE,SAAS,qBAAqB,eAC3B,cAAc,gBAAgB,QAAQ,cAAc;EACzD;;KAGG,0BACH,cACA,kBAAkB,YAChB,wBAAwB,cAAc;EACxC;EACA;;KAGG,6BACH,cACA,OACA,kBAAkB,YAChB,wBAAwB,cAAc;EACxC,UAAU,KAAK,OAAO,OAAO,iBAAiB;EAC9C,cAAc;;KAGX,oBAAoB,cAAc,OAAO,kBAAkB,YAC5D,0BAA0B,cAAc,aACxC,6BAA6B,cAAc,OAAO;;;;;;;;;;;;;;;iBAgBtC,cACd,wBACA,QAAQ,MAAM,eACd,kBAAkB,WAAW,YAE7B,UACA,aACA,SAEA,gBACC,oBAAoB,cAAc,OAAO,aAAa,cACvD,OACA"}
1
+ {"version":3,"file":"streamedQuery.d.cts","names":[],"sources":["../../src/streamedQuery.ts"],"mappings":";;KAQK,wBAAwB,cAAc,kBAAkB;;EAE3D,WACE,SAAS,qBAAqB,eAC3B,cAAc,gBAAgB,QAAQ,cAAc;;;;;;;EAOzD;;KAGG,0BACH,cACA,kBAAkB,YAChB,wBAAwB,cAAc;EACxC;EACA;;KAGG,6BACH,cACA,OACA,kBAAkB,YAChB,wBAAwB,cAAc;;;;;EAKxC,UAAU,KAAK,OAAO,OAAO,iBAAiB;;;;;EAK9C,cAAc;;KAGX,oBAAoB,cAAc,OAAO,kBAAkB,YAC5D,0BAA0B,cAAc,aACxC,6BAA6B,cAAc,OAAO;;;;;;;;;;;;;;;;;;;;;;;;iBAyBtC,cACd,wBACA,QAAQ,MAAM,eACd,kBAAkB,WAAW,YAE7B,UACA,aACA,SAEA,gBACC,oBAAoB,cAAc,OAAO,aAAa,cACvD,OACA"}
@@ -1,7 +1,14 @@
1
- import { Ct as QueryKey, St as QueryFunctionContext, xt as QueryFunction } from "./hydration-Bjs0MSgg.js";
1
+ import { Ct as QueryKey, St as QueryFunctionContext, xt as QueryFunction } from "./hydration-Cq7QYAzB.js";
2
2
  //#region src/streamedQuery.d.ts
3
3
  type BaseStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = {
4
+ /** The function that returns an `AsyncIterable` to stream data from. */
4
5
  streamFn: (context: QueryFunctionContext<TQueryKey>) => AsyncIterable<TQueryFnData> | Promise<AsyncIterable<TQueryFnData>>;
6
+ /**
7
+ * Defines how refetches are handled.
8
+ * - `'reset'` (default): erases all data and puts the query back into `pending` state.
9
+ * - `'append'`: appends new data to the existing data.
10
+ * - `'replace'`: writes all data to the cache once the stream ends.
11
+ */
5
12
  refetchMode?: 'append' | 'reset' | 'replace';
6
13
  };
7
14
  type SimpleStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {
@@ -9,7 +16,15 @@ type SimpleStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = BaseS
9
16
  initialValue?: never;
10
17
  };
11
18
  type ReducibleStreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {
19
+ /**
20
+ * Reduces streamed chunks into the final data shape. Required whenever `TData` is not an
21
+ * array, since there is no default way to accumulate non-array chunks.
22
+ */
12
23
  reducer: (acc: TData, chunk: TQueryFnData) => TData;
24
+ /**
25
+ * The value used while the first chunk is being fetched, and returned if the stream yields no
26
+ * values. Required together with a custom `reducer`.
27
+ */
13
28
  initialValue: TData;
14
29
  };
15
30
  type StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = SimpleStreamedQueryParams<TQueryFnData, TQueryKey> | ReducibleStreamedQueryParams<TQueryFnData, TData, TQueryKey>;
@@ -18,7 +33,7 @@ type StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = Simp
18
33
  * Data will be an Array of all the chunks received.
19
34
  * The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.
20
35
  * The query will stay in fetchStatus 'fetching' until the stream ends.
21
- * @param queryFn - The function that returns an AsyncIterable to stream data from.
36
+ * @param streamFn - The function that returns an AsyncIterable to stream data from.
22
37
  * @param refetchMode - Defines how re-fetches are handled.
23
38
  * Defaults to `'reset'`, erases all data and puts the query back into `pending` state.
24
39
  * Set to `'append'` to append new data to the existing data.
@@ -26,6 +41,15 @@ type StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> = Simp
26
41
  * @param reducer - A function to reduce the streamed chunks into the final data.
27
42
  * Defaults to a function that appends chunks to the end of the array.
28
43
  * @param initialValue - Initial value to be used while the first chunk is being fetched, and returned if the stream yields no values.
44
+ * @example
45
+ * ```ts
46
+ * await queryClient.query({
47
+ * queryKey: ['data'],
48
+ * queryFn: streamedQuery({
49
+ * streamFn: fetchDataInChunks,
50
+ * }),
51
+ * })
52
+ * ```
29
53
  */
30
54
  declare function streamedQuery<TQueryFnData = unknown, TData = Array<TQueryFnData>, TQueryKey extends QueryKey = QueryKey>({ streamFn, refetchMode, reducer, initialValue }: StreamedQueryParams<TQueryFnData, TData, TQueryKey>): QueryFunction<TData, TQueryKey>;
31
55
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"streamedQuery.d.ts","names":[],"sources":["../../src/streamedQuery.ts"],"mappings":";;KAQK,wBAAwB,cAAc,kBAAkB;EAC3D,WACE,SAAS,qBAAqB,eAC3B,cAAc,gBAAgB,QAAQ,cAAc;EACzD;;KAGG,0BACH,cACA,kBAAkB,YAChB,wBAAwB,cAAc;EACxC;EACA;;KAGG,6BACH,cACA,OACA,kBAAkB,YAChB,wBAAwB,cAAc;EACxC,UAAU,KAAK,OAAO,OAAO,iBAAiB;EAC9C,cAAc;;KAGX,oBAAoB,cAAc,OAAO,kBAAkB,YAC5D,0BAA0B,cAAc,aACxC,6BAA6B,cAAc,OAAO;;;;;;;;;;;;;;;iBAgBtC,cACd,wBACA,QAAQ,MAAM,eACd,kBAAkB,WAAW,YAE7B,UACA,aACA,SAEA,gBACC,oBAAoB,cAAc,OAAO,aAAa,cACvD,OACA"}
1
+ {"version":3,"file":"streamedQuery.d.ts","names":[],"sources":["../../src/streamedQuery.ts"],"mappings":";;KAQK,wBAAwB,cAAc,kBAAkB;;EAE3D,WACE,SAAS,qBAAqB,eAC3B,cAAc,gBAAgB,QAAQ,cAAc;;;;;;;EAOzD;;KAGG,0BACH,cACA,kBAAkB,YAChB,wBAAwB,cAAc;EACxC;EACA;;KAGG,6BACH,cACA,OACA,kBAAkB,YAChB,wBAAwB,cAAc;;;;;EAKxC,UAAU,KAAK,OAAO,OAAO,iBAAiB;;;;;EAK9C,cAAc;;KAGX,oBAAoB,cAAc,OAAO,kBAAkB,YAC5D,0BAA0B,cAAc,aACxC,6BAA6B,cAAc,OAAO;;;;;;;;;;;;;;;;;;;;;;;;iBAyBtC,cACd,wBACA,QAAQ,MAAM,eACd,kBAAkB,WAAW,YAE7B,UACA,aACA,SAEA,gBACC,oBAAoB,cAAc,OAAO,aAAa,cACvD,OACA"}
@@ -5,7 +5,7 @@ import { addConsumeAwareSignal, addToEnd } from "./utils.js";
5
5
  * Data will be an Array of all the chunks received.
6
6
  * The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.
7
7
  * The query will stay in fetchStatus 'fetching' until the stream ends.
8
- * @param queryFn - The function that returns an AsyncIterable to stream data from.
8
+ * @param streamFn - The function that returns an AsyncIterable to stream data from.
9
9
  * @param refetchMode - Defines how re-fetches are handled.
10
10
  * Defaults to `'reset'`, erases all data and puts the query back into `pending` state.
11
11
  * Set to `'append'` to append new data to the existing data.
@@ -13,6 +13,15 @@ import { addConsumeAwareSignal, addToEnd } from "./utils.js";
13
13
  * @param reducer - A function to reduce the streamed chunks into the final data.
14
14
  * Defaults to a function that appends chunks to the end of the array.
15
15
  * @param initialValue - Initial value to be used while the first chunk is being fetched, and returned if the stream yields no values.
16
+ * @example
17
+ * ```ts
18
+ * await queryClient.query({
19
+ * queryKey: ['data'],
20
+ * queryFn: streamedQuery({
21
+ * streamFn: fetchDataInChunks,
22
+ * }),
23
+ * })
24
+ * ```
16
25
  */
17
26
  function streamedQuery({ streamFn, refetchMode = "reset", reducer = (items, chunk) => addToEnd(items, chunk), initialValue = [] }) {
18
27
  return async (context) => {
@@ -1 +1 @@
1
- {"version":3,"file":"streamedQuery.js","names":[],"sources":["../../src/streamedQuery.ts"],"sourcesContent":["import { addConsumeAwareSignal, addToEnd } from './utils'\nimport type {\n OmitKeyof,\n QueryFunction,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\ntype BaseStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = {\n streamFn: (\n context: QueryFunctionContext<TQueryKey>,\n ) => AsyncIterable<TQueryFnData> | Promise<AsyncIterable<TQueryFnData>>\n refetchMode?: 'append' | 'reset' | 'replace'\n}\n\ntype SimpleStreamedQueryParams<\n TQueryFnData,\n TQueryKey extends QueryKey,\n> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {\n reducer?: never\n initialValue?: never\n}\n\ntype ReducibleStreamedQueryParams<\n TQueryFnData,\n TData,\n TQueryKey extends QueryKey,\n> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {\n reducer: (acc: TData, chunk: TQueryFnData) => TData\n initialValue: TData\n}\n\ntype StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> =\n | SimpleStreamedQueryParams<TQueryFnData, TQueryKey>\n | ReducibleStreamedQueryParams<TQueryFnData, TData, TQueryKey>\n\n/**\n * This is a helper function to create a query function that streams data from an AsyncIterable.\n * Data will be an Array of all the chunks received.\n * The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.\n * The query will stay in fetchStatus 'fetching' until the stream ends.\n * @param queryFn - The function that returns an AsyncIterable to stream data from.\n * @param refetchMode - Defines how re-fetches are handled.\n * Defaults to `'reset'`, erases all data and puts the query back into `pending` state.\n * Set to `'append'` to append new data to the existing data.\n * Set to `'replace'` to write all data to the cache once the stream ends.\n * @param reducer - A function to reduce the streamed chunks into the final data.\n * Defaults to a function that appends chunks to the end of the array.\n * @param initialValue - Initial value to be used while the first chunk is being fetched, and returned if the stream yields no values.\n */\nexport function streamedQuery<\n TQueryFnData = unknown,\n TData = Array<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n>({\n streamFn,\n refetchMode = 'reset',\n reducer = (items, chunk) =>\n addToEnd(items as Array<TQueryFnData>, chunk) as TData,\n initialValue = [] as TData,\n}: StreamedQueryParams<TQueryFnData, TData, TQueryKey>): QueryFunction<\n TData,\n TQueryKey\n> {\n return async (context) => {\n const query = context.client\n .getQueryCache()\n .find({ queryKey: context.queryKey, exact: true })\n const isRefetch = !!query && query.isFetched()\n if (isRefetch && refetchMode === 'reset') {\n query.setState({\n ...query.resetState,\n fetchStatus: 'fetching',\n })\n }\n\n let result = initialValue\n\n let cancelled: boolean = false as boolean\n const streamFnContext = addConsumeAwareSignal<\n OmitKeyof<typeof context, 'signal'>\n >(\n {\n client: context.client,\n meta: context.meta,\n queryKey: context.queryKey,\n pageParam: context.pageParam,\n direction: context.direction,\n },\n () => context.signal,\n () => (cancelled = true),\n )\n\n const stream = await streamFn(streamFnContext)\n\n const isReplaceRefetch = isRefetch && refetchMode === 'replace'\n\n for await (const chunk of stream) {\n if (cancelled) {\n break\n }\n\n if (isReplaceRefetch) {\n // don't append to the cache directly when replace-refetching\n result = reducer(result, chunk)\n } else {\n context.client.setQueryData<TData>(context.queryKey, (prev) =>\n reducer(prev === undefined ? initialValue : prev, chunk),\n )\n }\n }\n\n // finalize result: replace-refetching needs to write to the cache\n if (isReplaceRefetch && !cancelled) {\n context.client.setQueryData<TData>(context.queryKey, result)\n }\n\n return context.client.getQueryData(context.queryKey) ?? initialValue\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkDA,SAAgB,cAId,EACA,UACA,cAAc,SACd,WAAW,OAAO,UAChB,SAAS,OAA8B,KAAK,GAC9C,eAAe,CAAC,KAIhB;CACA,OAAO,OAAO,YAAY;EACxB,MAAM,QAAQ,QAAQ,OACnB,cAAc,CAAC,CACf,KAAK;GAAE,UAAU,QAAQ;GAAU,OAAO;EAAK,CAAC;EACnD,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,UAAU;EAC7C,IAAI,aAAa,gBAAgB,SAC/B,MAAM,SAAS;GACb,GAAG,MAAM;GACT,aAAa;EACf,CAAC;EAGH,IAAI,SAAS;EAEb,IAAI,YAAqB;EAezB,MAAM,SAAS,MAAM,SAdG,sBAGtB;GACE,QAAQ,QAAQ;GAChB,MAAM,QAAQ;GACd,UAAU,QAAQ;GAClB,WAAW,QAAQ;GACnB,WAAW,QAAQ;EACrB,SACM,QAAQ,cACP,YAAY,IAGuB,CAAC;EAE7C,MAAM,mBAAmB,aAAa,gBAAgB;EAEtD,WAAW,MAAM,SAAS,QAAQ;GAChC,IAAI,WACF;GAGF,IAAI,kBAEF,SAAS,QAAQ,QAAQ,KAAK;QAE9B,QAAQ,OAAO,aAAoB,QAAQ,WAAW,SACpD,QAAQ,SAAS,KAAA,IAAY,eAAe,MAAM,KAAK,CACzD;EAEJ;EAGA,IAAI,oBAAoB,CAAC,WACvB,QAAQ,OAAO,aAAoB,QAAQ,UAAU,MAAM;EAG7D,OAAO,QAAQ,OAAO,aAAa,QAAQ,QAAQ,KAAK;CAC1D;AACF"}
1
+ {"version":3,"file":"streamedQuery.js","names":[],"sources":["../../src/streamedQuery.ts"],"sourcesContent":["import { addConsumeAwareSignal, addToEnd } from './utils'\nimport type {\n OmitKeyof,\n QueryFunction,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\ntype BaseStreamedQueryParams<TQueryFnData, TQueryKey extends QueryKey> = {\n /** The function that returns an `AsyncIterable` to stream data from. */\n streamFn: (\n context: QueryFunctionContext<TQueryKey>,\n ) => AsyncIterable<TQueryFnData> | Promise<AsyncIterable<TQueryFnData>>\n /**\n * Defines how refetches are handled.\n * - `'reset'` (default): erases all data and puts the query back into `pending` state.\n * - `'append'`: appends new data to the existing data.\n * - `'replace'`: writes all data to the cache once the stream ends.\n */\n refetchMode?: 'append' | 'reset' | 'replace'\n}\n\ntype SimpleStreamedQueryParams<\n TQueryFnData,\n TQueryKey extends QueryKey,\n> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {\n reducer?: never\n initialValue?: never\n}\n\ntype ReducibleStreamedQueryParams<\n TQueryFnData,\n TData,\n TQueryKey extends QueryKey,\n> = BaseStreamedQueryParams<TQueryFnData, TQueryKey> & {\n /**\n * Reduces streamed chunks into the final data shape. Required whenever `TData` is not an\n * array, since there is no default way to accumulate non-array chunks.\n */\n reducer: (acc: TData, chunk: TQueryFnData) => TData\n /**\n * The value used while the first chunk is being fetched, and returned if the stream yields no\n * values. Required together with a custom `reducer`.\n */\n initialValue: TData\n}\n\ntype StreamedQueryParams<TQueryFnData, TData, TQueryKey extends QueryKey> =\n | SimpleStreamedQueryParams<TQueryFnData, TQueryKey>\n | ReducibleStreamedQueryParams<TQueryFnData, TData, TQueryKey>\n\n/**\n * This is a helper function to create a query function that streams data from an AsyncIterable.\n * Data will be an Array of all the chunks received.\n * The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.\n * The query will stay in fetchStatus 'fetching' until the stream ends.\n * @param streamFn - The function that returns an AsyncIterable to stream data from.\n * @param refetchMode - Defines how re-fetches are handled.\n * Defaults to `'reset'`, erases all data and puts the query back into `pending` state.\n * Set to `'append'` to append new data to the existing data.\n * Set to `'replace'` to write all data to the cache once the stream ends.\n * @param reducer - A function to reduce the streamed chunks into the final data.\n * Defaults to a function that appends chunks to the end of the array.\n * @param initialValue - Initial value to be used while the first chunk is being fetched, and returned if the stream yields no values.\n * @example\n * ```ts\n * await queryClient.query({\n * queryKey: ['data'],\n * queryFn: streamedQuery({\n * streamFn: fetchDataInChunks,\n * }),\n * })\n * ```\n */\nexport function streamedQuery<\n TQueryFnData = unknown,\n TData = Array<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n>({\n streamFn,\n refetchMode = 'reset',\n reducer = (items, chunk) =>\n addToEnd(items as Array<TQueryFnData>, chunk) as TData,\n initialValue = [] as TData,\n}: StreamedQueryParams<TQueryFnData, TData, TQueryKey>): QueryFunction<\n TData,\n TQueryKey\n> {\n return async (context) => {\n const query = context.client\n .getQueryCache()\n .find({ queryKey: context.queryKey, exact: true })\n const isRefetch = !!query && query.isFetched()\n if (isRefetch && refetchMode === 'reset') {\n query.setState({\n ...query.resetState,\n fetchStatus: 'fetching',\n })\n }\n\n let result = initialValue\n\n let cancelled: boolean = false as boolean\n const streamFnContext = addConsumeAwareSignal<\n OmitKeyof<typeof context, 'signal'>\n >(\n {\n client: context.client,\n meta: context.meta,\n queryKey: context.queryKey,\n pageParam: context.pageParam,\n direction: context.direction,\n },\n () => context.signal,\n () => (cancelled = true),\n )\n\n const stream = await streamFn(streamFnContext)\n\n const isReplaceRefetch = isRefetch && refetchMode === 'replace'\n\n for await (const chunk of stream) {\n if (cancelled) {\n break\n }\n\n if (isReplaceRefetch) {\n // don't append to the cache directly when replace-refetching\n result = reducer(result, chunk)\n } else {\n context.client.setQueryData<TData>(context.queryKey, (prev) =>\n reducer(prev === undefined ? initialValue : prev, chunk),\n )\n }\n }\n\n // finalize result: replace-refetching needs to write to the cache\n if (isReplaceRefetch && !cancelled) {\n context.client.setQueryData<TData>(context.queryKey, result)\n }\n\n return context.client.getQueryData(context.queryKey) ?? initialValue\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,cAId,EACA,UACA,cAAc,SACd,WAAW,OAAO,UAChB,SAAS,OAA8B,KAAK,GAC9C,eAAe,CAAC,KAIhB;CACA,OAAO,OAAO,YAAY;EACxB,MAAM,QAAQ,QAAQ,OACnB,cAAc,CAAC,CACf,KAAK;GAAE,UAAU,QAAQ;GAAU,OAAO;EAAK,CAAC;EACnD,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,UAAU;EAC7C,IAAI,aAAa,gBAAgB,SAC/B,MAAM,SAAS;GACb,GAAG,MAAM;GACT,aAAa;EACf,CAAC;EAGH,IAAI,SAAS;EAEb,IAAI,YAAqB;EAezB,MAAM,SAAS,MAAM,SAdG,sBAGtB;GACE,QAAQ,QAAQ;GAChB,MAAM,QAAQ;GACd,UAAU,QAAQ;GAClB,WAAW,QAAQ;GACnB,WAAW,QAAQ;EACrB,SACM,QAAQ,cACP,YAAY,IAGuB,CAAC;EAE7C,MAAM,mBAAmB,aAAa,gBAAgB;EAEtD,WAAW,MAAM,SAAS,QAAQ;GAChC,IAAI,WACF;GAGF,IAAI,kBAEF,SAAS,QAAQ,QAAQ,KAAK;QAE9B,QAAQ,OAAO,aAAoB,QAAQ,WAAW,SACpD,QAAQ,SAAS,KAAA,IAAY,eAAe,MAAM,KAAK,CACzD;EAEJ;EAGA,IAAI,oBAAoB,CAAC,WACvB,QAAQ,OAAO,aAAoB,QAAQ,UAAU,MAAM;EAG7D,OAAO,QAAQ,OAAO,aAAa,QAAQ,QAAQ,KAAK;CAC1D;AACF"}
@@ -20,6 +20,31 @@ const defaultTimeoutProvider = {
20
20
  var TimeoutManager = class {
21
21
  #provider = defaultTimeoutProvider;
22
22
  #providerCalled = false;
23
+ /**
24
+ * `setTimeoutProvider` can be used to set a custom implementation of the
25
+ * `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` functions,
26
+ * called a `TimeoutProvider`.
27
+ *
28
+ * This may be useful if you notice event loop performance issues with
29
+ * thousands of queries. A custom TimeoutProvider could also support timer
30
+ * delays longer than the global `setTimeout` maximum delay value of about
31
+ * 24 days.
32
+ *
33
+ * It is important to call `setTimeoutProvider` before creating a
34
+ * QueryClient or queries, so that the same provider is used consistently
35
+ * for all timers in the application, since different TimeoutProviders
36
+ * cannot cancel each others' timers.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { timeoutManager, QueryClient } from '@tanstack/query-core'
41
+ * import { CustomTimeoutProvider } from './CustomTimeoutProvider'
42
+ *
43
+ * timeoutManager.setTimeoutProvider(new CustomTimeoutProvider())
44
+ *
45
+ * export const queryClient = new QueryClient()
46
+ * ```
47
+ */
23
48
  setTimeoutProvider(provider) {
24
49
  if (process.env.NODE_ENV !== "production") {
25
50
  if (this.#providerCalled && provider !== this.#provider) console.error(`[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`, {
@@ -30,21 +55,95 @@ var TimeoutManager = class {
30
55
  this.#provider = provider;
31
56
  if (process.env.NODE_ENV !== "production") this.#providerCalled = false;
32
57
  }
58
+ /**
59
+ * `setTimeout` schedules a callback to run after approximately `delay`
60
+ * milliseconds, like the global `setTimeout` function. The callback can be
61
+ * canceled with `clearTimeout`.
62
+ *
63
+ * It returns a timer ID, which may be a number or an object that can be
64
+ * coerced to a number via `Symbol.toPrimitive`.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * import { timeoutManager } from '@tanstack/query-core'
69
+ *
70
+ * const timeoutId = timeoutManager.setTimeout(
71
+ * () => console.log('ran at:', new Date()),
72
+ * 1000,
73
+ * )
74
+ *
75
+ * const timeoutIdNumber: number = Number(timeoutId)
76
+ * ```
77
+ */
33
78
  setTimeout(callback, delay) {
34
79
  if (process.env.NODE_ENV !== "production") this.#providerCalled = true;
35
80
  return this.#provider.setTimeout(callback, delay);
36
81
  }
82
+ /**
83
+ * `clearTimeout` cancels a timeout callback scheduled with `setTimeout`,
84
+ * like the global `clearTimeout` function. It should be called with a
85
+ * timer ID returned by `setTimeout`.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * import { timeoutManager } from '@tanstack/query-core'
90
+ *
91
+ * const timeoutId = timeoutManager.setTimeout(
92
+ * () => console.log('ran at:', new Date()),
93
+ * 1000,
94
+ * )
95
+ *
96
+ * timeoutManager.clearTimeout(timeoutId)
97
+ * ```
98
+ */
37
99
  clearTimeout(timeoutId) {
38
100
  this.#provider.clearTimeout(timeoutId);
39
101
  }
102
+ /**
103
+ * `setInterval` schedules a callback to be called approximately every
104
+ * `delay` milliseconds, like the global `setInterval` function.
105
+ *
106
+ * Like `setTimeout`, it returns a timer ID, which may be a number or an
107
+ * object that can be coerced to a number via `Symbol.toPrimitive`.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * import { timeoutManager } from '@tanstack/query-core'
112
+ *
113
+ * const intervalId = timeoutManager.setInterval(
114
+ * () => console.log('ran at:', new Date()),
115
+ * 1000,
116
+ * )
117
+ * ```
118
+ */
40
119
  setInterval(callback, delay) {
41
120
  if (process.env.NODE_ENV !== "production") this.#providerCalled = true;
42
121
  return this.#provider.setInterval(callback, delay);
43
122
  }
123
+ /**
124
+ * `clearInterval` can be used to cancel an interval, like the global
125
+ * `clearInterval` function. It should be called with an interval ID
126
+ * returned by `setInterval`.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * import { timeoutManager } from '@tanstack/query-core'
131
+ *
132
+ * const intervalId = timeoutManager.setInterval(
133
+ * () => console.log('ran at:', new Date()),
134
+ * 1000,
135
+ * )
136
+ *
137
+ * timeoutManager.clearInterval(intervalId)
138
+ * ```
139
+ */
44
140
  clearInterval(intervalId) {
45
141
  this.#provider.clearInterval(intervalId);
46
142
  }
47
143
  };
144
+ /**
145
+ * Singleton instance of {@link TimeoutManager}, used throughout TanStack Query to schedule and cancel timers.
146
+ */
48
147
  const timeoutManager = new TimeoutManager();
49
148
  /**
50
149
  * In many cases code wants to delay to the next event loop tick; this is not
@@ -1 +1 @@
1
- {"version":3,"file":"timeoutManager.cjs","names":["#providerCalled","#provider"],"sources":["../../src/timeoutManager.ts"],"sourcesContent":["/**\n * {@link TimeoutManager} does not support passing arguments to the callback.\n *\n * `(_: void)` is the argument type inferred by TypeScript's default typings for\n * `setTimeout(cb, number)`.\n * If we don't accept a single void argument, then\n * `new Promise(resolve => timeoutManager.setTimeout(resolve, N))` is a type error.\n */\nexport type TimeoutCallback = (_: void) => void\n\n/**\n * Wrapping `setTimeout` is awkward from a typing perspective because platform\n * typings may extend the return type of `setTimeout`. For example, NodeJS\n * typings add `NodeJS.Timeout`; but a non-default `timeoutManager` may not be\n * able to return such a type.\n */\nexport type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }\n\n/**\n * Backend for timer functions.\n */\nexport type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> =\n {\n readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearTimeout: (timeoutId: TTimerId | undefined) => void\n\n readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearInterval: (intervalId: TTimerId | undefined) => void\n }\n\ntype SystemTimerId = ReturnType<typeof setTimeout>\n\nexport const defaultTimeoutProvider: TimeoutProvider = {\n // We need the wrapper function syntax below instead of direct references to\n // global setTimeout etc.\n //\n // BAD: `setTimeout: setTimeout`\n // GOOD: `setTimeout: (cb, delay) => setTimeout(cb, delay)`\n //\n // If we use direct references here, then anything that wants to spy on or\n // replace the global setTimeout (like tests) won't work since we'll already\n // have a hard reference to the original implementation at the time when this\n // file was imported.\n setTimeout: (callback, delay) => setTimeout(callback, delay),\n clearTimeout: (timeoutId) =>\n clearTimeout(timeoutId as SystemTimerId | undefined),\n\n setInterval: (callback, delay) => setInterval(callback, delay),\n clearInterval: (intervalId) =>\n clearInterval(intervalId as SystemTimerId | undefined),\n}\n\n/**\n * Allows customization of how timeouts are created.\n *\n * @tanstack/query-core makes liberal use of timeouts to implement `staleTime`\n * and `gcTime`. The default TimeoutManager provider uses the platform's global\n * `setTimeout` implementation, which is known to have scalability issues with\n * thousands of timeouts on the event loop.\n *\n * If you hit this limitation, consider providing a custom TimeoutProvider that\n * coalesces timeouts.\n */\nexport class TimeoutManager implements Omit<TimeoutProvider, 'name'> {\n // We cannot have TimeoutManager<T> as we must instantiate it with a concrete\n // type at app boot; and if we leave that type, then any new timer provider\n // would need to support the default provider's concrete timer ID, which is\n // infeasible across environments.\n //\n // We settle for type safety for the TimeoutProvider type, and accept that\n // this class is unsafe internally to allow for extension.\n #provider: TimeoutProvider<any> = defaultTimeoutProvider\n #providerCalled = false\n\n setTimeoutProvider<TTimerId extends ManagedTimerId>(\n provider: TimeoutProvider<TTimerId>,\n ): void {\n if (process.env.NODE_ENV !== 'production') {\n if (this.#providerCalled && provider !== this.#provider) {\n // After changing providers, `clearTimeout` will not work as expected for\n // timeouts from the previous provider.\n //\n // Since they may allocate the same timeout ID, clearTimeout may cancel an\n // arbitrary different timeout, or unexpected no-op.\n //\n // We could protect against this by mixing the timeout ID bits\n // deterministically with some per-provider bits.\n //\n // We could internally queue `setTimeout` calls to `TimeoutManager` until\n // some API call to set the initial provider.\n console.error(\n `[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`,\n { previous: this.#provider, provider },\n )\n }\n }\n\n this.#provider = provider\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = false\n }\n }\n\n setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setTimeout(callback, delay)\n }\n\n clearTimeout(timeoutId: ManagedTimerId | undefined): void {\n this.#provider.clearTimeout(timeoutId)\n }\n\n setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setInterval(callback, delay)\n }\n\n clearInterval(intervalId: ManagedTimerId | undefined): void {\n this.#provider.clearInterval(intervalId)\n }\n}\n\nexport const timeoutManager = new TimeoutManager()\n\n/**\n * In many cases code wants to delay to the next event loop tick; this is not\n * mediated by {@link timeoutManager}.\n *\n * This function is provided to make auditing the `tanstack/query-core` for\n * incorrect use of system `setTimeout` easier.\n */\nexport function systemSetTimeoutZero(callback: TimeoutCallback): void {\n setTimeout(callback, 0)\n}\n"],"mappings":";;AAgCA,MAAa,yBAA0C;CAWrD,aAAa,UAAU,UAAU,WAAW,UAAU,KAAK;CAC3D,eAAe,cACb,aAAa,SAAsC;CAErD,cAAc,UAAU,UAAU,YAAY,UAAU,KAAK;CAC7D,gBAAgB,eACd,cAAc,UAAuC;AACzD;;;;;;;;;;;;AAaA,IAAa,iBAAb,MAAqE;CAQnE,YAAkC;CAClC,kBAAkB;CAElB,mBACE,UACM;EACN,IAAI,QAAQ,IAAI,aAAa,cACvB;OAAA,KAAKA,mBAAmB,aAAa,KAAKC,WAY5C,QAAQ,MACN,8GACA;IAAE,UAAU,KAAKA;IAAW;GAAS,CACvC;EAAA;EAIJ,KAAKA,YAAY;EACjB,IAAI,QAAQ,IAAI,aAAa,cAC3B,KAAKD,kBAAkB;CAE3B;CAEA,WAAW,UAA2B,OAA+B;EACnE,IAAI,QAAQ,IAAI,aAAa,cAC3B,KAAKA,kBAAkB;EAEzB,OAAO,KAAKC,UAAU,WAAW,UAAU,KAAK;CAClD;CAEA,aAAa,WAA6C;EACxD,KAAKA,UAAU,aAAa,SAAS;CACvC;CAEA,YAAY,UAA2B,OAA+B;EACpE,IAAI,QAAQ,IAAI,aAAa,cAC3B,KAAKD,kBAAkB;EAEzB,OAAO,KAAKC,UAAU,YAAY,UAAU,KAAK;CACnD;CAEA,cAAc,YAA8C;EAC1D,KAAKA,UAAU,cAAc,UAAU;CACzC;AACF;AAEA,MAAa,iBAAiB,IAAI,eAAe;;;;;;;;AASjD,SAAgB,qBAAqB,UAAiC;CACpE,WAAW,UAAU,CAAC;AACxB"}
1
+ {"version":3,"file":"timeoutManager.cjs","names":["#providerCalled","#provider"],"sources":["../../src/timeoutManager.ts"],"sourcesContent":["/**\n * {@link TimeoutManager} does not support passing arguments to the callback.\n *\n * `(_: void)` is the argument type inferred by TypeScript's default typings for\n * `setTimeout(cb, number)`.\n * If we don't accept a single void argument, then\n * `new Promise(resolve => timeoutManager.setTimeout(resolve, N))` is a type error.\n */\nexport type TimeoutCallback = (_: void) => void\n\n/**\n * Wrapping `setTimeout` is awkward from a typing perspective because platform\n * typings may extend the return type of `setTimeout`. For example, NodeJS\n * typings add `NodeJS.Timeout`; but a non-default `timeoutManager` may not be\n * able to return such a type.\n */\nexport type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }\n\n/**\n * Backend for timer functions.\n *\n * Timers are performance-sensitive: short-lived timers (delays under a few seconds) tend to be\n * latency-sensitive, while long-lived ones may benefit more from coalescing — batching timers\n * with similar deadlines together — which the default provider (backed by the platform's global\n * `setTimeout`/`setInterval`) does not do. A custom provider can implement coalescing, and can\n * also support delays longer than the ~24-day maximum of the global `setTimeout`.\n */\nexport type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> =\n {\n readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearTimeout: (timeoutId: TTimerId | undefined) => void\n\n readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearInterval: (intervalId: TTimerId | undefined) => void\n }\n\ntype SystemTimerId = ReturnType<typeof setTimeout>\n\nexport const defaultTimeoutProvider: TimeoutProvider = {\n // We need the wrapper function syntax below instead of direct references to\n // global setTimeout etc.\n //\n // BAD: `setTimeout: setTimeout`\n // GOOD: `setTimeout: (cb, delay) => setTimeout(cb, delay)`\n //\n // If we use direct references here, then anything that wants to spy on or\n // replace the global setTimeout (like tests) won't work since we'll already\n // have a hard reference to the original implementation at the time when this\n // file was imported.\n setTimeout: (callback, delay) => setTimeout(callback, delay),\n clearTimeout: (timeoutId) =>\n clearTimeout(timeoutId as SystemTimerId | undefined),\n\n setInterval: (callback, delay) => setInterval(callback, delay),\n clearInterval: (intervalId) =>\n clearInterval(intervalId as SystemTimerId | undefined),\n}\n\n/**\n * Allows customization of how timeouts are created.\n *\n * @tanstack/query-core makes liberal use of timeouts to implement `staleTime`\n * and `gcTime`. The default TimeoutManager provider uses the platform's global\n * `setTimeout` implementation, which is known to have scalability issues with\n * thousands of timeouts on the event loop.\n *\n * If you hit this limitation, consider providing a custom TimeoutProvider that\n * coalesces timeouts.\n */\nexport class TimeoutManager implements Omit<TimeoutProvider, 'name'> {\n // We cannot have TimeoutManager<T> as we must instantiate it with a concrete\n // type at app boot; and if we leave that type, then any new timer provider\n // would need to support the default provider's concrete timer ID, which is\n // infeasible across environments.\n //\n // We settle for type safety for the TimeoutProvider type, and accept that\n // this class is unsafe internally to allow for extension.\n #provider: TimeoutProvider<any> = defaultTimeoutProvider\n #providerCalled = false\n\n /**\n * `setTimeoutProvider` can be used to set a custom implementation of the\n * `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` functions,\n * called a `TimeoutProvider`.\n *\n * This may be useful if you notice event loop performance issues with\n * thousands of queries. A custom TimeoutProvider could also support timer\n * delays longer than the global `setTimeout` maximum delay value of about\n * 24 days.\n *\n * It is important to call `setTimeoutProvider` before creating a\n * QueryClient or queries, so that the same provider is used consistently\n * for all timers in the application, since different TimeoutProviders\n * cannot cancel each others' timers.\n *\n * @example\n * ```ts\n * import { timeoutManager, QueryClient } from '@tanstack/query-core'\n * import { CustomTimeoutProvider } from './CustomTimeoutProvider'\n *\n * timeoutManager.setTimeoutProvider(new CustomTimeoutProvider())\n *\n * export const queryClient = new QueryClient()\n * ```\n */\n setTimeoutProvider<TTimerId extends ManagedTimerId>(\n provider: TimeoutProvider<TTimerId>,\n ): void {\n if (process.env.NODE_ENV !== 'production') {\n if (this.#providerCalled && provider !== this.#provider) {\n // After changing providers, `clearTimeout` will not work as expected for\n // timeouts from the previous provider.\n //\n // Since they may allocate the same timeout ID, clearTimeout may cancel an\n // arbitrary different timeout, or unexpected no-op.\n //\n // We could protect against this by mixing the timeout ID bits\n // deterministically with some per-provider bits.\n //\n // We could internally queue `setTimeout` calls to `TimeoutManager` until\n // some API call to set the initial provider.\n console.error(\n `[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`,\n { previous: this.#provider, provider },\n )\n }\n }\n\n this.#provider = provider\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = false\n }\n }\n\n /**\n * `setTimeout` schedules a callback to run after approximately `delay`\n * milliseconds, like the global `setTimeout` function. The callback can be\n * canceled with `clearTimeout`.\n *\n * It returns a timer ID, which may be a number or an object that can be\n * coerced to a number via `Symbol.toPrimitive`.\n *\n * @example\n * ```ts\n * import { timeoutManager } from '@tanstack/query-core'\n *\n * const timeoutId = timeoutManager.setTimeout(\n * () => console.log('ran at:', new Date()),\n * 1000,\n * )\n *\n * const timeoutIdNumber: number = Number(timeoutId)\n * ```\n */\n setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setTimeout(callback, delay)\n }\n\n /**\n * `clearTimeout` cancels a timeout callback scheduled with `setTimeout`,\n * like the global `clearTimeout` function. It should be called with a\n * timer ID returned by `setTimeout`.\n *\n * @example\n * ```ts\n * import { timeoutManager } from '@tanstack/query-core'\n *\n * const timeoutId = timeoutManager.setTimeout(\n * () => console.log('ran at:', new Date()),\n * 1000,\n * )\n *\n * timeoutManager.clearTimeout(timeoutId)\n * ```\n */\n clearTimeout(timeoutId: ManagedTimerId | undefined): void {\n this.#provider.clearTimeout(timeoutId)\n }\n\n /**\n * `setInterval` schedules a callback to be called approximately every\n * `delay` milliseconds, like the global `setInterval` function.\n *\n * Like `setTimeout`, it returns a timer ID, which may be a number or an\n * object that can be coerced to a number via `Symbol.toPrimitive`.\n *\n * @example\n * ```ts\n * import { timeoutManager } from '@tanstack/query-core'\n *\n * const intervalId = timeoutManager.setInterval(\n * () => console.log('ran at:', new Date()),\n * 1000,\n * )\n * ```\n */\n setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setInterval(callback, delay)\n }\n\n /**\n * `clearInterval` can be used to cancel an interval, like the global\n * `clearInterval` function. It should be called with an interval ID\n * returned by `setInterval`.\n *\n * @example\n * ```ts\n * import { timeoutManager } from '@tanstack/query-core'\n *\n * const intervalId = timeoutManager.setInterval(\n * () => console.log('ran at:', new Date()),\n * 1000,\n * )\n *\n * timeoutManager.clearInterval(intervalId)\n * ```\n */\n clearInterval(intervalId: ManagedTimerId | undefined): void {\n this.#provider.clearInterval(intervalId)\n }\n}\n\n/**\n * Singleton instance of {@link TimeoutManager}, used throughout TanStack Query to schedule and cancel timers.\n */\nexport const timeoutManager = new TimeoutManager()\n\n/**\n * In many cases code wants to delay to the next event loop tick; this is not\n * mediated by {@link timeoutManager}.\n *\n * This function is provided to make auditing the `tanstack/query-core` for\n * incorrect use of system `setTimeout` easier.\n */\nexport function systemSetTimeoutZero(callback: TimeoutCallback): void {\n setTimeout(callback, 0)\n}\n"],"mappings":";;AAsCA,MAAa,yBAA0C;CAWrD,aAAa,UAAU,UAAU,WAAW,UAAU,KAAK;CAC3D,eAAe,cACb,aAAa,SAAsC;CAErD,cAAc,UAAU,UAAU,YAAY,UAAU,KAAK;CAC7D,gBAAgB,eACd,cAAc,UAAuC;AACzD;;;;;;;;;;;;AAaA,IAAa,iBAAb,MAAqE;CAQnE,YAAkC;CAClC,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BlB,mBACE,UACM;EACN,IAAI,QAAQ,IAAI,aAAa,cACvB;OAAA,KAAKA,mBAAmB,aAAa,KAAKC,WAY5C,QAAQ,MACN,8GACA;IAAE,UAAU,KAAKA;IAAW;GAAS,CACvC;EAAA;EAIJ,KAAKA,YAAY;EACjB,IAAI,QAAQ,IAAI,aAAa,cAC3B,KAAKD,kBAAkB;CAE3B;;;;;;;;;;;;;;;;;;;;;CAsBA,WAAW,UAA2B,OAA+B;EACnE,IAAI,QAAQ,IAAI,aAAa,cAC3B,KAAKA,kBAAkB;EAEzB,OAAO,KAAKC,UAAU,WAAW,UAAU,KAAK;CAClD;;;;;;;;;;;;;;;;;;CAmBA,aAAa,WAA6C;EACxD,KAAKA,UAAU,aAAa,SAAS;CACvC;;;;;;;;;;;;;;;;;;CAmBA,YAAY,UAA2B,OAA+B;EACpE,IAAI,QAAQ,IAAI,aAAa,cAC3B,KAAKD,kBAAkB;EAEzB,OAAO,KAAKC,UAAU,YAAY,UAAU,KAAK;CACnD;;;;;;;;;;;;;;;;;;CAmBA,cAAc,YAA8C;EAC1D,KAAKA,UAAU,cAAc,UAAU;CACzC;AACF;;;;AAKA,MAAa,iBAAiB,IAAI,eAAe;;;;;;;;AASjD,SAAgB,qBAAqB,UAAiC;CACpE,WAAW,UAAU,CAAC;AACxB"}
@@ -19,6 +19,12 @@ type ManagedTimerId = number | {
19
19
  };
20
20
  /**
21
21
  * Backend for timer functions.
22
+ *
23
+ * Timers are performance-sensitive: short-lived timers (delays under a few seconds) tend to be
24
+ * latency-sensitive, while long-lived ones may benefit more from coalescing — batching timers
25
+ * with similar deadlines together — which the default provider (backed by the platform's global
26
+ * `setTimeout`/`setInterval`) does not do. A custom provider can implement coalescing, and can
27
+ * also support delays longer than the ~24-day maximum of the global `setTimeout`.
22
28
  */
23
29
  type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> = {
24
30
  readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId;
@@ -40,12 +46,111 @@ declare const defaultTimeoutProvider: TimeoutProvider;
40
46
  */
41
47
  declare class TimeoutManager implements Omit<TimeoutProvider, 'name'> {
42
48
  #private;
49
+ /**
50
+ * `setTimeoutProvider` can be used to set a custom implementation of the
51
+ * `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` functions,
52
+ * called a `TimeoutProvider`.
53
+ *
54
+ * This may be useful if you notice event loop performance issues with
55
+ * thousands of queries. A custom TimeoutProvider could also support timer
56
+ * delays longer than the global `setTimeout` maximum delay value of about
57
+ * 24 days.
58
+ *
59
+ * It is important to call `setTimeoutProvider` before creating a
60
+ * QueryClient or queries, so that the same provider is used consistently
61
+ * for all timers in the application, since different TimeoutProviders
62
+ * cannot cancel each others' timers.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { timeoutManager, QueryClient } from '@tanstack/query-core'
67
+ * import { CustomTimeoutProvider } from './CustomTimeoutProvider'
68
+ *
69
+ * timeoutManager.setTimeoutProvider(new CustomTimeoutProvider())
70
+ *
71
+ * export const queryClient = new QueryClient()
72
+ * ```
73
+ */
43
74
  setTimeoutProvider<TTimerId extends ManagedTimerId>(provider: TimeoutProvider<TTimerId>): void;
75
+ /**
76
+ * `setTimeout` schedules a callback to run after approximately `delay`
77
+ * milliseconds, like the global `setTimeout` function. The callback can be
78
+ * canceled with `clearTimeout`.
79
+ *
80
+ * It returns a timer ID, which may be a number or an object that can be
81
+ * coerced to a number via `Symbol.toPrimitive`.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { timeoutManager } from '@tanstack/query-core'
86
+ *
87
+ * const timeoutId = timeoutManager.setTimeout(
88
+ * () => console.log('ran at:', new Date()),
89
+ * 1000,
90
+ * )
91
+ *
92
+ * const timeoutIdNumber: number = Number(timeoutId)
93
+ * ```
94
+ */
44
95
  setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId;
96
+ /**
97
+ * `clearTimeout` cancels a timeout callback scheduled with `setTimeout`,
98
+ * like the global `clearTimeout` function. It should be called with a
99
+ * timer ID returned by `setTimeout`.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * import { timeoutManager } from '@tanstack/query-core'
104
+ *
105
+ * const timeoutId = timeoutManager.setTimeout(
106
+ * () => console.log('ran at:', new Date()),
107
+ * 1000,
108
+ * )
109
+ *
110
+ * timeoutManager.clearTimeout(timeoutId)
111
+ * ```
112
+ */
45
113
  clearTimeout(timeoutId: ManagedTimerId | undefined): void;
114
+ /**
115
+ * `setInterval` schedules a callback to be called approximately every
116
+ * `delay` milliseconds, like the global `setInterval` function.
117
+ *
118
+ * Like `setTimeout`, it returns a timer ID, which may be a number or an
119
+ * object that can be coerced to a number via `Symbol.toPrimitive`.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * import { timeoutManager } from '@tanstack/query-core'
124
+ *
125
+ * const intervalId = timeoutManager.setInterval(
126
+ * () => console.log('ran at:', new Date()),
127
+ * 1000,
128
+ * )
129
+ * ```
130
+ */
46
131
  setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId;
132
+ /**
133
+ * `clearInterval` can be used to cancel an interval, like the global
134
+ * `clearInterval` function. It should be called with an interval ID
135
+ * returned by `setInterval`.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import { timeoutManager } from '@tanstack/query-core'
140
+ *
141
+ * const intervalId = timeoutManager.setInterval(
142
+ * () => console.log('ran at:', new Date()),
143
+ * 1000,
144
+ * )
145
+ *
146
+ * timeoutManager.clearInterval(intervalId)
147
+ * ```
148
+ */
47
149
  clearInterval(intervalId: ManagedTimerId | undefined): void;
48
150
  }
151
+ /**
152
+ * Singleton instance of {@link TimeoutManager}, used throughout TanStack Query to schedule and cancel timers.
153
+ */
49
154
  declare const timeoutManager: TimeoutManager;
50
155
  /**
51
156
  * In many cases code wants to delay to the next event loop tick; this is not
@@ -1 +1 @@
1
- {"version":3,"file":"timeoutManager.d.cts","names":[],"sources":["../../src/timeoutManager.ts"],"mappings":";;;;;;;;;KAQY,mBAAmB;;;;;;;KAQnB;GAA6B,OAAO;;;;;KAKpC,gBAAgB,iBAAiB,iBAAiB;WAEjD,aAAa,UAAU,iBAAiB,kBAAkB;WAC1D,eAAe,WAAW;WAE1B,cAAc,UAAU,iBAAiB,kBAAkB;WAC3D,gBAAgB,YAAY;;cAK5B,wBAAwB;;;;;;;;;;;;cA+BxB,0BAA0B,KAAK;;EAW1C,mBAAmB,iBAAiB,gBAClC,UAAU,gBAAgB;EA4B5B,WAAW,UAAU,iBAAiB,gBAAgB;EAOtD,aAAa,WAAW;EAIxB,YAAY,UAAU,iBAAiB,gBAAgB;EAOvD,cAAc,YAAY;;cAKf,gBAAc;;;;;;;;iBASX,qBAAqB,UAAU"}
1
+ {"version":3,"file":"timeoutManager.d.cts","names":[],"sources":["../../src/timeoutManager.ts"],"mappings":";;;;;;;;;KAQY,mBAAmB;;;;;;;KAQnB;GAA6B,OAAO;;;;;;;;;;;KAWpC,gBAAgB,iBAAiB,iBAAiB;WAEjD,aAAa,UAAU,iBAAiB,kBAAkB;WAC1D,eAAe,WAAW;WAE1B,cAAc,UAAU,iBAAiB,kBAAkB;WAC3D,gBAAgB,YAAY;;cAK5B,wBAAwB;;;;;;;;;;;;cA+BxB,0BAA0B,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC1C,mBAAmB,iBAAiB,gBAClC,UAAU,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAgD5B,WAAW,UAAU,iBAAiB,gBAAgB;;;;;;;;;;;;;;;;;;EAwBtD,aAAa,WAAW;;;;;;;;;;;;;;;;;;EAqBxB,YAAY,UAAU,iBAAiB,gBAAgB;;;;;;;;;;;;;;;;;;EAwBvD,cAAc,YAAY;;;;;cAQf,gBAAc;;;;;;;;iBASX,qBAAqB,UAAU"}
@@ -19,6 +19,12 @@ type ManagedTimerId = number | {
19
19
  };
20
20
  /**
21
21
  * Backend for timer functions.
22
+ *
23
+ * Timers are performance-sensitive: short-lived timers (delays under a few seconds) tend to be
24
+ * latency-sensitive, while long-lived ones may benefit more from coalescing — batching timers
25
+ * with similar deadlines together — which the default provider (backed by the platform's global
26
+ * `setTimeout`/`setInterval`) does not do. A custom provider can implement coalescing, and can
27
+ * also support delays longer than the ~24-day maximum of the global `setTimeout`.
22
28
  */
23
29
  type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> = {
24
30
  readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId;
@@ -40,12 +46,111 @@ declare const defaultTimeoutProvider: TimeoutProvider;
40
46
  */
41
47
  declare class TimeoutManager implements Omit<TimeoutProvider, 'name'> {
42
48
  #private;
49
+ /**
50
+ * `setTimeoutProvider` can be used to set a custom implementation of the
51
+ * `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` functions,
52
+ * called a `TimeoutProvider`.
53
+ *
54
+ * This may be useful if you notice event loop performance issues with
55
+ * thousands of queries. A custom TimeoutProvider could also support timer
56
+ * delays longer than the global `setTimeout` maximum delay value of about
57
+ * 24 days.
58
+ *
59
+ * It is important to call `setTimeoutProvider` before creating a
60
+ * QueryClient or queries, so that the same provider is used consistently
61
+ * for all timers in the application, since different TimeoutProviders
62
+ * cannot cancel each others' timers.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { timeoutManager, QueryClient } from '@tanstack/query-core'
67
+ * import { CustomTimeoutProvider } from './CustomTimeoutProvider'
68
+ *
69
+ * timeoutManager.setTimeoutProvider(new CustomTimeoutProvider())
70
+ *
71
+ * export const queryClient = new QueryClient()
72
+ * ```
73
+ */
43
74
  setTimeoutProvider<TTimerId extends ManagedTimerId>(provider: TimeoutProvider<TTimerId>): void;
75
+ /**
76
+ * `setTimeout` schedules a callback to run after approximately `delay`
77
+ * milliseconds, like the global `setTimeout` function. The callback can be
78
+ * canceled with `clearTimeout`.
79
+ *
80
+ * It returns a timer ID, which may be a number or an object that can be
81
+ * coerced to a number via `Symbol.toPrimitive`.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { timeoutManager } from '@tanstack/query-core'
86
+ *
87
+ * const timeoutId = timeoutManager.setTimeout(
88
+ * () => console.log('ran at:', new Date()),
89
+ * 1000,
90
+ * )
91
+ *
92
+ * const timeoutIdNumber: number = Number(timeoutId)
93
+ * ```
94
+ */
44
95
  setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId;
96
+ /**
97
+ * `clearTimeout` cancels a timeout callback scheduled with `setTimeout`,
98
+ * like the global `clearTimeout` function. It should be called with a
99
+ * timer ID returned by `setTimeout`.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * import { timeoutManager } from '@tanstack/query-core'
104
+ *
105
+ * const timeoutId = timeoutManager.setTimeout(
106
+ * () => console.log('ran at:', new Date()),
107
+ * 1000,
108
+ * )
109
+ *
110
+ * timeoutManager.clearTimeout(timeoutId)
111
+ * ```
112
+ */
45
113
  clearTimeout(timeoutId: ManagedTimerId | undefined): void;
114
+ /**
115
+ * `setInterval` schedules a callback to be called approximately every
116
+ * `delay` milliseconds, like the global `setInterval` function.
117
+ *
118
+ * Like `setTimeout`, it returns a timer ID, which may be a number or an
119
+ * object that can be coerced to a number via `Symbol.toPrimitive`.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * import { timeoutManager } from '@tanstack/query-core'
124
+ *
125
+ * const intervalId = timeoutManager.setInterval(
126
+ * () => console.log('ran at:', new Date()),
127
+ * 1000,
128
+ * )
129
+ * ```
130
+ */
46
131
  setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId;
132
+ /**
133
+ * `clearInterval` can be used to cancel an interval, like the global
134
+ * `clearInterval` function. It should be called with an interval ID
135
+ * returned by `setInterval`.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import { timeoutManager } from '@tanstack/query-core'
140
+ *
141
+ * const intervalId = timeoutManager.setInterval(
142
+ * () => console.log('ran at:', new Date()),
143
+ * 1000,
144
+ * )
145
+ *
146
+ * timeoutManager.clearInterval(intervalId)
147
+ * ```
148
+ */
47
149
  clearInterval(intervalId: ManagedTimerId | undefined): void;
48
150
  }
151
+ /**
152
+ * Singleton instance of {@link TimeoutManager}, used throughout TanStack Query to schedule and cancel timers.
153
+ */
49
154
  declare const timeoutManager: TimeoutManager;
50
155
  /**
51
156
  * In many cases code wants to delay to the next event loop tick; this is not
@@ -1 +1 @@
1
- {"version":3,"file":"timeoutManager.d.ts","names":[],"sources":["../../src/timeoutManager.ts"],"mappings":";;;;;;;;;KAQY,mBAAmB;;;;;;;KAQnB;GAA6B,OAAO;;;;;KAKpC,gBAAgB,iBAAiB,iBAAiB;WAEjD,aAAa,UAAU,iBAAiB,kBAAkB;WAC1D,eAAe,WAAW;WAE1B,cAAc,UAAU,iBAAiB,kBAAkB;WAC3D,gBAAgB,YAAY;;cAK5B,wBAAwB;;;;;;;;;;;;cA+BxB,0BAA0B,KAAK;;EAW1C,mBAAmB,iBAAiB,gBAClC,UAAU,gBAAgB;EA4B5B,WAAW,UAAU,iBAAiB,gBAAgB;EAOtD,aAAa,WAAW;EAIxB,YAAY,UAAU,iBAAiB,gBAAgB;EAOvD,cAAc,YAAY;;cAKf,gBAAc;;;;;;;;iBASX,qBAAqB,UAAU"}
1
+ {"version":3,"file":"timeoutManager.d.ts","names":[],"sources":["../../src/timeoutManager.ts"],"mappings":";;;;;;;;;KAQY,mBAAmB;;;;;;;KAQnB;GAA6B,OAAO;;;;;;;;;;;KAWpC,gBAAgB,iBAAiB,iBAAiB;WAEjD,aAAa,UAAU,iBAAiB,kBAAkB;WAC1D,eAAe,WAAW;WAE1B,cAAc,UAAU,iBAAiB,kBAAkB;WAC3D,gBAAgB,YAAY;;cAK5B,wBAAwB;;;;;;;;;;;;cA+BxB,0BAA0B,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC1C,mBAAmB,iBAAiB,gBAClC,UAAU,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAgD5B,WAAW,UAAU,iBAAiB,gBAAgB;;;;;;;;;;;;;;;;;;EAwBtD,aAAa,WAAW;;;;;;;;;;;;;;;;;;EAqBxB,YAAY,UAAU,iBAAiB,gBAAgB;;;;;;;;;;;;;;;;;;EAwBvD,cAAc,YAAY;;;;;cAQf,gBAAc;;;;;;;;iBASX,qBAAqB,UAAU"}