@tanstack/query-core 5.0.0-alpha.7 → 5.0.0-alpha.81

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 (296) hide show
  1. package/build/lib/_virtual/{_rollupPluginBabelHelpers.js → _rollupPluginBabelHelpers.legacy.cjs} +1 -1
  2. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs.map +1 -0
  3. package/build/lib/_virtual/{_rollupPluginBabelHelpers.esm.js → _rollupPluginBabelHelpers.legacy.js} +1 -1
  4. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js.map +1 -0
  5. package/build/lib/{focusManager.mjs → focusManager.cjs} +12 -8
  6. package/build/lib/focusManager.cjs.map +1 -0
  7. package/build/lib/focusManager.d.ts +2 -1
  8. package/build/lib/focusManager.d.ts.map +1 -0
  9. package/build/lib/focusManager.js +22 -40
  10. package/build/lib/focusManager.js.map +1 -1
  11. package/build/lib/focusManager.legacy.cjs +91 -0
  12. package/build/lib/focusManager.legacy.cjs.map +1 -0
  13. package/build/lib/{focusManager.esm.js → focusManager.legacy.js} +7 -6
  14. package/build/lib/focusManager.legacy.js.map +1 -0
  15. package/build/lib/{hydration.mjs → hydration.cjs} +11 -20
  16. package/build/lib/hydration.cjs.map +1 -0
  17. package/build/lib/hydration.d.ts +3 -6
  18. package/build/lib/hydration.d.ts.map +1 -0
  19. package/build/lib/hydration.js +7 -28
  20. package/build/lib/hydration.js.map +1 -1
  21. package/build/lib/hydration.legacy.cjs +92 -0
  22. package/build/lib/hydration.legacy.cjs.map +1 -0
  23. package/build/lib/{hydration.esm.js → hydration.legacy.js} +6 -19
  24. package/build/lib/hydration.legacy.js.map +1 -0
  25. package/build/lib/index.cjs +40 -0
  26. package/build/lib/index.cjs.map +1 -0
  27. package/build/lib/index.d.ts +5 -2
  28. package/build/lib/index.d.ts.map +1 -0
  29. package/build/lib/index.js +13 -39
  30. package/build/lib/index.js.map +1 -1
  31. package/build/lib/index.legacy.cjs +40 -0
  32. package/build/lib/index.legacy.cjs.map +1 -0
  33. package/build/lib/index.legacy.js +14 -0
  34. package/build/lib/index.legacy.js.map +1 -0
  35. package/build/lib/{infiniteQueryBehavior.mjs → infiniteQueryBehavior.cjs} +15 -18
  36. package/build/lib/infiniteQueryBehavior.cjs.map +1 -0
  37. package/build/lib/infiniteQueryBehavior.d.ts +2 -1
  38. package/build/lib/infiniteQueryBehavior.d.ts.map +1 -0
  39. package/build/lib/infiniteQueryBehavior.js +14 -26
  40. package/build/lib/infiniteQueryBehavior.js.map +1 -1
  41. package/build/lib/infiniteQueryBehavior.legacy.cjs +125 -0
  42. package/build/lib/infiniteQueryBehavior.legacy.cjs.map +1 -0
  43. package/build/lib/{infiniteQueryBehavior.esm.js → infiniteQueryBehavior.legacy.js} +10 -16
  44. package/build/lib/infiniteQueryBehavior.legacy.js.map +1 -0
  45. package/build/lib/{infiniteQueryObserver.mjs → infiniteQueryObserver.cjs} +11 -9
  46. package/build/lib/{infiniteQueryObserver.mjs.map → infiniteQueryObserver.cjs.map} +1 -1
  47. package/build/lib/infiniteQueryObserver.d.ts +2 -1
  48. package/build/lib/infiniteQueryObserver.d.ts.map +1 -0
  49. package/build/lib/infiniteQueryObserver.js +10 -13
  50. package/build/lib/infiniteQueryObserver.js.map +1 -1
  51. package/build/lib/infiniteQueryObserver.legacy.cjs +78 -0
  52. package/build/lib/infiniteQueryObserver.legacy.cjs.map +1 -0
  53. package/build/lib/{infiniteQueryObserver.esm.js → infiniteQueryObserver.legacy.js} +3 -3
  54. package/build/lib/infiniteQueryObserver.legacy.js.map +1 -0
  55. package/build/lib/{mutation.mjs → mutation.cjs} +13 -10
  56. package/build/lib/mutation.cjs.map +1 -0
  57. package/build/lib/mutation.d.ts +2 -1
  58. package/build/lib/mutation.d.ts.map +1 -0
  59. package/build/lib/mutation.js +107 -135
  60. package/build/lib/mutation.js.map +1 -1
  61. package/build/lib/mutation.legacy.cjs +262 -0
  62. package/build/lib/mutation.legacy.cjs.map +1 -0
  63. package/build/lib/{mutation.esm.js → mutation.legacy.js} +6 -6
  64. package/build/lib/mutation.legacy.js.map +1 -0
  65. package/build/lib/{mutationCache.mjs → mutationCache.cjs} +21 -18
  66. package/build/lib/mutationCache.cjs.map +1 -0
  67. package/build/lib/mutationCache.d.ts +3 -2
  68. package/build/lib/mutationCache.d.ts.map +1 -0
  69. package/build/lib/mutationCache.js +33 -47
  70. package/build/lib/mutationCache.js.map +1 -1
  71. package/build/lib/mutationCache.legacy.cjs +98 -0
  72. package/build/lib/mutationCache.legacy.cjs.map +1 -0
  73. package/build/lib/{mutationCache.esm.js → mutationCache.legacy.js} +11 -10
  74. package/build/lib/mutationCache.legacy.js.map +1 -0
  75. package/build/lib/{mutationObserver.mjs → mutationObserver.cjs} +13 -11
  76. package/build/lib/mutationObserver.cjs.map +1 -0
  77. package/build/lib/mutationObserver.d.ts +2 -1
  78. package/build/lib/mutationObserver.d.ts.map +1 -0
  79. package/build/lib/mutationObserver.js +59 -91
  80. package/build/lib/mutationObserver.js.map +1 -1
  81. package/build/lib/mutationObserver.legacy.cjs +128 -0
  82. package/build/lib/mutationObserver.legacy.cjs.map +1 -0
  83. package/build/lib/{mutationObserver.esm.js → mutationObserver.legacy.js} +7 -7
  84. package/build/lib/mutationObserver.legacy.js.map +1 -0
  85. package/build/lib/{notifyManager.mjs → notifyManager.cjs} +8 -5
  86. package/build/lib/notifyManager.cjs.map +1 -0
  87. package/build/lib/notifyManager.d.ts +7 -5
  88. package/build/lib/notifyManager.d.ts.map +1 -0
  89. package/build/lib/notifyManager.js +4 -7
  90. package/build/lib/notifyManager.js.map +1 -1
  91. package/build/lib/notifyManager.legacy.cjs +92 -0
  92. package/build/lib/notifyManager.legacy.cjs.map +1 -0
  93. package/build/lib/{notifyManager.esm.js → notifyManager.legacy.js} +2 -2
  94. package/build/lib/notifyManager.legacy.js.map +1 -0
  95. package/build/lib/{onlineManager.mjs → onlineManager.cjs} +19 -12
  96. package/build/lib/onlineManager.cjs.map +1 -0
  97. package/build/lib/onlineManager.d.ts +2 -1
  98. package/build/lib/onlineManager.d.ts.map +1 -0
  99. package/build/lib/onlineManager.js +28 -42
  100. package/build/lib/onlineManager.js.map +1 -1
  101. package/build/lib/onlineManager.legacy.cjs +95 -0
  102. package/build/lib/onlineManager.legacy.cjs.map +1 -0
  103. package/build/lib/{onlineManager.esm.js → onlineManager.legacy.js} +14 -10
  104. package/build/lib/onlineManager.legacy.js.map +1 -0
  105. package/build/lib/{queriesObserver.mjs → queriesObserver.cjs} +51 -26
  106. package/build/lib/queriesObserver.cjs.map +1 -0
  107. package/build/lib/queriesObserver.d.ts +14 -6
  108. package/build/lib/queriesObserver.d.ts.map +1 -0
  109. package/build/lib/queriesObserver.js +99 -107
  110. package/build/lib/queriesObserver.js.map +1 -1
  111. package/build/lib/queriesObserver.legacy.cjs +207 -0
  112. package/build/lib/queriesObserver.legacy.cjs.map +1 -0
  113. package/build/lib/{queriesObserver.esm.js → queriesObserver.legacy.js} +62 -22
  114. package/build/lib/queriesObserver.legacy.js.map +1 -0
  115. package/build/lib/{query.mjs → query.cjs} +23 -21
  116. package/build/lib/query.cjs.map +1 -0
  117. package/build/lib/query.d.ts +3 -2
  118. package/build/lib/query.d.ts.map +1 -0
  119. package/build/lib/query.js +174 -225
  120. package/build/lib/query.js.map +1 -1
  121. package/build/lib/query.legacy.cjs +471 -0
  122. package/build/lib/query.legacy.cjs.map +1 -0
  123. package/build/lib/{query.esm.js → query.legacy.js} +11 -11
  124. package/build/lib/query.legacy.js.map +1 -0
  125. package/build/lib/{queryCache.mjs → queryCache.cjs} +28 -23
  126. package/build/lib/queryCache.cjs.map +1 -0
  127. package/build/lib/queryCache.d.ts +3 -3
  128. package/build/lib/queryCache.d.ts.map +1 -0
  129. package/build/lib/queryCache.js +31 -37
  130. package/build/lib/queryCache.js.map +1 -1
  131. package/build/lib/queryCache.legacy.cjs +111 -0
  132. package/build/lib/queryCache.legacy.cjs.map +1 -0
  133. package/build/lib/{queryCache.esm.js → queryCache.legacy.js} +13 -12
  134. package/build/lib/queryCache.legacy.js.map +1 -0
  135. package/build/lib/{queryClient.mjs → queryClient.cjs} +50 -42
  136. package/build/lib/queryClient.cjs.map +1 -0
  137. package/build/lib/queryClient.d.ts +2 -2
  138. package/build/lib/queryClient.d.ts.map +1 -0
  139. package/build/lib/queryClient.js +98 -134
  140. package/build/lib/queryClient.js.map +1 -1
  141. package/build/lib/queryClient.legacy.cjs +322 -0
  142. package/build/lib/queryClient.legacy.cjs.map +1 -0
  143. package/build/lib/{queryClient.esm.js → queryClient.legacy.js} +29 -26
  144. package/build/lib/queryClient.legacy.js.map +1 -0
  145. package/build/lib/{queryObserver.mjs → queryObserver.cjs} +76 -51
  146. package/build/lib/queryObserver.cjs.map +1 -0
  147. package/build/lib/queryObserver.d.ts +6 -7
  148. package/build/lib/queryObserver.d.ts.map +1 -0
  149. package/build/lib/queryObserver.js +244 -324
  150. package/build/lib/queryObserver.js.map +1 -1
  151. package/build/lib/queryObserver.legacy.cjs +561 -0
  152. package/build/lib/queryObserver.legacy.cjs.map +1 -0
  153. package/build/lib/{queryObserver.esm.js → queryObserver.legacy.js} +107 -89
  154. package/build/lib/queryObserver.legacy.js.map +1 -0
  155. package/build/lib/{removable.mjs → removable.cjs} +7 -5
  156. package/build/lib/{removable.mjs.map → removable.cjs.map} +1 -1
  157. package/build/lib/removable.d.ts +1 -0
  158. package/build/lib/removable.d.ts.map +1 -0
  159. package/build/lib/removable.js +9 -18
  160. package/build/lib/removable.js.map +1 -1
  161. package/build/lib/removable.legacy.cjs +38 -0
  162. package/build/lib/removable.legacy.cjs.map +1 -0
  163. package/build/lib/{removable.esm.js → removable.legacy.js} +3 -3
  164. package/build/lib/removable.legacy.js.map +1 -0
  165. package/build/lib/{retryer.mjs → retryer.cjs} +15 -8
  166. package/build/lib/{retryer.mjs.map → retryer.cjs.map} +1 -1
  167. package/build/lib/retryer.d.ts +5 -4
  168. package/build/lib/retryer.d.ts.map +1 -0
  169. package/build/lib/retryer.js +21 -25
  170. package/build/lib/retryer.js.map +1 -1
  171. package/build/lib/retryer.legacy.cjs +158 -0
  172. package/build/lib/retryer.legacy.cjs.map +1 -0
  173. package/build/lib/{retryer.esm.js → retryer.legacy.js} +6 -4
  174. package/build/lib/retryer.legacy.js.map +1 -0
  175. package/build/lib/{subscribable.esm.js → subscribable.cjs} +8 -6
  176. package/build/lib/subscribable.cjs.map +1 -0
  177. package/build/lib/subscribable.d.ts +3 -2
  178. package/build/lib/subscribable.d.ts.map +1 -0
  179. package/build/lib/subscribable.js +5 -7
  180. package/build/lib/subscribable.js.map +1 -1
  181. package/build/lib/subscribable.legacy.cjs +28 -0
  182. package/build/lib/subscribable.legacy.cjs.map +1 -0
  183. package/build/lib/{subscribable.mjs → subscribable.legacy.js} +5 -5
  184. package/build/lib/subscribable.legacy.js.map +1 -0
  185. package/build/lib/tests/focusManager.test.d.ts +1 -0
  186. package/build/lib/tests/focusManager.test.d.ts.map +1 -0
  187. package/build/lib/tests/hydration.test.d.ts +1 -0
  188. package/build/lib/tests/hydration.test.d.ts.map +1 -0
  189. package/build/lib/tests/infiniteQueryBehavior.test.d.ts +1 -0
  190. package/build/lib/tests/infiniteQueryBehavior.test.d.ts.map +1 -0
  191. package/build/lib/tests/infiniteQueryObserver.test.d.ts +1 -0
  192. package/build/lib/tests/infiniteQueryObserver.test.d.ts.map +1 -0
  193. package/build/lib/tests/mutationCache.test.d.ts +1 -0
  194. package/build/lib/tests/mutationCache.test.d.ts.map +1 -0
  195. package/build/lib/tests/mutationObserver.test.d.ts +1 -0
  196. package/build/lib/tests/mutationObserver.test.d.ts.map +1 -0
  197. package/build/lib/tests/mutations.test.d.ts +1 -0
  198. package/build/lib/tests/mutations.test.d.ts.map +1 -0
  199. package/build/lib/tests/notifyManager.test.d.ts +1 -0
  200. package/build/lib/tests/notifyManager.test.d.ts.map +1 -0
  201. package/build/lib/tests/onlineManager.test.d.ts +1 -0
  202. package/build/lib/tests/onlineManager.test.d.ts.map +1 -0
  203. package/build/lib/tests/queriesObserver.test.d.ts +1 -0
  204. package/build/lib/tests/queriesObserver.test.d.ts.map +1 -0
  205. package/build/lib/tests/query.test.d.ts +1 -0
  206. package/build/lib/tests/query.test.d.ts.map +1 -0
  207. package/build/lib/tests/queryCache.test.d.ts +1 -0
  208. package/build/lib/tests/queryCache.test.d.ts.map +1 -0
  209. package/build/lib/tests/queryClient.test.d.ts +1 -0
  210. package/build/lib/tests/queryClient.test.d.ts.map +1 -0
  211. package/build/lib/tests/queryObserver.test.d.ts +1 -0
  212. package/build/lib/tests/queryObserver.test.d.ts.map +1 -0
  213. package/build/lib/tests/utils.d.ts +1 -0
  214. package/build/lib/tests/utils.d.ts.map +1 -0
  215. package/build/lib/tests/utils.test.d.ts +1 -0
  216. package/build/lib/tests/utils.test.d.ts.map +1 -0
  217. package/build/lib/types.d.ts +42 -48
  218. package/build/lib/types.d.ts.map +1 -0
  219. package/build/lib/{utils.mjs → utils.cjs} +23 -2
  220. package/build/lib/{utils.mjs.map → utils.cjs.map} +1 -1
  221. package/build/lib/utils.d.ts +4 -3
  222. package/build/lib/utils.d.ts.map +1 -0
  223. package/build/lib/utils.js +2 -23
  224. package/build/lib/utils.js.map +1 -1
  225. package/build/lib/utils.legacy.cjs +248 -0
  226. package/build/lib/utils.legacy.cjs.map +1 -0
  227. package/build/lib/{utils.esm.js → utils.legacy.js} +1 -1
  228. package/build/lib/utils.legacy.js.map +1 -0
  229. package/package.json +13 -9
  230. package/src/focusManager.ts +3 -3
  231. package/src/hydration.ts +18 -37
  232. package/src/index.ts +3 -3
  233. package/src/infiniteQueryBehavior.ts +16 -18
  234. package/src/mutation.ts +1 -1
  235. package/src/mutationCache.ts +4 -4
  236. package/src/mutationObserver.ts +1 -1
  237. package/src/notifyManager.ts +7 -3
  238. package/src/onlineManager.ts +11 -6
  239. package/src/queriesObserver.ts +75 -25
  240. package/src/query.ts +7 -5
  241. package/src/queryCache.ts +6 -9
  242. package/src/queryClient.ts +23 -21
  243. package/src/queryObserver.ts +93 -56
  244. package/src/subscribable.ts +5 -5
  245. package/src/tests/focusManager.test.tsx +21 -14
  246. package/src/tests/hydration.test.tsx +7 -3
  247. package/src/tests/infiniteQueryBehavior.test.tsx +5 -2
  248. package/src/tests/notifyManager.test.tsx +15 -0
  249. package/src/tests/onlineManager.test.tsx +21 -0
  250. package/src/tests/query.test.tsx +4 -2
  251. package/src/tests/queryCache.test.tsx +1 -19
  252. package/src/tests/queryClient.test.tsx +79 -3
  253. package/src/tests/queryObserver.test.tsx +121 -0
  254. package/src/types.ts +31 -30
  255. package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js.map +0 -1
  256. package/build/lib/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  257. package/build/lib/focusManager.esm.js.map +0 -1
  258. package/build/lib/focusManager.mjs.map +0 -1
  259. package/build/lib/hydration.esm.js.map +0 -1
  260. package/build/lib/hydration.mjs.map +0 -1
  261. package/build/lib/index.esm.js +0 -14
  262. package/build/lib/index.esm.js.map +0 -1
  263. package/build/lib/index.mjs +0 -14
  264. package/build/lib/index.mjs.map +0 -1
  265. package/build/lib/infiniteQueryBehavior.esm.js.map +0 -1
  266. package/build/lib/infiniteQueryBehavior.mjs.map +0 -1
  267. package/build/lib/infiniteQueryObserver.esm.js.map +0 -1
  268. package/build/lib/mutation.esm.js.map +0 -1
  269. package/build/lib/mutation.mjs.map +0 -1
  270. package/build/lib/mutationCache.esm.js.map +0 -1
  271. package/build/lib/mutationCache.mjs.map +0 -1
  272. package/build/lib/mutationObserver.esm.js.map +0 -1
  273. package/build/lib/mutationObserver.mjs.map +0 -1
  274. package/build/lib/notifyManager.esm.js.map +0 -1
  275. package/build/lib/notifyManager.mjs.map +0 -1
  276. package/build/lib/onlineManager.esm.js.map +0 -1
  277. package/build/lib/onlineManager.mjs.map +0 -1
  278. package/build/lib/queriesObserver.esm.js.map +0 -1
  279. package/build/lib/queriesObserver.mjs.map +0 -1
  280. package/build/lib/query.esm.js.map +0 -1
  281. package/build/lib/query.mjs.map +0 -1
  282. package/build/lib/queryCache.esm.js.map +0 -1
  283. package/build/lib/queryCache.mjs.map +0 -1
  284. package/build/lib/queryClient.esm.js.map +0 -1
  285. package/build/lib/queryClient.mjs.map +0 -1
  286. package/build/lib/queryObserver.esm.js.map +0 -1
  287. package/build/lib/queryObserver.mjs.map +0 -1
  288. package/build/lib/removable.esm.js.map +0 -1
  289. package/build/lib/retryer.esm.js.map +0 -1
  290. package/build/lib/subscribable.esm.js.map +0 -1
  291. package/build/lib/subscribable.mjs.map +0 -1
  292. package/build/lib/utils.esm.js.map +0 -1
  293. package/build/umd/index.development.js +0 -2683
  294. package/build/umd/index.development.js.map +0 -1
  295. package/build/umd/index.production.js +0 -2
  296. package/build/umd/index.production.js.map +0 -1
@@ -25,6 +25,8 @@ import type {
25
25
  ResetOptions,
26
26
  SetDataOptions,
27
27
  DefaultError,
28
+ CancelOptions,
29
+ DefaultedQueryObserverOptions,
28
30
  } from './types'
29
31
  import type { QueryState } from './query'
30
32
  import { QueryCache } from './queryCache'
@@ -33,7 +35,6 @@ import { focusManager } from './focusManager'
33
35
  import { onlineManager } from './onlineManager'
34
36
  import { notifyManager } from './notifyManager'
35
37
  import { infiniteQueryBehavior } from './infiniteQueryBehavior'
36
- import type { CancelOptions, DefaultedQueryObserverOptions } from './types'
37
38
 
38
39
  // TYPES
39
40
 
@@ -212,14 +213,12 @@ export class QueryClient {
212
213
  filters: QueryFilters = {},
213
214
  cancelOptions: CancelOptions = {},
214
215
  ): Promise<void> {
215
- if (typeof cancelOptions.revert === 'undefined') {
216
- cancelOptions.revert = true
217
- }
216
+ const defaultedCancelOptions = { revert: true, ...cancelOptions }
218
217
 
219
218
  const promises = notifyManager.batch(() =>
220
219
  this.#queryCache
221
220
  .findAll(filters)
222
- .map((query) => query.cancel(cancelOptions)),
221
+ .map((query) => query.cancel(defaultedCancelOptions)),
223
222
  )
224
223
 
225
224
  return Promise.all(promises).then(noop).catch(noop)
@@ -249,25 +248,26 @@ export class QueryClient {
249
248
  filters: RefetchQueryFilters = {},
250
249
  options?: RefetchOptions,
251
250
  ): Promise<void> {
251
+ const fetchOptions = {
252
+ ...options,
253
+ cancelRefetch: options?.cancelRefetch ?? true,
254
+ }
252
255
  const promises = notifyManager.batch(() =>
253
256
  this.#queryCache
254
257
  .findAll(filters)
255
258
  .filter((query) => !query.isDisabled())
256
- .map((query) =>
257
- query.fetch(undefined, {
258
- ...options,
259
- cancelRefetch: options?.cancelRefetch ?? true,
260
- }),
261
- ),
259
+ .map((query) => {
260
+ let promise = query.fetch(undefined, fetchOptions)
261
+ if (!fetchOptions.throwOnError) {
262
+ promise = promise.catch(noop)
263
+ }
264
+ return query.state.fetchStatus === 'paused'
265
+ ? Promise.resolve()
266
+ : promise
267
+ }),
262
268
  )
263
269
 
264
- let promise = Promise.all(promises).then(noop)
265
-
266
- if (!options?.throwOnError) {
267
- promise = promise.catch(noop)
268
- }
269
-
270
- return promise
270
+ return Promise.all(promises).then(noop)
271
271
  }
272
272
 
273
273
  fetchQuery<
@@ -325,7 +325,9 @@ export class QueryClient {
325
325
  TPageParam
326
326
  >,
327
327
  ): Promise<InfiniteData<TData>> {
328
- options.behavior = infiniteQueryBehavior<TQueryFnData, TError, TData>()
328
+ options.behavior = infiniteQueryBehavior<TQueryFnData, TError, TData>(
329
+ options.pages,
330
+ )
329
331
  return this.fetchQuery(options)
330
332
  }
331
333
 
@@ -480,8 +482,8 @@ export class QueryClient {
480
482
  defaultedOptions.refetchOnReconnect =
481
483
  defaultedOptions.networkMode !== 'always'
482
484
  }
483
- if (typeof defaultedOptions.throwErrors === 'undefined') {
484
- defaultedOptions.throwErrors = !!defaultedOptions.suspense
485
+ if (typeof defaultedOptions.throwOnError === 'undefined') {
486
+ defaultedOptions.throwOnError = !!defaultedOptions.suspense
485
487
  }
486
488
 
487
489
  return defaultedOptions as DefaultedQueryObserverOptions<
@@ -1,14 +1,6 @@
1
- import type { DefaultedQueryObserverOptions, DefaultError } from './types'
2
- import {
3
- isServer,
4
- isValidTimeout,
5
- noop,
6
- replaceData,
7
- shallowEqualObjects,
8
- timeUntilStale,
9
- } from './utils'
10
- import { notifyManager } from './notifyManager'
11
1
  import type {
2
+ DefaultedQueryObserverOptions,
3
+ DefaultError,
12
4
  PlaceholderDataFunction,
13
5
  QueryKey,
14
6
  QueryObserverBaseResult,
@@ -17,11 +9,20 @@ import type {
17
9
  QueryOptions,
18
10
  RefetchOptions,
19
11
  } from './types'
20
- import type { Query, QueryState, Action, FetchOptions } from './query'
12
+ import {
13
+ isServer,
14
+ isValidTimeout,
15
+ noop,
16
+ replaceData,
17
+ shallowEqualObjects,
18
+ timeUntilStale,
19
+ } from './utils'
20
+ import { notifyManager } from './notifyManager'
21
+ import type { Query, QueryState, FetchOptions } from './query'
21
22
  import type { QueryClient } from './queryClient'
22
23
  import { focusManager } from './focusManager'
23
24
  import { Subscribable } from './subscribable'
24
- import { canFetch, isCancelledError } from './retryer'
25
+ import { canFetch } from './retryer'
25
26
 
26
27
  type QueryObserverListener<TData, TError> = (
27
28
  result: QueryObserverResult<TData, TError>,
@@ -29,8 +30,6 @@ type QueryObserverListener<TData, TError> = (
29
30
 
30
31
  export interface NotifyOptions {
31
32
  listeners?: boolean
32
- onError?: boolean
33
- onSuccess?: boolean
34
33
  }
35
34
 
36
35
  export interface ObserverFetchOptions extends FetchOptions {
@@ -64,10 +63,12 @@ export class QueryObserver<
64
63
  TQueryData,
65
64
  TQueryKey
66
65
  >
67
- #previousQueryResult?: QueryObserverResult<TData, TError>
68
66
  #selectError: TError | null
69
67
  #selectFn?: (data: TQueryData) => TData
70
68
  #selectResult?: TData
69
+ // This property keeps track of the last query with defined data.
70
+ // It will be used to pass the previous data and query to the placeholder function between renders.
71
+ #lastQueryWithDefinedData?: Query<TQueryFnData, TError, TQueryData, TQueryKey>
71
72
  #staleTimeoutId?: ReturnType<typeof setTimeout>
72
73
  #refetchIntervalId?: ReturnType<typeof setInterval>
73
74
  #currentRefetchInterval?: number | false
@@ -97,7 +98,7 @@ export class QueryObserver<
97
98
  }
98
99
 
99
100
  protected onSubscribe(): void {
100
- if (this.listeners.length === 1) {
101
+ if (this.listeners.size === 1) {
101
102
  this.#currentQuery.addObserver(this)
102
103
 
103
104
  if (shouldFetchOnMount(this.#currentQuery, this.options)) {
@@ -109,7 +110,7 @@ export class QueryObserver<
109
110
  }
110
111
 
111
112
  protected onUnsubscribe(): void {
112
- if (!this.listeners.length) {
113
+ if (!this.hasListeners()) {
113
114
  this.destroy()
114
115
  }
115
116
  }
@@ -131,7 +132,7 @@ export class QueryObserver<
131
132
  }
132
133
 
133
134
  destroy(): void {
134
- this.listeners = []
135
+ this.listeners = new Set()
135
136
  this.#clearStaleTimeout()
136
137
  this.#clearRefetchInterval()
137
138
  this.#currentQuery.removeObserver(this)
@@ -190,7 +191,7 @@ export class QueryObserver<
190
191
  }
191
192
 
192
193
  // Update result
193
- this.#updateResult(notifyOptions)
194
+ this.updateResult(notifyOptions)
194
195
 
195
196
  // Update stale interval if needed
196
197
  if (
@@ -226,7 +227,30 @@ export class QueryObserver<
226
227
  ): QueryObserverResult<TData, TError> {
227
228
  const query = this.#client.getQueryCache().build(this.#client, options)
228
229
 
229
- return this.createResult(query, options)
230
+ const result = this.createResult(query, options)
231
+
232
+ if (shouldAssignObserverCurrentProperties(this, result)) {
233
+ // this assigns the optimistic result to the current Observer
234
+ // because if the query function changes, useQuery will be performing
235
+ // an effect where it would fetch again.
236
+ // When the fetch finishes, we perform a deep data cloning in order
237
+ // to reuse objects references. This deep data clone is performed against
238
+ // the `observer.currentResult.data` property
239
+ // When QueryKey changes, we refresh the query and get new `optimistic`
240
+ // result, while we leave the `observer.currentResult`, so when new data
241
+ // arrives, it finds the old `observer.currentResult` which is related
242
+ // to the old QueryKey. Which means that currentResult and selectData are
243
+ // out of sync already.
244
+ // To solve this, we move the cursor of the currentResult everytime
245
+ // an observer reads an optimistic value.
246
+
247
+ // When keeping the previous data, the result doesn't change until new
248
+ // data arrives.
249
+ this.#currentResult = result
250
+ this.#currentResultOptions = this.options
251
+ this.#currentResultState = this.#currentQuery.state
252
+ }
253
+ return result
230
254
  }
231
255
 
232
256
  getCurrentResult(): QueryObserverResult<TData, TError> {
@@ -290,7 +314,7 @@ export class QueryObserver<
290
314
  ...fetchOptions,
291
315
  cancelRefetch: fetchOptions.cancelRefetch ?? true,
292
316
  }).then(() => {
293
- this.#updateResult()
317
+ this.updateResult()
294
318
  return this.#currentResult
295
319
  })
296
320
  }
@@ -336,18 +360,20 @@ export class QueryObserver<
336
360
 
337
361
  this.#staleTimeoutId = setTimeout(() => {
338
362
  if (!this.#currentResult.isStale) {
339
- this.#updateResult()
363
+ this.updateResult()
340
364
  }
341
365
  }, timeout)
342
366
  }
343
367
 
344
368
  #computeRefetchInterval() {
345
- return typeof this.options.refetchInterval === 'function'
346
- ? this.options.refetchInterval(
347
- this.#currentResult.data,
348
- this.#currentQuery,
349
- )
350
- : this.options.refetchInterval ?? false
369
+ return (
370
+ (typeof this.options.refetchInterval === 'function'
371
+ ? this.options.refetchInterval(
372
+ this.#currentResult.data,
373
+ this.#currentQuery,
374
+ )
375
+ : this.options.refetchInterval) ?? false
376
+ )
351
377
  }
352
378
 
353
379
  #updateRefetchInterval(nextInterval: number | false): void {
@@ -414,9 +440,6 @@ export class QueryObserver<
414
440
  const queryInitialState = queryChange
415
441
  ? query.state
416
442
  : this.#currentQueryInitialState
417
- const prevQueryResult = queryChange
418
- ? this.#currentResult
419
- : this.#previousQueryResult
420
443
 
421
444
  const { state } = query
422
445
  let { error, errorUpdatedAt, fetchStatus, status } = state
@@ -490,7 +513,10 @@ export class QueryObserver<
490
513
  typeof options.placeholderData === 'function'
491
514
  ? (
492
515
  options.placeholderData as unknown as PlaceholderDataFunction<TQueryData>
493
- )(prevQueryResult?.data as TQueryData | undefined)
516
+ )(
517
+ this.#lastQueryWithDefinedData?.state.data,
518
+ this.#lastQueryWithDefinedData as any,
519
+ )
494
520
  : options.placeholderData
495
521
  if (options.select && typeof placeholderData !== 'undefined') {
496
522
  try {
@@ -504,7 +530,11 @@ export class QueryObserver<
504
530
 
505
531
  if (typeof placeholderData !== 'undefined') {
506
532
  status = 'success'
507
- data = replaceData(prevResult?.data, placeholderData, options) as TData
533
+ data = replaceData(
534
+ prevResult?.data,
535
+ placeholderData as unknown,
536
+ options,
537
+ ) as TData
508
538
  isPlaceholderData = true
509
539
  }
510
540
  }
@@ -554,7 +584,7 @@ export class QueryObserver<
554
584
  return result as QueryObserverResult<TData, TError>
555
585
  }
556
586
 
557
- #updateResult(notifyOptions?: NotifyOptions): void {
587
+ updateResult(notifyOptions?: NotifyOptions): void {
558
588
  const prevResult = this.#currentResult as
559
589
  | QueryObserverResult<TData, TError>
560
590
  | undefined
@@ -568,6 +598,9 @@ export class QueryObserver<
568
598
  return
569
599
  }
570
600
 
601
+ if (this.#currentResultState.data !== undefined) {
602
+ this.#lastQueryWithDefinedData = this.#currentQuery
603
+ }
571
604
  this.#currentResult = nextResult
572
605
 
573
606
  // Determine which callbacks to trigger
@@ -589,7 +622,7 @@ export class QueryObserver<
589
622
 
590
623
  const includedProps = new Set(notifyOnChangeProps ?? this.#trackedProps)
591
624
 
592
- if (this.options.throwErrors) {
625
+ if (this.options.throwOnError) {
593
626
  includedProps.add('error')
594
627
  }
595
628
 
@@ -619,7 +652,6 @@ export class QueryObserver<
619
652
  | undefined
620
653
  this.#currentQuery = query
621
654
  this.#currentQueryInitialState = query.state
622
- this.#previousQueryResult = this.#currentResult
623
655
 
624
656
  if (this.hasListeners()) {
625
657
  prevQuery?.removeObserver(this)
@@ -627,16 +659,8 @@ export class QueryObserver<
627
659
  }
628
660
  }
629
661
 
630
- onQueryUpdate(action: Action<TData, TError>): void {
631
- const notifyOptions: NotifyOptions = {}
632
-
633
- if (action.type === 'success') {
634
- notifyOptions.onSuccess = !action.manual
635
- } else if (action.type === 'error' && !isCancelledError(action.error)) {
636
- notifyOptions.onError = true
637
- }
638
-
639
- this.#updateResult(notifyOptions)
662
+ onQueryUpdate(): void {
663
+ this.updateResult()
640
664
 
641
665
  if (this.hasListeners()) {
642
666
  this.#updateTimers()
@@ -645,16 +669,7 @@ export class QueryObserver<
645
669
 
646
670
  #notify(notifyOptions: NotifyOptions): void {
647
671
  notifyManager.batch(() => {
648
- // First trigger the configuration callbacks
649
- if (notifyOptions.onSuccess) {
650
- this.options.onSuccess?.(this.#currentResult.data!)
651
- this.options.onSettled?.(this.#currentResult.data, null)
652
- } else if (notifyOptions.onError) {
653
- this.options.onError?.(this.#currentResult.error!)
654
- this.options.onSettled?.(undefined, this.#currentResult.error)
655
- }
656
-
657
- // Then trigger the listeners
672
+ // First, trigger the listeners
658
673
  if (notifyOptions.listeners) {
659
674
  this.listeners.forEach((listener) => {
660
675
  listener(this.#currentResult)
@@ -727,3 +742,25 @@ function isStale(
727
742
  ): boolean {
728
743
  return query.isStaleByTime(options.staleTime)
729
744
  }
745
+
746
+ // this function would decide if we will update the observer's 'current'
747
+ // properties after an optimistic reading via getOptimisticResult
748
+ function shouldAssignObserverCurrentProperties<
749
+ TQueryFnData = unknown,
750
+ TError = unknown,
751
+ TData = TQueryFnData,
752
+ TQueryData = TQueryFnData,
753
+ TQueryKey extends QueryKey = QueryKey,
754
+ >(
755
+ observer: QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>,
756
+ optimisticResult: QueryObserverResult<TData, TError>,
757
+ ) {
758
+ // if the newly created result isn't what the observer is holding as current,
759
+ // then we'll need to update the properties as well
760
+ if (observer.getCurrentResult() !== optimisticResult) {
761
+ return true
762
+ }
763
+
764
+ // basically, just keep previous properties if nothing changed
765
+ return false
766
+ }
@@ -1,26 +1,26 @@
1
1
  type Listener = () => void
2
2
 
3
3
  export class Subscribable<TListener extends Function = Listener> {
4
- protected listeners: TListener[]
4
+ protected listeners: Set<TListener>
5
5
 
6
6
  constructor() {
7
- this.listeners = []
7
+ this.listeners = new Set()
8
8
  this.subscribe = this.subscribe.bind(this)
9
9
  }
10
10
 
11
11
  subscribe(listener: TListener): () => void {
12
- this.listeners.push(listener)
12
+ this.listeners.add(listener)
13
13
 
14
14
  this.onSubscribe()
15
15
 
16
16
  return () => {
17
- this.listeners = this.listeners.filter((x) => x !== listener)
17
+ this.listeners.delete(listener)
18
18
  this.onUnsubscribe()
19
19
  }
20
20
  }
21
21
 
22
22
  hasListeners(): boolean {
23
- return this.listeners.length > 0
23
+ return this.listeners.size > 0
24
24
  }
25
25
 
26
26
  protected onSubscribe(): void {
@@ -39,20 +39,6 @@ describe('focusManager', () => {
39
39
  expect(focusManager.isFocused()).toBeTruthy()
40
40
  })
41
41
 
42
- it('should not notify listeners on focus if already focused', async () => {
43
- const subscriptionSpy = vi.fn()
44
- const unsubscribe = focusManager.subscribe(subscriptionSpy)
45
-
46
- focusManager.setFocused(true)
47
- expect(subscriptionSpy).toHaveBeenCalledTimes(1)
48
- subscriptionSpy.mockReset()
49
-
50
- focusManager.setFocused(false)
51
- expect(subscriptionSpy).toHaveBeenCalledTimes(0)
52
-
53
- unsubscribe()
54
- })
55
-
56
42
  it('should return true for isFocused if document is undefined', async () => {
57
43
  const { document } = globalThis
58
44
 
@@ -150,4 +136,25 @@ describe('focusManager', () => {
150
136
 
151
137
  unsubscribe2()
152
138
  })
139
+
140
+ test('should call listeners when setFocused is called', () => {
141
+ const listener = vi.fn()
142
+
143
+ focusManager.subscribe(listener)
144
+
145
+ focusManager.setFocused(true)
146
+ focusManager.setFocused(true)
147
+
148
+ expect(listener).toHaveBeenCalledTimes(1)
149
+
150
+ focusManager.setFocused(false)
151
+ focusManager.setFocused(false)
152
+
153
+ expect(listener).toHaveBeenCalledTimes(2)
154
+
155
+ focusManager.setFocused(undefined)
156
+ focusManager.setFocused(undefined)
157
+
158
+ expect(listener).toHaveBeenCalledTimes(3)
159
+ })
153
160
  })
@@ -113,7 +113,9 @@ describe('dehydration and rehydration', () => {
113
113
  queryFn: () => fetchData('string'),
114
114
  })
115
115
 
116
- const dehydrated = dehydrate(queryClient, { dehydrateQueries: false })
116
+ const dehydrated = dehydrate(queryClient, {
117
+ shouldDehydrateQuery: () => false,
118
+ })
117
119
 
118
120
  expect(dehydrated.queries.length).toBe(0)
119
121
 
@@ -244,7 +246,7 @@ describe('dehydration and rehydration', () => {
244
246
  consoleMock.mockRestore()
245
247
  })
246
248
 
247
- test('should filter queries via shouldDehydrateQuery', async () => {
249
+ test('should filter queries via dehydrateQuery', async () => {
248
250
  const queryCache = new QueryCache()
249
251
  const queryClient = createQueryClient({ queryCache })
250
252
  await queryClient.prefetchQuery({
@@ -446,7 +448,9 @@ describe('dehydration and rehydration', () => {
446
448
  ).catch(() => undefined)
447
449
 
448
450
  await sleep(1)
449
- const dehydrated = dehydrate(queryClient, { dehydrateMutations: false })
451
+ const dehydrated = dehydrate(queryClient, {
452
+ shouldDehydrateMutation: () => false,
453
+ })
450
454
 
451
455
  expect(dehydrated.mutations.length).toBe(0)
452
456
 
@@ -1,14 +1,16 @@
1
1
  import { waitFor } from '@testing-library/react'
2
- import type { QueryClient, InfiniteQueryObserverResult } from '..'
2
+ import type { QueryClient, QueryCache, InfiniteQueryObserverResult } from '..'
3
3
  import { InfiniteQueryObserver, CancelledError } from '..'
4
4
  import { createQueryClient, queryKey, sleep } from './utils'
5
5
  import { vi } from 'vitest'
6
6
 
7
7
  describe('InfiniteQueryBehavior', () => {
8
8
  let queryClient: QueryClient
9
+ let queryCache: QueryCache
9
10
 
10
11
  beforeEach(() => {
11
12
  queryClient = createQueryClient()
13
+ queryCache = queryClient.getQueryCache()
12
14
  queryClient.mount()
13
15
  })
14
16
 
@@ -35,9 +37,10 @@ describe('InfiniteQueryBehavior', () => {
35
37
  })
36
38
 
37
39
  await waitFor(() => {
40
+ const query = queryCache.find({ queryKey: key })!
38
41
  return expect(observerResult).toMatchObject({
39
42
  isError: true,
40
- error: new Error('Missing queryFn'),
43
+ error: new Error(`Missing queryFn: '${query.queryHash}'`),
41
44
  })
42
45
  })
43
46
 
@@ -49,4 +49,19 @@ describe('notifyManager', () => {
49
49
 
50
50
  expect(notifySpy).toHaveBeenCalledTimes(1)
51
51
  })
52
+
53
+ it('typedefs should catch proper signatures', async () => {
54
+ const notifyManagerTest = createNotifyManager()
55
+
56
+ // we define some fn with its signature:
57
+ const fn: (a: string, b: number) => string = (a, b) => a + b
58
+
59
+ //now somefn expect to be called with args [a: string, b: number]
60
+ const someFn = notifyManagerTest.batchCalls(fn)
61
+
62
+ someFn('im happy', 4)
63
+
64
+ //@ts-expect-error
65
+ someFn('im not happy', false)
66
+ })
52
67
  })
@@ -148,4 +148,25 @@ describe('onlineManager', () => {
148
148
 
149
149
  unsubscribe2()
150
150
  })
151
+
152
+ test('should call listeners when setOnline is called', () => {
153
+ const listener = vi.fn()
154
+
155
+ onlineManager.subscribe(listener)
156
+
157
+ onlineManager.setOnline(true)
158
+ onlineManager.setOnline(true)
159
+
160
+ expect(listener).toHaveBeenCalledTimes(1)
161
+
162
+ onlineManager.setOnline(false)
163
+ onlineManager.setOnline(false)
164
+
165
+ expect(listener).toHaveBeenCalledTimes(2)
166
+
167
+ onlineManager.setOnline(undefined)
168
+ onlineManager.setOnline(undefined)
169
+
170
+ expect(listener).toHaveBeenCalledTimes(3)
171
+ })
151
172
  })
@@ -761,10 +761,12 @@ describe('query', () => {
761
761
  })
762
762
 
763
763
  const unsubscribe = observer.subscribe(() => undefined)
764
+
764
765
  await sleep(10)
766
+ const query = queryCache.find({ queryKey: key })!
765
767
  expect(observer.getCurrentResult()).toMatchObject({
766
768
  status: 'error',
767
- error: new Error('Missing queryFn'),
769
+ error: new Error(`Missing queryFn: '${query.queryHash}'`),
768
770
  })
769
771
  unsubscribe()
770
772
  })
@@ -788,7 +790,7 @@ describe('query', () => {
788
790
 
789
791
  await sleep(10)
790
792
 
791
- const error = new Error('undefined')
793
+ const error = new Error(`${JSON.stringify(key)} data is undefined`)
792
794
 
793
795
  expect(observerResult).toMatchObject({
794
796
  isError: true,
@@ -1,6 +1,5 @@
1
1
  import { sleep, queryKey, createQueryClient } from './utils'
2
- import { QueryClient } from '..'
3
- import { QueryCache, QueryObserver } from '..'
2
+ import { QueryClient, QueryCache, QueryObserver } from '..'
4
3
  import { waitFor } from '@testing-library/react'
5
4
  import { vi } from 'vitest'
6
5
 
@@ -329,23 +328,6 @@ describe('queryCache', () => {
329
328
  })
330
329
  })
331
330
 
332
- describe('QueryCacheConfig.createStore', () => {
333
- test('should call createStore', async () => {
334
- const createStore = vi.fn().mockImplementation(() => new Map())
335
- new QueryCache({ createStore })
336
- expect(createStore).toHaveBeenCalledWith()
337
- })
338
-
339
- test('should use created store', async () => {
340
- const store = new Map()
341
- const spy = vi.spyOn(store, 'get')
342
-
343
- new QueryCache({ createStore: () => store }).get('key')
344
-
345
- expect(spy).toHaveBeenCalledTimes(1)
346
- })
347
- })
348
-
349
331
  describe('QueryCache.add', () => {
350
332
  test('should not try to add a query already added to the cache', async () => {
351
333
  const key = queryKey()