@tanstack/vue-query 5.0.0-alpha.7 → 5.0.0-alpha.71

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 (270) hide show
  1. package/README.md +18 -14
  2. package/build/lib/__mocks__/useBaseQuery.d.ts +1 -0
  3. package/build/lib/__mocks__/useBaseQuery.d.ts.map +1 -0
  4. package/build/lib/__mocks__/useQueryClient.d.ts +1 -0
  5. package/build/lib/__mocks__/useQueryClient.d.ts.map +1 -0
  6. package/build/lib/__tests__/mutationCache.test.d.ts +1 -0
  7. package/build/lib/__tests__/mutationCache.test.d.ts.map +1 -0
  8. package/build/lib/__tests__/queryCache.test.d.ts +1 -0
  9. package/build/lib/__tests__/queryCache.test.d.ts.map +1 -0
  10. package/build/lib/__tests__/queryClient.test.d.ts +1 -0
  11. package/build/lib/__tests__/queryClient.test.d.ts.map +1 -0
  12. package/build/lib/__tests__/test-utils.d.ts +3 -2
  13. package/build/lib/__tests__/test-utils.d.ts.map +1 -0
  14. package/build/lib/__tests__/useInfiniteQuery.test.d.ts +1 -0
  15. package/build/lib/__tests__/useInfiniteQuery.test.d.ts.map +1 -0
  16. package/build/lib/__tests__/useInfiniteQuery.types.test.d.ts +1 -0
  17. package/build/lib/__tests__/useInfiniteQuery.types.test.d.ts.map +1 -0
  18. package/build/lib/__tests__/useIsFetching.test.d.ts +1 -0
  19. package/build/lib/__tests__/useIsFetching.test.d.ts.map +1 -0
  20. package/build/lib/__tests__/useIsMutating.test.d.ts +1 -0
  21. package/build/lib/__tests__/useIsMutating.test.d.ts.map +1 -0
  22. package/build/lib/__tests__/useMutation.test.d.ts +1 -0
  23. package/build/lib/__tests__/useMutation.test.d.ts.map +1 -0
  24. package/build/lib/__tests__/useMutation.types.test.d.ts +1 -0
  25. package/build/lib/__tests__/useMutation.types.test.d.ts.map +1 -0
  26. package/build/lib/__tests__/useQueries.test.d.ts +1 -0
  27. package/build/lib/__tests__/useQueries.test.d.ts.map +1 -0
  28. package/build/lib/__tests__/useQuery.test.d.ts +1 -0
  29. package/build/lib/__tests__/useQuery.test.d.ts.map +1 -0
  30. package/build/lib/__tests__/useQuery.types.test.d.ts +1 -0
  31. package/build/lib/__tests__/useQuery.types.test.d.ts.map +1 -0
  32. package/build/lib/__tests__/useQueryClient.test.d.ts +1 -0
  33. package/build/lib/__tests__/useQueryClient.test.d.ts.map +1 -0
  34. package/build/lib/__tests__/utils.test.d.ts +1 -0
  35. package/build/lib/__tests__/utils.test.d.ts.map +1 -0
  36. package/build/lib/__tests__/vueQueryPlugin.test.d.ts +1 -0
  37. package/build/lib/__tests__/vueQueryPlugin.test.d.ts.map +1 -0
  38. package/build/lib/devtools/{devtools.mjs → devtools.cjs} +62 -20
  39. package/build/lib/devtools/devtools.cjs.map +1 -0
  40. package/build/lib/devtools/devtools.d.ts +1 -0
  41. package/build/lib/devtools/devtools.d.ts.map +1 -0
  42. package/build/lib/devtools/devtools.js +61 -25
  43. package/build/lib/devtools/devtools.js.map +1 -1
  44. package/build/lib/devtools/devtools.legacy.cjs +198 -0
  45. package/build/lib/devtools/devtools.legacy.cjs.map +1 -0
  46. package/build/lib/devtools/{devtools.esm.js → devtools.legacy.js} +48 -8
  47. package/build/lib/devtools/devtools.legacy.js.map +1 -0
  48. package/build/lib/devtools/{utils.mjs → utils.cjs} +11 -5
  49. package/build/lib/devtools/{utils.mjs.map → utils.cjs.map} +1 -1
  50. package/build/lib/devtools/utils.d.ts +2 -1
  51. package/build/lib/devtools/utils.d.ts.map +1 -0
  52. package/build/lib/devtools/utils.js +4 -10
  53. package/build/lib/devtools/utils.js.map +1 -1
  54. package/build/lib/devtools/utils.legacy.cjs +85 -0
  55. package/build/lib/devtools/utils.legacy.cjs.map +1 -0
  56. package/build/lib/devtools/{utils.esm.js → utils.legacy.js} +4 -4
  57. package/build/lib/devtools/utils.legacy.js.map +1 -0
  58. package/build/lib/index.cjs +38 -0
  59. package/build/lib/index.cjs.map +1 -0
  60. package/build/lib/index.d.ts +1 -0
  61. package/build/lib/index.d.ts.map +1 -0
  62. package/build/lib/index.js +13 -37
  63. package/build/lib/index.js.map +1 -1
  64. package/build/lib/index.legacy.cjs +38 -0
  65. package/build/lib/index.legacy.cjs.map +1 -0
  66. package/build/lib/index.legacy.js +14 -0
  67. package/build/lib/index.legacy.js.map +1 -0
  68. package/build/lib/mutationCache.cjs +16 -0
  69. package/build/lib/{mutationCache.mjs.map → mutationCache.cjs.map} +1 -1
  70. package/build/lib/mutationCache.d.ts +1 -0
  71. package/build/lib/mutationCache.d.ts.map +1 -0
  72. package/build/lib/mutationCache.js +6 -8
  73. package/build/lib/mutationCache.js.map +1 -1
  74. package/build/lib/mutationCache.legacy.cjs +16 -0
  75. package/build/lib/mutationCache.legacy.cjs.map +1 -0
  76. package/build/lib/{mutationCache.esm.js → mutationCache.legacy.js} +2 -2
  77. package/build/lib/mutationCache.legacy.js.map +1 -0
  78. package/build/lib/queryCache.cjs +16 -0
  79. package/build/lib/{queryCache.mjs.map → queryCache.cjs.map} +1 -1
  80. package/build/lib/queryCache.d.ts +1 -0
  81. package/build/lib/queryCache.d.ts.map +1 -0
  82. package/build/lib/queryCache.js +6 -8
  83. package/build/lib/queryCache.js.map +1 -1
  84. package/build/lib/queryCache.legacy.cjs +16 -0
  85. package/build/lib/queryCache.legacy.cjs.map +1 -0
  86. package/build/lib/{queryCache.esm.js → queryCache.legacy.js} +2 -2
  87. package/build/lib/queryCache.legacy.js.map +1 -0
  88. package/build/lib/queryClient.cjs +86 -0
  89. package/build/lib/{queryClient.mjs.map → queryClient.cjs.map} +1 -1
  90. package/build/lib/queryClient.d.ts +1 -0
  91. package/build/lib/queryClient.d.ts.map +1 -0
  92. package/build/lib/queryClient.js +32 -34
  93. package/build/lib/queryClient.js.map +1 -1
  94. package/build/lib/queryClient.legacy.cjs +86 -0
  95. package/build/lib/queryClient.legacy.cjs.map +1 -0
  96. package/build/lib/{queryClient.esm.js → queryClient.legacy.js} +4 -4
  97. package/build/lib/queryClient.legacy.js.map +1 -0
  98. package/build/lib/types.d.ts +4 -3
  99. package/build/lib/types.d.ts.map +1 -0
  100. package/build/lib/{useBaseQuery.mjs → useBaseQuery.cjs} +19 -17
  101. package/build/lib/{useBaseQuery.mjs.map → useBaseQuery.cjs.map} +1 -1
  102. package/build/lib/useBaseQuery.d.ts +3 -2
  103. package/build/lib/useBaseQuery.d.ts.map +1 -0
  104. package/build/lib/useBaseQuery.js +16 -18
  105. package/build/lib/useBaseQuery.js.map +1 -1
  106. package/build/lib/useBaseQuery.legacy.cjs +69 -0
  107. package/build/lib/useBaseQuery.legacy.cjs.map +1 -0
  108. package/build/lib/{useBaseQuery.esm.js → useBaseQuery.legacy.js} +3 -3
  109. package/build/lib/useBaseQuery.legacy.js.map +1 -0
  110. package/build/lib/{useInfiniteQuery.mjs → useInfiniteQuery.cjs} +8 -6
  111. package/build/lib/{useInfiniteQuery.mjs.map → useInfiniteQuery.cjs.map} +1 -1
  112. package/build/lib/useInfiniteQuery.d.ts +4 -3
  113. package/build/lib/useInfiniteQuery.d.ts.map +1 -0
  114. package/build/lib/useInfiniteQuery.js +5 -7
  115. package/build/lib/useInfiniteQuery.js.map +1 -1
  116. package/build/lib/useInfiniteQuery.legacy.cjs +20 -0
  117. package/build/lib/useInfiniteQuery.legacy.cjs.map +1 -0
  118. package/build/lib/{useInfiniteQuery.esm.js → useInfiniteQuery.legacy.js} +2 -2
  119. package/build/lib/useInfiniteQuery.legacy.js.map +1 -0
  120. package/build/lib/useIsFetching.cjs +26 -0
  121. package/build/lib/{useIsFetching.mjs.map → useIsFetching.cjs.map} +1 -1
  122. package/build/lib/useIsFetching.d.ts +2 -1
  123. package/build/lib/useIsFetching.d.ts.map +1 -0
  124. package/build/lib/useIsFetching.js +9 -11
  125. package/build/lib/useIsFetching.js.map +1 -1
  126. package/build/lib/useIsFetching.legacy.cjs +26 -0
  127. package/build/lib/useIsFetching.legacy.cjs.map +1 -0
  128. package/build/lib/{useIsFetching.mjs → useIsFetching.legacy.js} +3 -3
  129. package/build/lib/useIsFetching.legacy.js.map +1 -0
  130. package/build/lib/useMutation.cjs +41 -0
  131. package/build/lib/{useMutation.mjs.map → useMutation.cjs.map} +1 -1
  132. package/build/lib/useMutation.d.ts +5 -4
  133. package/build/lib/useMutation.d.ts.map +1 -0
  134. package/build/lib/useMutation.js +14 -16
  135. package/build/lib/useMutation.js.map +1 -1
  136. package/build/lib/useMutation.legacy.cjs +41 -0
  137. package/build/lib/useMutation.legacy.cjs.map +1 -0
  138. package/build/lib/{useMutation.esm.js → useMutation.legacy.js} +3 -3
  139. package/build/lib/useMutation.legacy.js.map +1 -0
  140. package/build/lib/useMutationState.cjs +43 -0
  141. package/build/lib/useMutationState.cjs.map +1 -0
  142. package/build/lib/useMutationState.d.ts +5 -4
  143. package/build/lib/useMutationState.d.ts.map +1 -0
  144. package/build/lib/useMutationState.js +20 -16
  145. package/build/lib/useMutationState.js.map +1 -1
  146. package/build/lib/useMutationState.legacy.cjs +43 -0
  147. package/build/lib/useMutationState.legacy.cjs.map +1 -0
  148. package/build/lib/{useMutationState.esm.js → useMutationState.legacy.js} +13 -6
  149. package/build/lib/useMutationState.legacy.js.map +1 -0
  150. package/build/lib/useQueries.cjs +62 -0
  151. package/build/lib/useQueries.cjs.map +1 -0
  152. package/build/lib/useQueries.d.ts +12 -11
  153. package/build/lib/useQueries.d.ts.map +1 -0
  154. package/build/lib/useQueries.js +34 -22
  155. package/build/lib/useQueries.js.map +1 -1
  156. package/build/lib/useQueries.legacy.cjs +62 -0
  157. package/build/lib/useQueries.legacy.cjs.map +1 -0
  158. package/build/lib/useQueries.legacy.js +60 -0
  159. package/build/lib/useQueries.legacy.js.map +1 -0
  160. package/build/lib/useQuery.cjs +15 -0
  161. package/build/lib/{useQuery.mjs.map → useQuery.cjs.map} +1 -1
  162. package/build/lib/useQuery.d.ts +4 -3
  163. package/build/lib/useQuery.d.ts.map +1 -0
  164. package/build/lib/useQuery.js +4 -6
  165. package/build/lib/useQuery.js.map +1 -1
  166. package/build/lib/useQuery.legacy.cjs +15 -0
  167. package/build/lib/useQuery.legacy.cjs.map +1 -0
  168. package/build/lib/{useQuery.esm.js → useQuery.legacy.js} +2 -2
  169. package/build/lib/useQuery.legacy.js.map +1 -0
  170. package/build/lib/{useQueryClient.mjs → useQueryClient.cjs} +9 -7
  171. package/build/lib/{useQueryClient.mjs.map → useQueryClient.cjs.map} +1 -1
  172. package/build/lib/useQueryClient.d.ts +1 -0
  173. package/build/lib/useQueryClient.d.ts.map +1 -0
  174. package/build/lib/useQueryClient.js +6 -9
  175. package/build/lib/useQueryClient.js.map +1 -1
  176. package/build/lib/useQueryClient.legacy.cjs +21 -0
  177. package/build/lib/useQueryClient.legacy.cjs.map +1 -0
  178. package/build/lib/{useQueryClient.esm.js → useQueryClient.legacy.js} +2 -2
  179. package/build/lib/useQueryClient.legacy.js.map +1 -0
  180. package/build/lib/{utils.mjs → utils.cjs} +12 -6
  181. package/build/lib/{utils.mjs.map → utils.cjs.map} +1 -1
  182. package/build/lib/utils.d.ts +1 -0
  183. package/build/lib/utils.d.ts.map +1 -0
  184. package/build/lib/utils.js +5 -11
  185. package/build/lib/utils.js.map +1 -1
  186. package/build/lib/utils.legacy.cjs +56 -0
  187. package/build/lib/utils.legacy.cjs.map +1 -0
  188. package/build/lib/{utils.esm.js → utils.legacy.js} +1 -1
  189. package/build/lib/utils.legacy.js.map +1 -0
  190. package/build/lib/{vueQueryPlugin.esm.js → vueQueryPlugin.cjs} +15 -13
  191. package/build/lib/{vueQueryPlugin.mjs.map → vueQueryPlugin.cjs.map} +1 -1
  192. package/build/lib/vueQueryPlugin.d.ts +3 -2
  193. package/build/lib/vueQueryPlugin.d.ts.map +1 -0
  194. package/build/lib/vueQueryPlugin.js +12 -14
  195. package/build/lib/vueQueryPlugin.js.map +1 -1
  196. package/build/lib/vueQueryPlugin.legacy.cjs +75 -0
  197. package/build/lib/vueQueryPlugin.legacy.cjs.map +1 -0
  198. package/build/lib/{vueQueryPlugin.mjs → vueQueryPlugin.legacy.js} +4 -4
  199. package/build/lib/vueQueryPlugin.legacy.js.map +1 -0
  200. package/package.json +20 -15
  201. package/src/__mocks__/useBaseQuery.ts +8 -0
  202. package/src/__mocks__/useQueryClient.ts +10 -0
  203. package/src/__tests__/mutationCache.test.ts +40 -0
  204. package/src/__tests__/queryCache.test.ts +48 -0
  205. package/src/__tests__/queryClient.test.ts +365 -0
  206. package/src/__tests__/test-utils.ts +62 -0
  207. package/src/__tests__/useInfiniteQuery.test.ts +37 -0
  208. package/src/__tests__/useInfiniteQuery.types.test.tsx +102 -0
  209. package/src/__tests__/useIsFetching.test.ts +77 -0
  210. package/src/__tests__/useIsMutating.test.ts +123 -0
  211. package/src/__tests__/useMutation.test.ts +335 -0
  212. package/src/__tests__/useMutation.types.test.tsx +97 -0
  213. package/src/__tests__/useQueries.test.ts +256 -0
  214. package/src/__tests__/useQuery.test.ts +290 -0
  215. package/src/__tests__/useQuery.types.test.tsx +88 -0
  216. package/src/__tests__/useQueryClient.test.ts +51 -0
  217. package/src/__tests__/utils.test.ts +148 -0
  218. package/src/__tests__/vueQueryPlugin.test.ts +351 -0
  219. package/src/devtools/devtools.ts +249 -0
  220. package/src/devtools/utils.ts +96 -0
  221. package/src/index.ts +30 -0
  222. package/src/mutationCache.ts +25 -0
  223. package/src/queryCache.ts +21 -0
  224. package/src/queryClient.ts +278 -0
  225. package/src/types.ts +17 -0
  226. package/src/useBaseQuery.ts +152 -0
  227. package/src/useInfiniteQuery.ts +105 -0
  228. package/src/useIsFetching.ts +37 -0
  229. package/src/useMutation.ts +109 -0
  230. package/src/useMutationState.ts +81 -0
  231. package/src/useQueries.ts +227 -0
  232. package/src/useQuery.ts +125 -0
  233. package/src/useQueryClient.ts +23 -0
  234. package/src/utils.ts +67 -0
  235. package/src/vueQueryPlugin.ts +101 -0
  236. package/build/lib/devtools/devtools.esm.js.map +0 -1
  237. package/build/lib/devtools/devtools.mjs.map +0 -1
  238. package/build/lib/devtools/utils.esm.js.map +0 -1
  239. package/build/lib/index.esm.js +0 -14
  240. package/build/lib/index.esm.js.map +0 -1
  241. package/build/lib/index.mjs +0 -14
  242. package/build/lib/index.mjs.map +0 -1
  243. package/build/lib/mutationCache.esm.js.map +0 -1
  244. package/build/lib/mutationCache.mjs +0 -14
  245. package/build/lib/queryCache.esm.js.map +0 -1
  246. package/build/lib/queryCache.mjs +0 -14
  247. package/build/lib/queryClient.esm.js.map +0 -1
  248. package/build/lib/queryClient.mjs +0 -84
  249. package/build/lib/useBaseQuery.esm.js.map +0 -1
  250. package/build/lib/useInfiniteQuery.esm.js.map +0 -1
  251. package/build/lib/useIsFetching.esm.js +0 -24
  252. package/build/lib/useIsFetching.esm.js.map +0 -1
  253. package/build/lib/useMutation.esm.js.map +0 -1
  254. package/build/lib/useMutation.mjs +0 -39
  255. package/build/lib/useMutationState.esm.js.map +0 -1
  256. package/build/lib/useMutationState.mjs +0 -33
  257. package/build/lib/useMutationState.mjs.map +0 -1
  258. package/build/lib/useQueries.esm.js +0 -46
  259. package/build/lib/useQueries.esm.js.map +0 -1
  260. package/build/lib/useQueries.mjs +0 -46
  261. package/build/lib/useQueries.mjs.map +0 -1
  262. package/build/lib/useQuery.esm.js.map +0 -1
  263. package/build/lib/useQuery.mjs +0 -13
  264. package/build/lib/useQueryClient.esm.js.map +0 -1
  265. package/build/lib/utils.esm.js.map +0 -1
  266. package/build/lib/vueQueryPlugin.esm.js.map +0 -1
  267. package/build/umd/index.development.js +0 -4199
  268. package/build/umd/index.development.js.map +0 -1
  269. package/build/umd/index.production.js +0 -2
  270. package/build/umd/index.production.js.map +0 -1
@@ -0,0 +1,88 @@
1
+ import { reactive } from 'vue'
2
+ import { useQuery } from '../useQuery'
3
+ import { doNotExecute, simpleFetcher } from './test-utils'
4
+ import type { Equal, Expect } from './test-utils'
5
+
6
+ describe('Discriminated union return type', () => {
7
+ it('data should be possibly undefined by default', () => {
8
+ doNotExecute(() => {
9
+ const query = reactive(
10
+ useQuery({
11
+ queryKey: ['key'],
12
+ queryFn: simpleFetcher,
13
+ }),
14
+ )
15
+
16
+ const result: Expect<Equal<string | undefined, typeof query.data>> = true
17
+ return result
18
+ })
19
+ })
20
+
21
+ it('data should be defined when query is success', () => {
22
+ doNotExecute(() => {
23
+ const query = reactive(
24
+ useQuery({
25
+ queryKey: ['key'],
26
+ queryFn: simpleFetcher,
27
+ }),
28
+ )
29
+
30
+ if (query.isSuccess) {
31
+ const result: Expect<Equal<string, typeof query.data>> = true
32
+ return result
33
+ }
34
+ return
35
+ })
36
+ })
37
+
38
+ it('error should be null when query is success', () => {
39
+ doNotExecute(() => {
40
+ const query = reactive(
41
+ useQuery({
42
+ queryKey: ['key'],
43
+ queryFn: simpleFetcher,
44
+ }),
45
+ )
46
+
47
+ if (query.isSuccess) {
48
+ const result: Expect<Equal<null, typeof query.error>> = true
49
+ return result
50
+ }
51
+ return
52
+ })
53
+ })
54
+
55
+ it('data should be undefined when query is pending', () => {
56
+ doNotExecute(() => {
57
+ const query = reactive(
58
+ useQuery({
59
+ queryKey: ['key'],
60
+ queryFn: simpleFetcher,
61
+ }),
62
+ )
63
+
64
+ if (query.isPending) {
65
+ const result: Expect<Equal<undefined, typeof query.data>> = true
66
+ return result
67
+ }
68
+ return
69
+ })
70
+ })
71
+
72
+ it('error should be defined when query is error', () => {
73
+ doNotExecute(() => {
74
+ const query = reactive(
75
+ useQuery({
76
+ queryKey: ['key'],
77
+ queryFn: simpleFetcher,
78
+ }),
79
+ )
80
+
81
+ if (query.isError) {
82
+ const result: Expect<Equal<Error, typeof query.error>> = true
83
+ return result
84
+ }
85
+ return
86
+ })
87
+ })
88
+ })
@@ -0,0 +1,51 @@
1
+ import { getCurrentInstance, inject } from 'vue-demi'
2
+ import { useQueryClient } from '../useQueryClient'
3
+ import { VUE_QUERY_CLIENT } from '../utils'
4
+ import { vi } from 'vitest'
5
+ import type { Mock } from 'vitest'
6
+
7
+ describe('useQueryClient', () => {
8
+ const injectSpy = inject as Mock
9
+ const getCurrentInstanceSpy = getCurrentInstance as Mock
10
+
11
+ beforeEach(() => {
12
+ vi.restoreAllMocks()
13
+ })
14
+
15
+ test('should return queryClient when it is provided in the context', () => {
16
+ const queryClientMock = { name: 'Mocked client' }
17
+ injectSpy.mockReturnValueOnce(queryClientMock)
18
+
19
+ const queryClient = useQueryClient()
20
+
21
+ expect(queryClient).toStrictEqual(queryClientMock)
22
+ expect(injectSpy).toHaveBeenCalledTimes(1)
23
+ expect(injectSpy).toHaveBeenCalledWith(VUE_QUERY_CLIENT)
24
+ })
25
+
26
+ test('should throw an error when queryClient does not exist in the context', () => {
27
+ injectSpy.mockReturnValueOnce(undefined)
28
+
29
+ expect(useQueryClient).toThrowError()
30
+ expect(injectSpy).toHaveBeenCalledTimes(1)
31
+ expect(injectSpy).toHaveBeenCalledWith(VUE_QUERY_CLIENT)
32
+ })
33
+
34
+ test('should throw an error when used outside of setup function', () => {
35
+ getCurrentInstanceSpy.mockReturnValueOnce(undefined)
36
+
37
+ expect(useQueryClient).toThrowError()
38
+ expect(getCurrentInstanceSpy).toHaveBeenCalledTimes(1)
39
+ })
40
+
41
+ test('should call inject with a custom key as a suffix', () => {
42
+ const queryClientKey = 'foo'
43
+ const expectedKeyParameter = `${VUE_QUERY_CLIENT}:${queryClientKey}`
44
+ const queryClientMock = { name: 'Mocked client' }
45
+ injectSpy.mockReturnValueOnce(queryClientMock)
46
+
47
+ useQueryClient(queryClientKey)
48
+
49
+ expect(injectSpy).toHaveBeenCalledWith(expectedKeyParameter)
50
+ })
51
+ })
@@ -0,0 +1,148 @@
1
+ import { updateState, cloneDeep, cloneDeepUnref } from '../utils'
2
+ import { reactive, ref } from 'vue-demi'
3
+
4
+ describe('utils', () => {
5
+ describe('updateState', () => {
6
+ test('should update first object with values from the second one', () => {
7
+ const origin = { option1: 'a', option2: 'b', option3: 'c' }
8
+ const update = { option1: 'x', option2: 'y', option3: 'z' }
9
+ const expected = { option1: 'x', option2: 'y', option3: 'z' }
10
+
11
+ updateState(origin, update)
12
+ expect(origin).toEqual(expected)
13
+ })
14
+
15
+ test('should update only existing keys', () => {
16
+ const origin = { option1: 'a', option2: 'b' }
17
+ const update = { option1: 'x', option2: 'y', option3: 'z' }
18
+ const expected = { option1: 'x', option2: 'y' }
19
+
20
+ updateState(origin, update)
21
+ expect(origin).toEqual(expected)
22
+ })
23
+
24
+ test('should remove non existing keys', () => {
25
+ const origin = { option1: 'a', option2: 'b', option3: 'c' }
26
+ const update = { option1: 'x', option2: 'y' }
27
+ const expected = { option1: 'x', option2: 'y' }
28
+
29
+ updateState(origin, update)
30
+ expect(origin).toEqual(expected)
31
+ })
32
+ })
33
+
34
+ describe('cloneDeep', () => {
35
+ test('should copy primitives and functions AS-IS', () => {
36
+ expect(cloneDeep(3456)).toBe(3456)
37
+ expect(cloneDeep('theString')).toBe('theString')
38
+ expect(cloneDeep(null)).toBe(null)
39
+ })
40
+
41
+ test('should copy Maps and Sets AS-IS', () => {
42
+ const setVal = new Set([3, 4, 5])
43
+ const setValCopy = cloneDeep(setVal)
44
+ expect(setValCopy).toBe(setVal)
45
+ expect(setValCopy).toStrictEqual(new Set([3, 4, 5]))
46
+
47
+ const mapVal = new Map([
48
+ ['a', 'aVal'],
49
+ ['b', 'bVal'],
50
+ ])
51
+ const mapValCopy = cloneDeep(mapVal)
52
+ expect(mapValCopy).toBe(mapVal)
53
+ expect(mapValCopy).toStrictEqual(
54
+ new Map([
55
+ ['a', 'aVal'],
56
+ ['b', 'bVal'],
57
+ ]),
58
+ )
59
+ })
60
+
61
+ test('should deeply copy arrays', () => {
62
+ const val = [
63
+ 25,
64
+ 'str',
65
+ null,
66
+ new Set([3, 4]),
67
+ [5, 6, { a: 1 }],
68
+ undefined,
69
+ ]
70
+ const cp = cloneDeep(val)
71
+ expect(cp).toStrictEqual([
72
+ 25,
73
+ 'str',
74
+ null,
75
+ new Set([3, 4]),
76
+ [5, 6, { a: 1 }],
77
+ undefined,
78
+ ])
79
+ expect(cp).not.toBe(val)
80
+ expect(cp[3]).toBe(val[3]) // Set([3, 4])
81
+ expect(cp[4]).not.toBe(val[4]) // [5, 6, { a: 1 }]
82
+ expect((cp[4] as number[])[2]).not.toBe((val[4] as number[])[2]) // { a : 1 }
83
+ })
84
+
85
+ test('should deeply copy object', () => {
86
+ const val = reactive({
87
+ a: 25,
88
+ b: 'str',
89
+ c: null,
90
+ d: undefined,
91
+ e: new Set([5, 6]),
92
+ f: [3, 4],
93
+ g: { fa: 26 },
94
+ })
95
+ const cp = cloneDeep(val)
96
+
97
+ expect(cp).toStrictEqual({
98
+ a: 25,
99
+ b: 'str',
100
+ c: null,
101
+ d: undefined,
102
+ e: new Set([5, 6]),
103
+ f: [3, 4],
104
+ g: { fa: 26 },
105
+ })
106
+
107
+ expect(cp.e).toBe(val.e) // Set
108
+ expect(cp.f).not.toBe(val.f) // []
109
+ expect(cp.g).not.toBe(val.g) // {}
110
+ })
111
+ })
112
+
113
+ describe('cloneDeepUnref', () => {
114
+ test('should unref primitives', () => {
115
+ expect(cloneDeepUnref(ref(34))).toBe(34)
116
+ expect(cloneDeepUnref(ref('mystr'))).toBe('mystr')
117
+ })
118
+
119
+ test('should deeply unref arrays', () => {
120
+ const val = ref([2, 3, ref(4), ref('5'), { a: ref(6) }, [ref(7)]])
121
+ const cp = cloneDeepUnref(val)
122
+ expect(cp).toStrictEqual([2, 3, 4, '5', { a: 6 }, [7]])
123
+ })
124
+
125
+ test('should deeply unref objects', () => {
126
+ const val = ref({
127
+ a: 1,
128
+ b: ref(2),
129
+ c: [ref('c1'), ref(['c2'])],
130
+ d: {
131
+ e: ref('e'),
132
+ },
133
+ })
134
+ const cp = cloneDeepUnref(val)
135
+
136
+ expect(cp).toEqual({
137
+ a: 1,
138
+ b: 2,
139
+ c: ['c1', ['c2']],
140
+ d: { e: 'e' },
141
+ })
142
+ })
143
+
144
+ test('should unref undefined', () => {
145
+ expect(cloneDeepUnref(ref(undefined))).toBe(undefined)
146
+ })
147
+ })
148
+ })
@@ -0,0 +1,351 @@
1
+ import type { App, ComponentOptions } from 'vue'
2
+ import { isVue2, isVue3, ref } from 'vue-demi'
3
+
4
+ import { QueryClient } from '../queryClient'
5
+ import { VueQueryPlugin } from '../vueQueryPlugin'
6
+ import { VUE_QUERY_CLIENT } from '../utils'
7
+ import { setupDevtools } from '../devtools/devtools'
8
+ import { flushPromises } from './test-utils'
9
+ import { useQuery } from '../useQuery'
10
+ import { useQueries } from '../useQueries'
11
+ import { vi } from 'vitest'
12
+ import type { Mock } from 'vitest'
13
+
14
+ vi.mock('../devtools/devtools')
15
+ vi.mock('../useQueryClient')
16
+ vi.mock('../useBaseQuery')
17
+
18
+ interface TestApp extends App {
19
+ onUnmount: Function
20
+ _unmount: Function
21
+ _mixin: ComponentOptions
22
+ _provided: Record<string, any>
23
+ $root: TestApp
24
+ }
25
+
26
+ const testIf = (condition: boolean) => (condition ? test : test.skip)
27
+
28
+ function getAppMock(withUnmountHook = false): TestApp {
29
+ const mock = {
30
+ provide: vi.fn(),
31
+ unmount: vi.fn(),
32
+ onUnmount: withUnmountHook
33
+ ? vi.fn((u: Function) => {
34
+ mock._unmount = u
35
+ })
36
+ : undefined,
37
+ mixin: (m: ComponentOptions): any => {
38
+ mock._mixin = m
39
+ },
40
+ } as unknown as TestApp
41
+
42
+ return mock
43
+ }
44
+
45
+ describe('VueQueryPlugin', () => {
46
+ describe('devtools', () => {
47
+ test('should NOT setup devtools', () => {
48
+ const setupDevtoolsMock = setupDevtools as Mock
49
+ const appMock = getAppMock()
50
+ VueQueryPlugin.install(appMock)
51
+
52
+ expect(setupDevtoolsMock).toHaveBeenCalledTimes(0)
53
+ })
54
+
55
+ testIf(isVue2)('should setup devtools', () => {
56
+ const envCopy = process.env.NODE_ENV
57
+ process.env.NODE_ENV = 'development'
58
+ const setupDevtoolsMock = setupDevtools as Mock
59
+ const appMock = getAppMock()
60
+ VueQueryPlugin.install(appMock)
61
+
62
+ appMock.$root = appMock
63
+ appMock._mixin.beforeCreate?.call(appMock)
64
+ process.env.NODE_ENV = envCopy
65
+
66
+ expect(setupDevtoolsMock).toHaveBeenCalledTimes(1)
67
+ })
68
+
69
+ testIf(isVue3)('should setup devtools', () => {
70
+ const envCopy = process.env.NODE_ENV
71
+ process.env.NODE_ENV = 'development'
72
+ const setupDevtoolsMock = setupDevtools as Mock
73
+ const appMock = getAppMock()
74
+ VueQueryPlugin.install(appMock)
75
+ process.env.NODE_ENV = envCopy
76
+
77
+ expect(setupDevtoolsMock).toHaveBeenCalledTimes(1)
78
+ })
79
+ })
80
+
81
+ describe('when app unmounts', () => {
82
+ test('should call unmount on each client when onUnmount is missing', () => {
83
+ const appMock = getAppMock()
84
+ const customClient = {
85
+ mount: vi.fn(),
86
+ unmount: vi.fn(),
87
+ } as unknown as QueryClient
88
+ const originalUnmount = appMock.unmount
89
+ VueQueryPlugin.install(appMock, {
90
+ queryClient: customClient,
91
+ })
92
+
93
+ appMock.unmount()
94
+
95
+ expect(appMock.unmount).not.toEqual(originalUnmount)
96
+ expect(customClient.unmount).toHaveBeenCalledTimes(1)
97
+ expect(originalUnmount).toHaveBeenCalledTimes(1)
98
+ })
99
+
100
+ test('should call onUnmount if present', () => {
101
+ const appMock = getAppMock(true)
102
+ const customClient = {
103
+ mount: vi.fn(),
104
+ unmount: vi.fn(),
105
+ } as unknown as QueryClient
106
+ const originalUnmount = appMock.unmount
107
+ VueQueryPlugin.install(appMock, { queryClient: customClient })
108
+
109
+ appMock._unmount()
110
+
111
+ expect(appMock.unmount).toEqual(originalUnmount)
112
+ expect(customClient.unmount).toHaveBeenCalledTimes(1)
113
+ })
114
+ })
115
+
116
+ describe('when called without additional options', () => {
117
+ testIf(isVue2)('should provide a client with default clientKey', () => {
118
+ const appMock = getAppMock()
119
+ VueQueryPlugin.install(appMock)
120
+
121
+ appMock._mixin.beforeCreate?.call(appMock)
122
+
123
+ expect(appMock._provided).toMatchObject({
124
+ VUE_QUERY_CLIENT: expect.any(QueryClient),
125
+ })
126
+ })
127
+
128
+ testIf(isVue3)('should provide a client with default clientKey', () => {
129
+ const appMock = getAppMock()
130
+ VueQueryPlugin.install(appMock)
131
+
132
+ expect(appMock.provide).toHaveBeenCalledWith(
133
+ VUE_QUERY_CLIENT,
134
+ expect.any(QueryClient),
135
+ )
136
+ })
137
+ })
138
+
139
+ describe('when called with custom clientKey', () => {
140
+ testIf(isVue2)('should provide a client with customized clientKey', () => {
141
+ const appMock = getAppMock()
142
+ VueQueryPlugin.install(appMock, { queryClientKey: 'CUSTOM' })
143
+
144
+ appMock._mixin.beforeCreate?.call(appMock)
145
+
146
+ expect(appMock._provided).toMatchObject({
147
+ [VUE_QUERY_CLIENT + ':CUSTOM']: expect.any(QueryClient),
148
+ })
149
+ })
150
+
151
+ testIf(isVue3)('should provide a client with customized clientKey', () => {
152
+ const appMock = getAppMock()
153
+ VueQueryPlugin.install(appMock, { queryClientKey: 'CUSTOM' })
154
+
155
+ expect(appMock.provide).toHaveBeenCalledWith(
156
+ VUE_QUERY_CLIENT + ':CUSTOM',
157
+ expect.any(QueryClient),
158
+ )
159
+ })
160
+ })
161
+
162
+ describe('when called with custom client', () => {
163
+ testIf(isVue2)('should provide that custom client', () => {
164
+ const appMock = getAppMock()
165
+ const customClient = { mount: vi.fn() } as unknown as QueryClient
166
+ VueQueryPlugin.install(appMock, { queryClient: customClient })
167
+
168
+ appMock._mixin.beforeCreate?.call(appMock)
169
+
170
+ expect(customClient.mount).toHaveBeenCalled()
171
+ expect(appMock._provided).toMatchObject({
172
+ VUE_QUERY_CLIENT: customClient,
173
+ })
174
+ })
175
+
176
+ testIf(isVue3)('should provide that custom client', () => {
177
+ const appMock = getAppMock()
178
+ const customClient = { mount: vi.fn() } as unknown as QueryClient
179
+ VueQueryPlugin.install(appMock, { queryClient: customClient })
180
+
181
+ expect(customClient.mount).toHaveBeenCalled()
182
+ expect(appMock.provide).toHaveBeenCalledWith(
183
+ VUE_QUERY_CLIENT,
184
+ customClient,
185
+ )
186
+ })
187
+ })
188
+
189
+ describe('when called with custom client config', () => {
190
+ testIf(isVue2)(
191
+ 'should instantiate a client with the provided config',
192
+ () => {
193
+ const appMock = getAppMock()
194
+ const config = {
195
+ defaultOptions: { queries: { enabled: true } },
196
+ }
197
+ VueQueryPlugin.install(appMock, {
198
+ queryClientConfig: config,
199
+ })
200
+
201
+ appMock._mixin.beforeCreate?.call(appMock)
202
+ const client = appMock._provided.VUE_QUERY_CLIENT as QueryClient
203
+ const defaultOptions = client.getDefaultOptions()
204
+
205
+ expect(defaultOptions).toEqual(config.defaultOptions)
206
+ },
207
+ )
208
+
209
+ testIf(isVue3)(
210
+ 'should instantiate a client with the provided config',
211
+ () => {
212
+ const appMock = getAppMock()
213
+ const config = {
214
+ defaultOptions: { queries: { enabled: true } },
215
+ }
216
+ VueQueryPlugin.install(appMock, {
217
+ queryClientConfig: config,
218
+ })
219
+
220
+ const client = (appMock.provide as Mock).mock.calls[0][1]
221
+ const defaultOptions = client.getDefaultOptions()
222
+
223
+ expect(defaultOptions).toEqual(config.defaultOptions)
224
+ },
225
+ )
226
+ })
227
+
228
+ describe('when persister is provided', () => {
229
+ test('should properly modify isRestoring flag on queryClient', async () => {
230
+ const appMock = getAppMock()
231
+ const customClient = {
232
+ mount: vi.fn(),
233
+ isRestoring: ref(false),
234
+ } as unknown as QueryClient
235
+
236
+ VueQueryPlugin.install(appMock, {
237
+ queryClient: customClient,
238
+ clientPersister: () => [
239
+ vi.fn(),
240
+ new Promise((resolve) => {
241
+ resolve()
242
+ }),
243
+ ],
244
+ })
245
+
246
+ expect(customClient.isRestoring.value).toBeTruthy()
247
+
248
+ await flushPromises()
249
+
250
+ expect(customClient.isRestoring.value).toBeFalsy()
251
+ })
252
+
253
+ test('should delay useQuery subscription and not call fetcher if data is not stale', async () => {
254
+ const appMock = getAppMock()
255
+ const customClient = new QueryClient({
256
+ defaultOptions: {
257
+ queries: {
258
+ staleTime: 1000 * 60 * 60,
259
+ },
260
+ },
261
+ })
262
+
263
+ VueQueryPlugin.install(appMock, {
264
+ queryClient: customClient,
265
+ clientPersister: (client) => [
266
+ vi.fn(),
267
+ new Promise((resolve) => {
268
+ setTimeout(() => {
269
+ client.setQueryData(['persist'], () => ({
270
+ foo: 'bar',
271
+ }))
272
+ resolve()
273
+ }, 0)
274
+ }),
275
+ ],
276
+ })
277
+
278
+ const fnSpy = vi.fn()
279
+
280
+ const query = useQuery(
281
+ {
282
+ queryKey: ['persist'],
283
+ queryFn: fnSpy,
284
+ },
285
+ customClient,
286
+ )
287
+
288
+ expect(customClient.isRestoring.value).toBeTruthy()
289
+ expect(query.isFetching.value).toBeFalsy()
290
+ expect(query.data.value).toStrictEqual(undefined)
291
+ expect(fnSpy).toHaveBeenCalledTimes(0)
292
+
293
+ await flushPromises()
294
+
295
+ expect(customClient.isRestoring.value).toBeFalsy()
296
+ expect(query.data.value).toStrictEqual({ foo: 'bar' })
297
+ expect(fnSpy).toHaveBeenCalledTimes(0)
298
+ })
299
+
300
+ test('should delay useQueries subscription and not call fetcher if data is not stale', async () => {
301
+ const appMock = getAppMock()
302
+ const customClient = new QueryClient({
303
+ defaultOptions: {
304
+ queries: {
305
+ staleTime: 1000 * 60 * 60,
306
+ },
307
+ },
308
+ })
309
+
310
+ VueQueryPlugin.install(appMock, {
311
+ queryClient: customClient,
312
+ clientPersister: (client) => [
313
+ vi.fn(),
314
+ new Promise((resolve) => {
315
+ setTimeout(() => {
316
+ client.setQueryData(['persist'], () => ({
317
+ foo: 'bar',
318
+ }))
319
+ resolve()
320
+ }, 0)
321
+ }),
322
+ ],
323
+ })
324
+
325
+ const fnSpy = vi.fn()
326
+
327
+ const queries = useQueries(
328
+ {
329
+ queries: [
330
+ {
331
+ queryKey: ['persist'],
332
+ queryFn: fnSpy,
333
+ },
334
+ ],
335
+ },
336
+ customClient,
337
+ )
338
+
339
+ expect(customClient.isRestoring.value).toBeTruthy()
340
+ expect(queries.value[0].isFetching).toBeFalsy()
341
+ expect(queries.value[0].data).toStrictEqual(undefined)
342
+ expect(fnSpy).toHaveBeenCalledTimes(0)
343
+
344
+ await flushPromises()
345
+
346
+ expect(customClient.isRestoring.value).toBeFalsy()
347
+ expect(queries.value[0].data).toStrictEqual({ foo: 'bar' })
348
+ expect(fnSpy).toHaveBeenCalledTimes(0)
349
+ })
350
+ })
351
+ })