@tanstack/query-core 5.0.0-alpha.3 → 5.0.0-alpha.32

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 (200) hide show
  1. package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js +13 -0
  2. package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js.map +1 -0
  3. package/build/lib/_virtual/_rollupPluginBabelHelpers.js +16 -0
  4. package/build/lib/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  5. package/build/lib/focusManager.d.ts +1 -0
  6. package/build/lib/focusManager.d.ts.map +1 -0
  7. package/build/lib/focusManager.esm.js +31 -15
  8. package/build/lib/focusManager.esm.js.map +1 -1
  9. package/build/lib/focusManager.js +31 -15
  10. package/build/lib/focusManager.js.map +1 -1
  11. package/build/lib/hydration.d.ts +3 -6
  12. package/build/lib/hydration.d.ts.map +1 -0
  13. package/build/lib/hydration.esm.js +9 -20
  14. package/build/lib/hydration.esm.js.map +1 -1
  15. package/build/lib/hydration.js +9 -20
  16. package/build/lib/hydration.js.map +1 -1
  17. package/build/lib/hydration.mjs +4 -18
  18. package/build/lib/hydration.mjs.map +1 -1
  19. package/build/lib/index.d.ts +4 -3
  20. package/build/lib/index.d.ts.map +1 -0
  21. package/build/lib/infiniteQueryBehavior.d.ts +3 -2
  22. package/build/lib/infiniteQueryBehavior.d.ts.map +1 -0
  23. package/build/lib/infiniteQueryBehavior.esm.js +52 -48
  24. package/build/lib/infiniteQueryBehavior.esm.js.map +1 -1
  25. package/build/lib/infiniteQueryBehavior.js +52 -48
  26. package/build/lib/infiniteQueryBehavior.js.map +1 -1
  27. package/build/lib/infiniteQueryBehavior.mjs +48 -45
  28. package/build/lib/infiniteQueryBehavior.mjs.map +1 -1
  29. package/build/lib/infiniteQueryObserver.d.ts +7 -6
  30. package/build/lib/infiniteQueryObserver.d.ts.map +1 -0
  31. package/build/lib/infiniteQueryObserver.esm.js +7 -8
  32. package/build/lib/infiniteQueryObserver.esm.js.map +1 -1
  33. package/build/lib/infiniteQueryObserver.js +7 -8
  34. package/build/lib/infiniteQueryObserver.js.map +1 -1
  35. package/build/lib/infiniteQueryObserver.mjs +4 -6
  36. package/build/lib/infiniteQueryObserver.mjs.map +1 -1
  37. package/build/lib/mutation.d.ts +1 -0
  38. package/build/lib/mutation.d.ts.map +1 -0
  39. package/build/lib/mutation.esm.js +127 -102
  40. package/build/lib/mutation.esm.js.map +1 -1
  41. package/build/lib/mutation.js +127 -102
  42. package/build/lib/mutation.js.map +1 -1
  43. package/build/lib/mutationCache.d.ts +1 -0
  44. package/build/lib/mutationCache.d.ts.map +1 -0
  45. package/build/lib/mutationCache.esm.js +34 -20
  46. package/build/lib/mutationCache.esm.js.map +1 -1
  47. package/build/lib/mutationCache.js +34 -20
  48. package/build/lib/mutationCache.js.map +1 -1
  49. package/build/lib/mutationCache.mjs +5 -4
  50. package/build/lib/mutationCache.mjs.map +1 -1
  51. package/build/lib/mutationObserver.d.ts +1 -0
  52. package/build/lib/mutationObserver.d.ts.map +1 -0
  53. package/build/lib/mutationObserver.esm.js +82 -52
  54. package/build/lib/mutationObserver.esm.js.map +1 -1
  55. package/build/lib/mutationObserver.js +82 -52
  56. package/build/lib/mutationObserver.js.map +1 -1
  57. package/build/lib/mutationObserver.mjs +1 -1
  58. package/build/lib/mutationObserver.mjs.map +1 -1
  59. package/build/lib/notifyManager.d.ts +1 -0
  60. package/build/lib/notifyManager.d.ts.map +1 -0
  61. package/build/lib/onlineManager.d.ts +1 -0
  62. package/build/lib/onlineManager.d.ts.map +1 -0
  63. package/build/lib/onlineManager.esm.js +29 -14
  64. package/build/lib/onlineManager.esm.js.map +1 -1
  65. package/build/lib/onlineManager.js +29 -14
  66. package/build/lib/onlineManager.js.map +1 -1
  67. package/build/lib/queriesObserver.d.ts +1 -0
  68. package/build/lib/queriesObserver.d.ts.map +1 -0
  69. package/build/lib/queriesObserver.esm.js +98 -68
  70. package/build/lib/queriesObserver.esm.js.map +1 -1
  71. package/build/lib/queriesObserver.js +98 -68
  72. package/build/lib/queriesObserver.js.map +1 -1
  73. package/build/lib/queriesObserver.mjs +7 -6
  74. package/build/lib/queriesObserver.mjs.map +1 -1
  75. package/build/lib/query.d.ts +5 -3
  76. package/build/lib/query.d.ts.map +1 -0
  77. package/build/lib/query.esm.js +211 -162
  78. package/build/lib/query.esm.js.map +1 -1
  79. package/build/lib/query.js +211 -162
  80. package/build/lib/query.js.map +1 -1
  81. package/build/lib/query.mjs +2 -2
  82. package/build/lib/query.mjs.map +1 -1
  83. package/build/lib/queryCache.d.ts +1 -1
  84. package/build/lib/queryCache.d.ts.map +1 -0
  85. package/build/lib/queryCache.esm.js +20 -13
  86. package/build/lib/queryCache.esm.js.map +1 -1
  87. package/build/lib/queryCache.js +20 -13
  88. package/build/lib/queryCache.js.map +1 -1
  89. package/build/lib/queryCache.mjs +6 -5
  90. package/build/lib/queryCache.mjs.map +1 -1
  91. package/build/lib/queryClient.d.ts +1 -0
  92. package/build/lib/queryClient.d.ts.map +1 -0
  93. package/build/lib/queryClient.esm.js +113 -71
  94. package/build/lib/queryClient.esm.js.map +1 -1
  95. package/build/lib/queryClient.js +113 -71
  96. package/build/lib/queryClient.js.map +1 -1
  97. package/build/lib/queryClient.mjs +17 -13
  98. package/build/lib/queryClient.mjs.map +1 -1
  99. package/build/lib/queryObserver.d.ts +3 -4
  100. package/build/lib/queryObserver.d.ts.map +1 -0
  101. package/build/lib/queryObserver.esm.js +303 -214
  102. package/build/lib/queryObserver.esm.js.map +1 -1
  103. package/build/lib/queryObserver.js +301 -212
  104. package/build/lib/queryObserver.js.map +1 -1
  105. package/build/lib/queryObserver.mjs +16 -28
  106. package/build/lib/queryObserver.mjs.map +1 -1
  107. package/build/lib/removable.d.ts +1 -0
  108. package/build/lib/removable.d.ts.map +1 -0
  109. package/build/lib/removable.esm.js +13 -6
  110. package/build/lib/removable.esm.js.map +1 -1
  111. package/build/lib/removable.js +13 -6
  112. package/build/lib/removable.js.map +1 -1
  113. package/build/lib/retryer.d.ts +1 -0
  114. package/build/lib/retryer.d.ts.map +1 -0
  115. package/build/lib/retryer.esm.js +15 -14
  116. package/build/lib/retryer.esm.js.map +1 -1
  117. package/build/lib/retryer.js +15 -14
  118. package/build/lib/retryer.js.map +1 -1
  119. package/build/lib/subscribable.d.ts +2 -1
  120. package/build/lib/subscribable.d.ts.map +1 -0
  121. package/build/lib/subscribable.esm.js +4 -4
  122. package/build/lib/subscribable.esm.js.map +1 -1
  123. package/build/lib/subscribable.js +4 -4
  124. package/build/lib/subscribable.js.map +1 -1
  125. package/build/lib/subscribable.mjs +4 -4
  126. package/build/lib/subscribable.mjs.map +1 -1
  127. package/build/lib/tests/focusManager.test.d.ts +1 -0
  128. package/build/lib/tests/focusManager.test.d.ts.map +1 -0
  129. package/build/lib/tests/hydration.test.d.ts +1 -0
  130. package/build/lib/tests/hydration.test.d.ts.map +1 -0
  131. package/build/lib/tests/infiniteQueryBehavior.test.d.ts +1 -0
  132. package/build/lib/tests/infiniteQueryBehavior.test.d.ts.map +1 -0
  133. package/build/lib/tests/infiniteQueryObserver.test.d.ts +1 -0
  134. package/build/lib/tests/infiniteQueryObserver.test.d.ts.map +1 -0
  135. package/build/lib/tests/mutationCache.test.d.ts +1 -0
  136. package/build/lib/tests/mutationCache.test.d.ts.map +1 -0
  137. package/build/lib/tests/mutationObserver.test.d.ts +1 -0
  138. package/build/lib/tests/mutationObserver.test.d.ts.map +1 -0
  139. package/build/lib/tests/mutations.test.d.ts +1 -0
  140. package/build/lib/tests/mutations.test.d.ts.map +1 -0
  141. package/build/lib/tests/notifyManager.test.d.ts +1 -0
  142. package/build/lib/tests/notifyManager.test.d.ts.map +1 -0
  143. package/build/lib/tests/onlineManager.test.d.ts +1 -0
  144. package/build/lib/tests/onlineManager.test.d.ts.map +1 -0
  145. package/build/lib/tests/queriesObserver.test.d.ts +1 -0
  146. package/build/lib/tests/queriesObserver.test.d.ts.map +1 -0
  147. package/build/lib/tests/query.test.d.ts +1 -0
  148. package/build/lib/tests/query.test.d.ts.map +1 -0
  149. package/build/lib/tests/queryCache.test.d.ts +1 -0
  150. package/build/lib/tests/queryCache.test.d.ts.map +1 -0
  151. package/build/lib/tests/queryClient.test.d.ts +1 -0
  152. package/build/lib/tests/queryClient.test.d.ts.map +1 -0
  153. package/build/lib/tests/queryObserver.test.d.ts +1 -0
  154. package/build/lib/tests/queryObserver.test.d.ts.map +1 -0
  155. package/build/lib/tests/utils.d.ts +5 -5
  156. package/build/lib/tests/utils.d.ts.map +1 -0
  157. package/build/lib/tests/utils.test.d.ts +1 -0
  158. package/build/lib/tests/utils.test.d.ts.map +1 -0
  159. package/build/lib/types.d.ts +12 -21
  160. package/build/lib/types.d.ts.map +1 -0
  161. package/build/lib/utils.d.ts +1 -0
  162. package/build/lib/utils.d.ts.map +1 -0
  163. package/build/lib/utils.esm.js +1 -1
  164. package/build/lib/utils.esm.js.map +1 -1
  165. package/build/lib/utils.js +1 -1
  166. package/build/lib/utils.js.map +1 -1
  167. package/build/umd/index.development.js +113 -131
  168. package/build/umd/index.development.js.map +1 -1
  169. package/build/umd/index.production.js +1 -1
  170. package/build/umd/index.production.js.map +1 -1
  171. package/package.json +2 -2
  172. package/src/hydration.ts +18 -37
  173. package/src/index.ts +2 -4
  174. package/src/infiniteQueryBehavior.ts +52 -60
  175. package/src/infiniteQueryObserver.ts +15 -10
  176. package/src/mutationCache.ts +4 -4
  177. package/src/mutationObserver.ts +1 -1
  178. package/src/queriesObserver.ts +11 -11
  179. package/src/query.ts +8 -6
  180. package/src/queryCache.ts +5 -8
  181. package/src/queryClient.ts +18 -19
  182. package/src/queryObserver.ts +32 -41
  183. package/src/subscribable.ts +5 -5
  184. package/src/tests/focusManager.test.tsx +12 -14
  185. package/src/tests/hydration.test.tsx +22 -17
  186. package/src/tests/infiniteQueryBehavior.test.tsx +16 -9
  187. package/src/tests/infiniteQueryObserver.test.tsx +62 -1
  188. package/src/tests/mutationCache.test.tsx +11 -10
  189. package/src/tests/mutationObserver.test.tsx +3 -2
  190. package/src/tests/mutations.test.tsx +11 -10
  191. package/src/tests/notifyManager.test.tsx +7 -6
  192. package/src/tests/onlineManager.test.tsx +12 -17
  193. package/src/tests/queriesObserver.test.tsx +18 -17
  194. package/src/tests/query.test.tsx +19 -18
  195. package/src/tests/queryCache.test.tsx +12 -28
  196. package/src/tests/queryClient.test.tsx +82 -49
  197. package/src/tests/queryObserver.test.tsx +131 -9
  198. package/src/tests/utils.test.tsx +2 -1
  199. package/src/tests/utils.ts +5 -4
  200. package/src/types.ts +22 -20
@@ -1,7 +1,12 @@
1
1
  import { waitFor } from '@testing-library/react'
2
2
  import '@testing-library/jest-dom'
3
3
 
4
- import { sleep, queryKey, createQueryClient } from './utils'
4
+ import {
5
+ sleep,
6
+ queryKey,
7
+ createQueryClient,
8
+ mockNavigatorOnLine,
9
+ } from './utils'
5
10
  import type {
6
11
  QueryCache,
7
12
  QueryClient,
@@ -11,6 +16,7 @@ import type {
11
16
  import { MutationObserver, QueryObserver } from '..'
12
17
  import { focusManager, onlineManager } from '..'
13
18
  import { noop } from '../utils'
19
+ import { vi } from 'vitest'
14
20
 
15
21
  describe('queryClient', () => {
16
22
  let queryClient: QueryClient
@@ -223,7 +229,7 @@ describe('queryClient', () => {
223
229
  test('should accept an update function', () => {
224
230
  const key = queryKey()
225
231
 
226
- const updater = jest.fn((oldData) => `new data + ${oldData}`)
232
+ const updater = vi.fn((oldData) => `new data + ${oldData}`)
227
233
 
228
234
  queryClient.setQueryData(key, 'test data')
229
235
  queryClient.setQueryData(key, updater)
@@ -802,7 +808,7 @@ describe('queryClient', () => {
802
808
  describe('refetchQueries', () => {
803
809
  test('should not refetch if all observers are disabled', async () => {
804
810
  const key = queryKey()
805
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
811
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
806
812
  await queryClient.fetchQuery({ queryKey: key, queryFn })
807
813
  const observer1 = new QueryObserver(queryClient, {
808
814
  queryKey: key,
@@ -816,7 +822,7 @@ describe('queryClient', () => {
816
822
  })
817
823
  test('should refetch if at least one observer is enabled', async () => {
818
824
  const key = queryKey()
819
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
825
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
820
826
  await queryClient.fetchQuery({ queryKey: key, queryFn })
821
827
  const observer1 = new QueryObserver(queryClient, {
822
828
  queryKey: key,
@@ -838,8 +844,8 @@ describe('queryClient', () => {
838
844
  test('should refetch all queries when no arguments are given', async () => {
839
845
  const key1 = queryKey()
840
846
  const key2 = queryKey()
841
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
842
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
847
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
848
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
843
849
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
844
850
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
845
851
  const observer1 = new QueryObserver(queryClient, {
@@ -864,8 +870,8 @@ describe('queryClient', () => {
864
870
  test('should be able to refetch all fresh queries', async () => {
865
871
  const key1 = queryKey()
866
872
  const key2 = queryKey()
867
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
868
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
873
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
874
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
869
875
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
870
876
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
871
877
  const observer = new QueryObserver(queryClient, {
@@ -883,8 +889,8 @@ describe('queryClient', () => {
883
889
  test('should be able to refetch all stale queries', async () => {
884
890
  const key1 = queryKey()
885
891
  const key2 = queryKey()
886
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
887
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
892
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
893
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
888
894
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
889
895
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
890
896
  const observer = new QueryObserver(queryClient, {
@@ -903,8 +909,8 @@ describe('queryClient', () => {
903
909
  test('should be able to refetch all stale and active queries', async () => {
904
910
  const key1 = queryKey()
905
911
  const key2 = queryKey()
906
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
907
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
912
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
913
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
908
914
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
909
915
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
910
916
  queryClient.invalidateQueries({ queryKey: key1 })
@@ -925,8 +931,8 @@ describe('queryClient', () => {
925
931
  test('should be able to refetch all active and inactive queries', async () => {
926
932
  const key1 = queryKey()
927
933
  const key2 = queryKey()
928
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
929
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
934
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
935
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
930
936
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
931
937
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
932
938
  const observer = new QueryObserver(queryClient, {
@@ -944,8 +950,8 @@ describe('queryClient', () => {
944
950
  test('should be able to refetch all active and inactive queries', async () => {
945
951
  const key1 = queryKey()
946
952
  const key2 = queryKey()
947
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
948
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
953
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
954
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
949
955
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
950
956
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
951
957
  const observer = new QueryObserver(queryClient, {
@@ -963,8 +969,8 @@ describe('queryClient', () => {
963
969
  test('should be able to refetch only active queries', async () => {
964
970
  const key1 = queryKey()
965
971
  const key2 = queryKey()
966
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
967
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
972
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
973
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
968
974
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
969
975
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
970
976
  const observer = new QueryObserver(queryClient, {
@@ -982,8 +988,8 @@ describe('queryClient', () => {
982
988
  test('should be able to refetch only inactive queries', async () => {
983
989
  const key1 = queryKey()
984
990
  const key2 = queryKey()
985
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
986
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
991
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
992
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
987
993
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
988
994
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
989
995
  const observer = new QueryObserver(queryClient, {
@@ -1019,14 +1025,41 @@ describe('queryClient', () => {
1019
1025
  }
1020
1026
  expect(error).toEqual('error')
1021
1027
  })
1028
+
1029
+ test('should resolve Promise immediately if query is paused', async () => {
1030
+ const key1 = queryKey()
1031
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1032
+ await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1033
+ const onlineMock = mockNavigatorOnLine(false)
1034
+
1035
+ await queryClient.refetchQueries({ queryKey: key1 })
1036
+
1037
+ // if we reach this point, the test succeeds because the Promise was resolved immediately
1038
+ expect(queryFn1).toHaveBeenCalledTimes(1)
1039
+ onlineMock.mockRestore()
1040
+ })
1041
+
1042
+ test('should refetch if query we are offline but query networkMode is always', async () => {
1043
+ const key1 = queryKey()
1044
+ queryClient.setQueryDefaults(key1, { networkMode: 'always' })
1045
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1046
+ await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1047
+ const onlineMock = mockNavigatorOnLine(false)
1048
+
1049
+ await queryClient.refetchQueries({ queryKey: key1 })
1050
+
1051
+ // initial fetch + refetch (even though we are offline)
1052
+ expect(queryFn1).toHaveBeenCalledTimes(2)
1053
+ onlineMock.mockRestore()
1054
+ })
1022
1055
  })
1023
1056
 
1024
1057
  describe('invalidateQueries', () => {
1025
1058
  test('should refetch active queries by default', async () => {
1026
1059
  const key1 = queryKey()
1027
1060
  const key2 = queryKey()
1028
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
1029
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
1061
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1062
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
1030
1063
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1031
1064
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
1032
1065
  const observer = new QueryObserver(queryClient, {
@@ -1044,8 +1077,8 @@ describe('queryClient', () => {
1044
1077
  test('should not refetch inactive queries by default', async () => {
1045
1078
  const key1 = queryKey()
1046
1079
  const key2 = queryKey()
1047
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
1048
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
1080
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1081
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
1049
1082
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1050
1083
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
1051
1084
  const observer = new QueryObserver(queryClient, {
@@ -1063,8 +1096,8 @@ describe('queryClient', () => {
1063
1096
  test('should not refetch active queries when "refetch" is "none"', async () => {
1064
1097
  const key1 = queryKey()
1065
1098
  const key2 = queryKey()
1066
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
1067
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
1099
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1100
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
1068
1101
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1069
1102
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
1070
1103
  const observer = new QueryObserver(queryClient, {
@@ -1085,8 +1118,8 @@ describe('queryClient', () => {
1085
1118
  test('should refetch inactive queries when "refetch" is "inactive"', async () => {
1086
1119
  const key1 = queryKey()
1087
1120
  const key2 = queryKey()
1088
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
1089
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
1121
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1122
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
1090
1123
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1091
1124
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
1092
1125
  const observer = new QueryObserver(queryClient, {
@@ -1109,8 +1142,8 @@ describe('queryClient', () => {
1109
1142
  test('should refetch active and inactive queries when "refetch" is "all"', async () => {
1110
1143
  const key1 = queryKey()
1111
1144
  const key2 = queryKey()
1112
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
1113
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
1145
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1146
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
1114
1147
  await queryClient.fetchQuery({ queryKey: key1, queryFn: queryFn1 })
1115
1148
  await queryClient.fetchQuery({ queryKey: key2, queryFn: queryFn2 })
1116
1149
  const observer = new QueryObserver(queryClient, {
@@ -1129,7 +1162,7 @@ describe('queryClient', () => {
1129
1162
 
1130
1163
  test('should cancel ongoing fetches if cancelRefetch option is set (default value)', async () => {
1131
1164
  const key = queryKey()
1132
- const abortFn = jest.fn()
1165
+ const abortFn = vi.fn()
1133
1166
  let fetchCount = 0
1134
1167
  const observer = new QueryObserver(queryClient, {
1135
1168
  queryKey: key,
@@ -1152,7 +1185,7 @@ describe('queryClient', () => {
1152
1185
 
1153
1186
  test('should not cancel ongoing fetches if cancelRefetch option is set to false', async () => {
1154
1187
  const key = queryKey()
1155
- const abortFn = jest.fn()
1188
+ const abortFn = vi.fn()
1156
1189
  let fetchCount = 0
1157
1190
  const observer = new QueryObserver(queryClient, {
1158
1191
  queryKey: key,
@@ -1178,7 +1211,7 @@ describe('queryClient', () => {
1178
1211
  test('should notify listeners when a query is reset', async () => {
1179
1212
  const key = queryKey()
1180
1213
 
1181
- const callback = jest.fn()
1214
+ const callback = vi.fn()
1182
1215
 
1183
1216
  await queryClient.prefetchQuery({ queryKey: key, queryFn: () => 'data' })
1184
1217
 
@@ -1231,8 +1264,8 @@ describe('queryClient', () => {
1231
1264
  test('should refetch all active queries', async () => {
1232
1265
  const key1 = queryKey()
1233
1266
  const key2 = queryKey()
1234
- const queryFn1 = jest.fn<string, unknown[]>().mockReturnValue('data1')
1235
- const queryFn2 = jest.fn<string, unknown[]>().mockReturnValue('data2')
1267
+ const queryFn1 = vi.fn<unknown[], string>().mockReturnValue('data1')
1268
+ const queryFn2 = vi.fn<unknown[], string>().mockReturnValue('data2')
1236
1269
  const observer1 = new QueryObserver(queryClient, {
1237
1270
  queryKey: key1,
1238
1271
  queryFn: queryFn1,
@@ -1258,15 +1291,15 @@ describe('queryClient', () => {
1258
1291
  const testClient = createQueryClient()
1259
1292
  testClient.mount()
1260
1293
 
1261
- const queryCacheOnFocusSpy = jest.spyOn(
1294
+ const queryCacheOnFocusSpy = vi.spyOn(
1262
1295
  testClient.getQueryCache(),
1263
1296
  'onFocus',
1264
1297
  )
1265
- const queryCacheOnOnlineSpy = jest.spyOn(
1298
+ const queryCacheOnOnlineSpy = vi.spyOn(
1266
1299
  testClient.getQueryCache(),
1267
1300
  'onOnline',
1268
1301
  )
1269
- const mutationCacheResumePausedMutationsSpy = jest.spyOn(
1302
+ const mutationCacheResumePausedMutationsSpy = vi.spyOn(
1270
1303
  testClient.getMutationCache(),
1271
1304
  'resumePausedMutations',
1272
1305
  )
@@ -1291,15 +1324,15 @@ describe('queryClient', () => {
1291
1324
  const testClient = createQueryClient()
1292
1325
  testClient.mount()
1293
1326
 
1294
- const queryCacheOnFocusSpy = jest.spyOn(
1327
+ const queryCacheOnFocusSpy = vi.spyOn(
1295
1328
  testClient.getQueryCache(),
1296
1329
  'onFocus',
1297
1330
  )
1298
- const queryCacheOnOnlineSpy = jest.spyOn(
1331
+ const queryCacheOnOnlineSpy = vi.spyOn(
1299
1332
  testClient.getQueryCache(),
1300
1333
  'onOnline',
1301
1334
  )
1302
- const mutationCacheResumePausedMutationsSpy = jest.spyOn(
1335
+ const mutationCacheResumePausedMutationsSpy = vi.spyOn(
1303
1336
  testClient.getMutationCache(),
1304
1337
  'resumePausedMutations',
1305
1338
  )
@@ -1321,7 +1354,7 @@ describe('queryClient', () => {
1321
1354
  })
1322
1355
 
1323
1356
  test('should resume paused mutations when coming online', async () => {
1324
- const consoleMock = jest.spyOn(console, 'error')
1357
+ const consoleMock = vi.spyOn(console, 'error')
1325
1358
  consoleMock.mockImplementation(() => undefined)
1326
1359
  onlineManager.setOnline(false)
1327
1360
 
@@ -1351,7 +1384,7 @@ describe('queryClient', () => {
1351
1384
  })
1352
1385
 
1353
1386
  test('should resume paused mutations one after the other when invoked manually at the same time', async () => {
1354
- const consoleMock = jest.spyOn(console, 'error')
1387
+ const consoleMock = vi.spyOn(console, 'error')
1355
1388
  consoleMock.mockImplementation(() => undefined)
1356
1389
  onlineManager.setOnline(false)
1357
1390
 
@@ -1401,15 +1434,15 @@ describe('queryClient', () => {
1401
1434
  testClient.mount()
1402
1435
  testClient.unmount()
1403
1436
 
1404
- const queryCacheOnFocusSpy = jest.spyOn(
1437
+ const queryCacheOnFocusSpy = vi.spyOn(
1405
1438
  testClient.getQueryCache(),
1406
1439
  'onFocus',
1407
1440
  )
1408
- const queryCacheOnOnlineSpy = jest.spyOn(
1441
+ const queryCacheOnOnlineSpy = vi.spyOn(
1409
1442
  testClient.getQueryCache(),
1410
1443
  'onOnline',
1411
1444
  )
1412
- const mutationCacheResumePausedMutationsSpy = jest.spyOn(
1445
+ const mutationCacheResumePausedMutationsSpy = vi.spyOn(
1413
1446
  testClient.getMutationCache(),
1414
1447
  'resumePausedMutations',
1415
1448
  )
@@ -1436,15 +1469,15 @@ describe('queryClient', () => {
1436
1469
  testClient.unmount()
1437
1470
  testClient.unmount()
1438
1471
 
1439
- const queryCacheOnFocusSpy = jest.spyOn(
1472
+ const queryCacheOnFocusSpy = vi.spyOn(
1440
1473
  testClient.getQueryCache(),
1441
1474
  'onFocus',
1442
1475
  )
1443
- const queryCacheOnOnlineSpy = jest.spyOn(
1476
+ const queryCacheOnOnlineSpy = vi.spyOn(
1444
1477
  testClient.getQueryCache(),
1445
1478
  'onOnline',
1446
1479
  )
1447
- const mutationCacheResumePausedMutationsSpy = jest.spyOn(
1480
+ const mutationCacheResumePausedMutationsSpy = vi.spyOn(
1448
1481
  testClient.getMutationCache(),
1449
1482
  'resumePausedMutations',
1450
1483
  )
@@ -1,6 +1,7 @@
1
1
  import { sleep, queryKey, expectType, createQueryClient } from './utils'
2
2
  import type { QueryClient, QueryObserverResult } from '..'
3
3
  import { QueryObserver, focusManager } from '..'
4
+ import { vi } from 'vitest'
4
5
 
5
6
  describe('queryObserver', () => {
6
7
  let queryClient: QueryClient
@@ -16,7 +17,7 @@ describe('queryObserver', () => {
16
17
 
17
18
  test('should trigger a fetch when subscribed', async () => {
18
19
  const key = queryKey()
19
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
20
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
20
21
  const observer = new QueryObserver(queryClient, { queryKey: key, queryFn })
21
22
  const unsubscribe = observer.subscribe(() => undefined)
22
23
  await sleep(1)
@@ -348,7 +349,7 @@ describe('queryObserver', () => {
348
349
 
349
350
  test('should not trigger a fetch when subscribed and disabled', async () => {
350
351
  const key = queryKey()
351
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
352
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
352
353
  const observer = new QueryObserver(queryClient, {
353
354
  queryKey: key,
354
355
  queryFn,
@@ -362,7 +363,7 @@ describe('queryObserver', () => {
362
363
 
363
364
  test('should not trigger a fetch when not subscribed', async () => {
364
365
  const key = queryKey()
365
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
366
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
366
367
  new QueryObserver(queryClient, { queryKey: key, queryFn })
367
368
  await sleep(1)
368
369
  expect(queryFn).toHaveBeenCalledTimes(0)
@@ -370,8 +371,8 @@ describe('queryObserver', () => {
370
371
 
371
372
  test('should be able to watch a query without defining a query function', async () => {
372
373
  const key = queryKey()
373
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
374
- const callback = jest.fn()
374
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
375
+ const callback = vi.fn()
375
376
  const observer = new QueryObserver(queryClient, {
376
377
  queryKey: key,
377
378
  enabled: false,
@@ -385,7 +386,7 @@ describe('queryObserver', () => {
385
386
 
386
387
  test('should accept unresolved query config in update function', async () => {
387
388
  const key = queryKey()
388
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
389
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
389
390
  const observer = new QueryObserver(queryClient, {
390
391
  queryKey: key,
391
392
  enabled: false,
@@ -407,7 +408,7 @@ describe('queryObserver', () => {
407
408
 
408
409
  test('should be able to handle multiple subscribers', async () => {
409
410
  const key = queryKey()
410
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
411
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
411
412
  const observer = new QueryObserver<string>(queryClient, {
412
413
  queryKey: key,
413
414
  enabled: false,
@@ -567,7 +568,7 @@ describe('queryObserver', () => {
567
568
 
568
569
  test('should not refetch in background if refetchIntervalInBackground is false', async () => {
569
570
  const key = queryKey()
570
- const queryFn = jest.fn<string, unknown[]>().mockReturnValue('data')
571
+ const queryFn = vi.fn<unknown[], string>().mockReturnValue('data')
571
572
 
572
573
  focusManager.setFocused(false)
573
574
  const observer = new QueryObserver(queryClient, {
@@ -690,6 +691,127 @@ describe('queryObserver', () => {
690
691
  expect(observer.getCurrentResult().isPlaceholderData).toBe(false)
691
692
  })
692
693
 
694
+ test('should pass the correct previous queryKey (from prevQuery) to placeholderData function params with select', async () => {
695
+ const results: QueryObserverResult[] = []
696
+ const keys: Array<readonly unknown[] | null> = []
697
+
698
+ const key1 = queryKey()
699
+ const key2 = queryKey()
700
+
701
+ const data1 = { value: 'data1' }
702
+ const data2 = { value: 'data2' }
703
+
704
+ const observer = new QueryObserver(queryClient, {
705
+ queryKey: key1,
706
+ queryFn: () => data1,
707
+ placeholderData: (prev, prevQuery) => {
708
+ keys.push(prevQuery?.queryKey || null)
709
+ return prev
710
+ },
711
+ select: (data) => data.value,
712
+ })
713
+
714
+ const unsubscribe = observer.subscribe((result) => {
715
+ results.push(result)
716
+ })
717
+
718
+ await sleep(1)
719
+
720
+ observer.setOptions({
721
+ queryKey: key2,
722
+ queryFn: () => data2,
723
+ placeholderData: (prev, prevQuery) => {
724
+ keys.push(prevQuery?.queryKey || null)
725
+ return prev
726
+ },
727
+ select: (data) => data.value,
728
+ })
729
+
730
+ await sleep(1)
731
+ unsubscribe()
732
+ expect(results.length).toBe(4)
733
+ expect(keys.length).toBe(3)
734
+ expect(keys[0]).toBe(null) // First Query - status: 'pending', fetchStatus: 'idle'
735
+ expect(keys[1]).toBe(null) // First Query - status: 'pending', fetchStatus: 'fetching'
736
+ expect(keys[2]).toBe(key1) // Second Query - status: 'pending', fetchStatus: 'fetching'
737
+
738
+ expect(results[0]).toMatchObject({
739
+ data: undefined,
740
+ status: 'pending',
741
+ fetchStatus: 'fetching',
742
+ }) // Initial fetch
743
+ expect(results[1]).toMatchObject({
744
+ data: 'data1',
745
+ status: 'success',
746
+ fetchStatus: 'idle',
747
+ }) // Successful fetch
748
+ expect(results[2]).toMatchObject({
749
+ data: 'data1',
750
+ status: 'success',
751
+ fetchStatus: 'fetching',
752
+ }) // Fetch for new key, but using previous data as placeholder
753
+ expect(results[3]).toMatchObject({
754
+ data: 'data2',
755
+ status: 'success',
756
+ fetchStatus: 'idle',
757
+ }) // Successful fetch for new key
758
+ })
759
+
760
+ test('should pass the correct previous data to placeholderData function params when select function is used in conjunction', async () => {
761
+ const results: QueryObserverResult[] = []
762
+
763
+ const key1 = queryKey()
764
+ const key2 = queryKey()
765
+
766
+ const data1 = { value: 'data1' }
767
+ const data2 = { value: 'data2' }
768
+
769
+ const observer = new QueryObserver(queryClient, {
770
+ queryKey: key1,
771
+ queryFn: () => data1,
772
+ placeholderData: (prev) => prev,
773
+ select: (data) => data.value,
774
+ })
775
+
776
+ const unsubscribe = observer.subscribe((result) => {
777
+ results.push(result)
778
+ })
779
+
780
+ await sleep(1)
781
+
782
+ observer.setOptions({
783
+ queryKey: key2,
784
+ queryFn: () => data2,
785
+ placeholderData: (prev) => prev,
786
+ select: (data) => data.value,
787
+ })
788
+
789
+ await sleep(1)
790
+ unsubscribe()
791
+
792
+ expect(results.length).toBe(4)
793
+ expect(results[0]).toMatchObject({
794
+ data: undefined,
795
+ status: 'pending',
796
+ fetchStatus: 'fetching',
797
+ }) // Initial fetch
798
+ expect(results[1]).toMatchObject({
799
+ data: 'data1',
800
+ status: 'success',
801
+ fetchStatus: 'idle',
802
+ }) // Successful fetch
803
+ expect(results[2]).toMatchObject({
804
+ data: 'data1',
805
+ status: 'success',
806
+ fetchStatus: 'fetching',
807
+ }) // Fetch for new key, but using previous data as placeholder
808
+ expect(results[3]).toMatchObject({
809
+ data: 'data2',
810
+ status: 'success',
811
+ fetchStatus: 'idle',
812
+ }) // Successful fetch for new key
813
+ })
814
+
693
815
  test('setOptions should notify cache listeners', async () => {
694
816
  const key = queryKey()
695
817
 
@@ -697,7 +819,7 @@ describe('queryObserver', () => {
697
819
  queryKey: key,
698
820
  })
699
821
 
700
- const spy = jest.fn()
822
+ const spy = vi.fn()
701
823
  const unsubscribe = queryClient.getQueryCache().subscribe(spy)
702
824
  observer.setOptions({ enabled: false })
703
825
 
@@ -11,6 +11,7 @@ import {
11
11
  } from '../utils'
12
12
  import { Mutation } from '../mutation'
13
13
  import { createQueryClient } from './utils'
14
+ import { vi } from 'vitest'
14
15
 
15
16
  describe('core/utils', () => {
16
17
  describe('isPlainObject', () => {
@@ -343,7 +344,7 @@ describe('core/utils', () => {
343
344
 
344
345
  describe('scheduleMicrotask', () => {
345
346
  it('should defer execution of callback', async () => {
346
- const callback = jest.fn()
347
+ const callback = vi.fn()
347
348
 
348
349
  scheduleMicrotask(callback)
349
350
  expect(callback).not.toHaveBeenCalled()
@@ -1,7 +1,8 @@
1
1
  import { act } from '@testing-library/react'
2
+ import { vi } from 'vitest'
2
3
 
3
- import type { MutationOptions, QueryClientConfig } from '@tanstack/query-core'
4
- import { QueryClient } from '@tanstack/query-core'
4
+ import type { MutationOptions, QueryClientConfig } from '..'
5
+ import { QueryClient } from '..'
5
6
  import * as utils from '../utils'
6
7
 
7
8
  export function createQueryClient(config?: QueryClientConfig): QueryClient {
@@ -9,11 +10,11 @@ export function createQueryClient(config?: QueryClientConfig): QueryClient {
9
10
  }
10
11
 
11
12
  export function mockVisibilityState(value: DocumentVisibilityState) {
12
- return jest.spyOn(document, 'visibilityState', 'get').mockReturnValue(value)
13
+ return vi.spyOn(document, 'visibilityState', 'get').mockReturnValue(value)
13
14
  }
14
15
 
15
16
  export function mockNavigatorOnLine(value: boolean) {
16
- return jest.spyOn(navigator, 'onLine', 'get').mockReturnValue(value)
17
+ return vi.spyOn(navigator, 'onLine', 'get').mockReturnValue(value)
17
18
  }
18
19
 
19
20
  let queryKeyCount = 0