@tanstack/vue-query 5.0.0-beta.9 → 5.0.0-rc.1

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 (166) hide show
  1. package/build/legacy/devtools/devtools.cjs.map +1 -1
  2. package/build/legacy/devtools/devtools.js.map +1 -1
  3. package/build/legacy/index.d.cts +2 -2
  4. package/build/legacy/index.d.ts +2 -2
  5. package/build/legacy/mutationCache.cjs.map +1 -1
  6. package/build/legacy/mutationCache.d.cts +1 -1
  7. package/build/legacy/mutationCache.d.ts +1 -1
  8. package/build/legacy/mutationCache.js.map +1 -1
  9. package/build/legacy/queryCache.cjs.map +1 -1
  10. package/build/legacy/queryCache.d.cts +1 -1
  11. package/build/legacy/queryCache.d.ts +1 -1
  12. package/build/legacy/queryCache.js.map +1 -1
  13. package/build/legacy/queryClient.cjs +3 -4
  14. package/build/legacy/queryClient.cjs.map +1 -1
  15. package/build/legacy/queryClient.d.cts +4 -4
  16. package/build/legacy/queryClient.d.ts +4 -4
  17. package/build/legacy/queryClient.js +3 -4
  18. package/build/legacy/queryClient.js.map +1 -1
  19. package/build/legacy/types.cjs.map +1 -1
  20. package/build/legacy/types.d.cts +7 -2
  21. package/build/legacy/types.d.ts +7 -2
  22. package/build/legacy/useBaseQuery.cjs +40 -20
  23. package/build/legacy/useBaseQuery.cjs.map +1 -1
  24. package/build/legacy/useBaseQuery.d.cts +1 -1
  25. package/build/legacy/useBaseQuery.d.ts +1 -1
  26. package/build/legacy/useBaseQuery.js +42 -21
  27. package/build/legacy/useBaseQuery.js.map +1 -1
  28. package/build/legacy/useInfiniteQuery.cjs.map +1 -1
  29. package/build/legacy/useInfiniteQuery.d.cts +1 -1
  30. package/build/legacy/useInfiniteQuery.d.ts +1 -1
  31. package/build/legacy/useInfiniteQuery.js.map +1 -1
  32. package/build/legacy/useIsFetching.cjs +13 -13
  33. package/build/legacy/useIsFetching.cjs.map +1 -1
  34. package/build/legacy/useIsFetching.js +14 -14
  35. package/build/legacy/useIsFetching.js.map +1 -1
  36. package/build/legacy/useMutation.cjs +16 -1
  37. package/build/legacy/useMutation.cjs.map +1 -1
  38. package/build/legacy/useMutation.js +18 -2
  39. package/build/legacy/useMutation.js.map +1 -1
  40. package/build/legacy/useMutationState.cjs +10 -7
  41. package/build/legacy/useMutationState.cjs.map +1 -1
  42. package/build/legacy/useMutationState.js +18 -8
  43. package/build/legacy/useMutationState.js.map +1 -1
  44. package/build/legacy/useQueries.cjs +9 -2
  45. package/build/legacy/useQueries.cjs.map +1 -1
  46. package/build/legacy/useQueries.d.cts +7 -5
  47. package/build/legacy/useQueries.d.ts +7 -5
  48. package/build/legacy/useQueries.js +17 -3
  49. package/build/legacy/useQueries.js.map +1 -1
  50. package/build/legacy/{useQuery-ebff9211.d.ts → useQuery-42d67167.d.ts} +6 -6
  51. package/build/legacy/{useQuery-846c66db.d.ts → useQuery-ac350b9a.d.ts} +6 -6
  52. package/build/legacy/useQuery.cjs.map +1 -1
  53. package/build/legacy/useQuery.d.cts +1 -1
  54. package/build/legacy/useQuery.d.ts +1 -1
  55. package/build/legacy/useQuery.js.map +1 -1
  56. package/build/legacy/useQueryClient.cjs +4 -4
  57. package/build/legacy/useQueryClient.cjs.map +1 -1
  58. package/build/legacy/useQueryClient.js +5 -5
  59. package/build/legacy/useQueryClient.js.map +1 -1
  60. package/build/legacy/utils.cjs +8 -0
  61. package/build/legacy/utils.cjs.map +1 -1
  62. package/build/legacy/utils.d.cts +2 -1
  63. package/build/legacy/utils.d.ts +2 -1
  64. package/build/legacy/utils.js +7 -0
  65. package/build/legacy/utils.js.map +1 -1
  66. package/build/legacy/vueQueryPlugin.cjs +2 -0
  67. package/build/legacy/vueQueryPlugin.cjs.map +1 -1
  68. package/build/legacy/vueQueryPlugin.d.cts +3 -2
  69. package/build/legacy/vueQueryPlugin.d.ts +3 -2
  70. package/build/legacy/vueQueryPlugin.js +2 -0
  71. package/build/legacy/vueQueryPlugin.js.map +1 -1
  72. package/build/modern/devtools/devtools.cjs.map +1 -1
  73. package/build/modern/devtools/devtools.js.map +1 -1
  74. package/build/modern/index.d.cts +2 -2
  75. package/build/modern/index.d.ts +2 -2
  76. package/build/modern/mutationCache.cjs.map +1 -1
  77. package/build/modern/mutationCache.d.cts +1 -1
  78. package/build/modern/mutationCache.d.ts +1 -1
  79. package/build/modern/mutationCache.js.map +1 -1
  80. package/build/modern/queryCache.cjs.map +1 -1
  81. package/build/modern/queryCache.d.cts +1 -1
  82. package/build/modern/queryCache.d.ts +1 -1
  83. package/build/modern/queryCache.js.map +1 -1
  84. package/build/modern/queryClient.cjs +3 -4
  85. package/build/modern/queryClient.cjs.map +1 -1
  86. package/build/modern/queryClient.d.cts +4 -4
  87. package/build/modern/queryClient.d.ts +4 -4
  88. package/build/modern/queryClient.js +3 -4
  89. package/build/modern/queryClient.js.map +1 -1
  90. package/build/modern/types.cjs.map +1 -1
  91. package/build/modern/types.d.cts +7 -2
  92. package/build/modern/types.d.ts +7 -2
  93. package/build/modern/useBaseQuery.cjs +40 -20
  94. package/build/modern/useBaseQuery.cjs.map +1 -1
  95. package/build/modern/useBaseQuery.d.cts +1 -1
  96. package/build/modern/useBaseQuery.d.ts +1 -1
  97. package/build/modern/useBaseQuery.js +42 -21
  98. package/build/modern/useBaseQuery.js.map +1 -1
  99. package/build/modern/useInfiniteQuery.cjs.map +1 -1
  100. package/build/modern/useInfiniteQuery.d.cts +1 -1
  101. package/build/modern/useInfiniteQuery.d.ts +1 -1
  102. package/build/modern/useInfiniteQuery.js.map +1 -1
  103. package/build/modern/useIsFetching.cjs +13 -13
  104. package/build/modern/useIsFetching.cjs.map +1 -1
  105. package/build/modern/useIsFetching.js +14 -14
  106. package/build/modern/useIsFetching.js.map +1 -1
  107. package/build/modern/useMutation.cjs +16 -1
  108. package/build/modern/useMutation.cjs.map +1 -1
  109. package/build/modern/useMutation.js +18 -2
  110. package/build/modern/useMutation.js.map +1 -1
  111. package/build/modern/useMutationState.cjs +10 -7
  112. package/build/modern/useMutationState.cjs.map +1 -1
  113. package/build/modern/useMutationState.js +18 -8
  114. package/build/modern/useMutationState.js.map +1 -1
  115. package/build/modern/useQueries.cjs +9 -2
  116. package/build/modern/useQueries.cjs.map +1 -1
  117. package/build/modern/useQueries.d.cts +7 -5
  118. package/build/modern/useQueries.d.ts +7 -5
  119. package/build/modern/useQueries.js +17 -3
  120. package/build/modern/useQueries.js.map +1 -1
  121. package/build/modern/{useQuery-ebff9211.d.ts → useQuery-42d67167.d.ts} +6 -6
  122. package/build/modern/{useQuery-846c66db.d.ts → useQuery-ac350b9a.d.ts} +6 -6
  123. package/build/modern/useQuery.cjs.map +1 -1
  124. package/build/modern/useQuery.d.cts +1 -1
  125. package/build/modern/useQuery.d.ts +1 -1
  126. package/build/modern/useQuery.js.map +1 -1
  127. package/build/modern/useQueryClient.cjs +4 -3
  128. package/build/modern/useQueryClient.cjs.map +1 -1
  129. package/build/modern/useQueryClient.js +5 -4
  130. package/build/modern/useQueryClient.js.map +1 -1
  131. package/build/modern/utils.cjs +8 -0
  132. package/build/modern/utils.cjs.map +1 -1
  133. package/build/modern/utils.d.cts +2 -1
  134. package/build/modern/utils.d.ts +2 -1
  135. package/build/modern/utils.js +7 -0
  136. package/build/modern/utils.js.map +1 -1
  137. package/build/modern/vueQueryPlugin.cjs +1 -0
  138. package/build/modern/vueQueryPlugin.cjs.map +1 -1
  139. package/build/modern/vueQueryPlugin.d.cts +3 -2
  140. package/build/modern/vueQueryPlugin.d.ts +3 -2
  141. package/build/modern/vueQueryPlugin.js +1 -0
  142. package/build/modern/vueQueryPlugin.js.map +1 -1
  143. package/package.json +6 -6
  144. package/src/__mocks__/useBaseQuery.ts +1 -1
  145. package/src/__tests__/queryClient.test.ts +4 -4
  146. package/src/__tests__/useInfiniteQuery.test.ts +1 -1
  147. package/src/__tests__/useInfiniteQuery.types.test.tsx +5 -5
  148. package/src/__tests__/useMutation.test.ts +23 -3
  149. package/src/__tests__/useQuery.test.ts +57 -6
  150. package/src/__tests__/useQueryClient.test.ts +4 -4
  151. package/src/__tests__/utils.test.ts +1 -1
  152. package/src/devtools/devtools.ts +2 -2
  153. package/src/mutationCache.ts +1 -1
  154. package/src/queryCache.ts +1 -1
  155. package/src/queryClient.ts +17 -10
  156. package/src/types.ts +23 -1
  157. package/src/useBaseQuery.ts +51 -21
  158. package/src/useInfiniteQuery.ts +2 -3
  159. package/src/useIsFetching.ts +16 -14
  160. package/src/useMutation.ts +23 -2
  161. package/src/useMutationState.ts +20 -9
  162. package/src/useQueries.ts +51 -28
  163. package/src/useQuery.ts +10 -5
  164. package/src/useQueryClient.ts +6 -5
  165. package/src/utils.ts +12 -0
  166. package/src/vueQueryPlugin.ts +3 -2
@@ -259,11 +259,11 @@ describe('QueryCache', () => {
259
259
 
260
260
  queryClient.fetchInfiniteQuery({
261
261
  queryKey: queryKeyRef,
262
- defaultPageParam: 0,
262
+ initialPageParam: 0,
263
263
  })
264
264
 
265
265
  expect(QueryClientOrigin.prototype.fetchInfiniteQuery).toBeCalledWith({
266
- defaultPageParam: 0,
266
+ initialPageParam: 0,
267
267
  queryKey: queryKeyUnref,
268
268
  })
269
269
  })
@@ -276,11 +276,11 @@ describe('QueryCache', () => {
276
276
  queryClient.prefetchInfiniteQuery({
277
277
  queryKey: queryKeyRef,
278
278
  queryFn: fn,
279
- defaultPageParam: 0,
279
+ initialPageParam: 0,
280
280
  })
281
281
 
282
282
  expect(QueryClientOrigin.prototype.prefetchInfiniteQuery).toBeCalledWith({
283
- defaultPageParam: 0,
283
+ initialPageParam: 0,
284
284
  queryKey: queryKeyUnref,
285
285
  queryFn: fn,
286
286
  })
@@ -9,7 +9,7 @@ describe('useQuery', () => {
9
9
  const { data, fetchNextPage, status } = useInfiniteQuery({
10
10
  queryKey: ['infiniteQuery'],
11
11
  queryFn: infiniteFetcher,
12
- defaultPageParam: 0,
12
+ initialPageParam: 0,
13
13
  getNextPageParam: () => 12,
14
14
  })
15
15
 
@@ -12,7 +12,7 @@ describe('Discriminated union return type', () => {
12
12
  queryKey: ['infiniteQuery'],
13
13
  queryFn: simpleFetcher,
14
14
  getNextPageParam: () => undefined,
15
- defaultPageParam: 0,
15
+ initialPageParam: 0,
16
16
  }),
17
17
  )
18
18
 
@@ -31,7 +31,7 @@ describe('Discriminated union return type', () => {
31
31
  queryKey: ['infiniteQuery'],
32
32
  queryFn: simpleFetcher,
33
33
  getNextPageParam: () => undefined,
34
- defaultPageParam: 0,
34
+ initialPageParam: 0,
35
35
  }),
36
36
  )
37
37
 
@@ -53,7 +53,7 @@ describe('Discriminated union return type', () => {
53
53
  queryKey: ['infiniteQuery'],
54
54
  queryFn: simpleFetcher,
55
55
  getNextPageParam: () => undefined,
56
- defaultPageParam: 0,
56
+ initialPageParam: 0,
57
57
  }),
58
58
  )
59
59
 
@@ -72,7 +72,7 @@ describe('Discriminated union return type', () => {
72
72
  queryKey: ['infiniteQuery'],
73
73
  queryFn: simpleFetcher,
74
74
  getNextPageParam: () => undefined,
75
- defaultPageParam: 0,
75
+ initialPageParam: 0,
76
76
  }),
77
77
  )
78
78
 
@@ -91,7 +91,7 @@ describe('Discriminated union return type', () => {
91
91
  queryKey: ['infiniteQuery'],
92
92
  queryFn: simpleFetcher,
93
93
  getNextPageParam: () => undefined,
94
- defaultPageParam: 0,
94
+ initialPageParam: 0,
95
95
  }),
96
96
  )
97
97
 
@@ -99,7 +99,7 @@ describe('useMutation', () => {
99
99
  name: string
100
100
  }
101
101
  }
102
- const mutationKey = ref<MutationKeyTest[]>([
102
+ const mutationKey = ref<Array<MutationKeyTest>>([
103
103
  {
104
104
  entity: 'test',
105
105
  otherObject: { name: 'objectName' },
@@ -128,13 +128,13 @@ describe('useMutation', () => {
128
128
  })
129
129
 
130
130
  expect(
131
- (relevantMutation?.options.mutationKey as MutationKeyTest[])[0]
131
+ (relevantMutation?.options.mutationKey as Array<MutationKeyTest>)[0]
132
132
  ?.otherObject.name === 'someOtherObjectName',
133
133
  )
134
134
  })
135
135
 
136
136
  test('should allow for non-options object (mutationFn or mutationKey) passed as arg1 & arg2 to trigger reactive updates', async () => {
137
- const mutationKey = ref<string[]>(['foo2'])
137
+ const mutationKey = ref<Array<string>>(['foo2'])
138
138
  const mutationFn = ref((params: string) => successMutator(params))
139
139
  const queryClient = useQueryClient()
140
140
  const mutationCache = queryClient.getMutationCache()
@@ -332,4 +332,24 @@ describe('useMutation', () => {
332
332
  })
333
333
  })
334
334
  })
335
+
336
+ describe('throwOnError', () => {
337
+ test('should evaluate throwOnError when mutation is expected to throw', async () => {
338
+ const err = new Error('Expected mock error. All is well!')
339
+ const boundaryFn = vi.fn()
340
+ const { mutate } = useMutation({
341
+ mutationFn: () => {
342
+ return Promise.reject(err)
343
+ },
344
+ throwOnError: boundaryFn,
345
+ })
346
+
347
+ mutate()
348
+
349
+ await flushPromises()
350
+
351
+ expect(boundaryFn).toHaveBeenCalledTimes(1)
352
+ expect(boundaryFn).toHaveBeenCalledWith(err)
353
+ })
354
+ })
335
355
  })
@@ -138,8 +138,6 @@ describe('useQuery', () => {
138
138
  })
139
139
 
140
140
  secondKeyRef.value = 'key8'
141
- await flushPromises()
142
-
143
141
  expect(query).toMatchObject({
144
142
  status: { value: 'pending' },
145
143
  data: { value: undefined },
@@ -168,9 +166,6 @@ describe('useQuery', () => {
168
166
  })
169
167
 
170
168
  enabled.value = true
171
-
172
- await flushPromises()
173
-
174
169
  expect(query).toMatchObject({
175
170
  fetchStatus: { value: 'fetching' },
176
171
  data: { value: undefined },
@@ -191,16 +186,18 @@ describe('useQuery', () => {
191
186
 
192
187
  const enabled = computed(() => !!data.value)
193
188
 
189
+ const dependentQueryFn = vi.fn().mockImplementation(simpleFetcher)
194
190
  const { fetchStatus, status } = useQuery(
195
191
  reactive({
196
192
  queryKey: ['dependant2'],
197
- queryFn: simpleFetcher,
193
+ queryFn: dependentQueryFn,
198
194
  enabled,
199
195
  }),
200
196
  )
201
197
 
202
198
  expect(data.value).toStrictEqual(undefined)
203
199
  expect(fetchStatus.value).toStrictEqual('idle')
200
+ expect(dependentQueryFn).not.toHaveBeenCalled()
204
201
 
205
202
  await flushPromises()
206
203
 
@@ -211,6 +208,10 @@ describe('useQuery', () => {
211
208
 
212
209
  expect(fetchStatus.value).toStrictEqual('idle')
213
210
  expect(status.value).toStrictEqual('success')
211
+ expect(dependentQueryFn).toHaveBeenCalledTimes(1)
212
+ expect(dependentQueryFn).toHaveBeenCalledWith(
213
+ expect.objectContaining({ queryKey: ['dependant2'] }),
214
+ )
214
215
  })
215
216
 
216
217
  test('should stop listening to changes on onScopeDispose', async () => {
@@ -235,6 +236,56 @@ describe('useQuery', () => {
235
236
  expect(status.value).toStrictEqual('pending')
236
237
  })
237
238
 
239
+ test('should use the current value for the queryKey when refetch is called', async () => {
240
+ const fetchFn = vi.fn()
241
+ const keyRef = ref('key11')
242
+ const query = useQuery({
243
+ queryKey: ['key10', keyRef],
244
+ queryFn: fetchFn,
245
+ enabled: false,
246
+ })
247
+
248
+ expect(fetchFn).not.toHaveBeenCalled()
249
+ await query.refetch()
250
+ expect(fetchFn).toHaveBeenCalledTimes(1)
251
+ expect(fetchFn).toHaveBeenCalledWith(
252
+ expect.objectContaining({
253
+ queryKey: ['key10', 'key11'],
254
+ }),
255
+ )
256
+
257
+ keyRef.value = 'key12'
258
+ await query.refetch()
259
+ expect(fetchFn).toHaveBeenCalledTimes(2)
260
+ expect(fetchFn).toHaveBeenCalledWith(
261
+ expect.objectContaining({
262
+ queryKey: ['key10', 'key12'],
263
+ }),
264
+ )
265
+ })
266
+
267
+ describe('throwOnError', () => {
268
+ test('should evaluate throwOnError when query is expected to throw', async () => {
269
+ const boundaryFn = vi.fn()
270
+ useQuery({
271
+ queryKey: ['key0'],
272
+ queryFn: rejectFetcher,
273
+ retry: false,
274
+ throwOnError: boundaryFn,
275
+ })
276
+
277
+ await flushPromises()
278
+
279
+ expect(boundaryFn).toHaveBeenCalledTimes(1)
280
+ expect(boundaryFn).toHaveBeenCalledWith(
281
+ Error('Some error'),
282
+ expect.objectContaining({
283
+ state: expect.objectContaining({ status: 'error' }),
284
+ }),
285
+ )
286
+ })
287
+ })
288
+
238
289
  describe('suspense', () => {
239
290
  test('should return a Promise', () => {
240
291
  const getCurrentInstanceSpy = getCurrentInstance as Mock
@@ -1,4 +1,4 @@
1
- import { getCurrentInstance, inject } from 'vue-demi'
1
+ import { hasInjectionContext, inject } from 'vue-demi'
2
2
  import { vi } from 'vitest'
3
3
  import { useQueryClient } from '../useQueryClient'
4
4
  import { VUE_QUERY_CLIENT } from '../utils'
@@ -6,7 +6,7 @@ import type { Mock } from 'vitest'
6
6
 
7
7
  describe('useQueryClient', () => {
8
8
  const injectSpy = inject as Mock
9
- const getCurrentInstanceSpy = getCurrentInstance as Mock
9
+ const hasInjectionContextSpy = hasInjectionContext as Mock
10
10
 
11
11
  beforeEach(() => {
12
12
  vi.restoreAllMocks()
@@ -32,10 +32,10 @@ describe('useQueryClient', () => {
32
32
  })
33
33
 
34
34
  test('should throw an error when used outside of setup function', () => {
35
- getCurrentInstanceSpy.mockReturnValueOnce(undefined)
35
+ hasInjectionContextSpy.mockReturnValueOnce(false)
36
36
 
37
37
  expect(useQueryClient).toThrowError()
38
- expect(getCurrentInstanceSpy).toHaveBeenCalledTimes(1)
38
+ expect(hasInjectionContextSpy).toHaveBeenCalledTimes(1)
39
39
  })
40
40
 
41
41
  test('should call inject with a custom key as a suffix', () => {
@@ -79,7 +79,7 @@ describe('utils', () => {
79
79
  expect(cp).not.toBe(val)
80
80
  expect(cp[3]).toBe(val[3]) // Set([3, 4])
81
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 }
82
+ expect((cp[4] as Array<number>)[2]).not.toBe((val[4] as Array<number>)[2]) // { a : 1 }
83
83
  })
84
84
 
85
85
  test('should deeply copy object', () => {
@@ -146,7 +146,7 @@ export function setupDevtools(app: any, queryClient: QueryClient) {
146
146
  api.sendInspectorTree(pluginId)
147
147
  api.sendInspectorState(pluginId)
148
148
 
149
- const queryEvents: QueryCacheNotifyEvent['type'][] = [
149
+ const queryEvents: Array<QueryCacheNotifyEvent['type']> = [
150
150
  'added',
151
151
  'removed',
152
152
  'updated',
@@ -189,7 +189,7 @@ export function setupDevtools(app: any, queryClient: QueryClient) {
189
189
  (a, b) => sortFns[settings.sortFn]!(a, b) * settings.baseSort,
190
190
  )
191
191
 
192
- const nodes: CustomInspectorNode[] = sorted.map((query) => {
192
+ const nodes: Array<CustomInspectorNode> = sorted.map((query) => {
193
193
  const stateLabel = getQueryStateLabel(query)
194
194
 
195
195
  return {
@@ -19,7 +19,7 @@ export class MutationCache extends MC {
19
19
  return super.find(cloneDeepUnref(filters))
20
20
  }
21
21
 
22
- findAll(filters: MaybeRefDeep<MutationFilters> = {}): Mutation[] {
22
+ findAll(filters: MaybeRefDeep<MutationFilters> = {}): Array<Mutation> {
23
23
  return super.findAll(cloneDeepUnref(filters))
24
24
  }
25
25
  }
package/src/queryCache.ts CHANGED
@@ -15,7 +15,7 @@ export class QueryCache extends QC {
15
15
  return super.find(cloneDeepUnref(filters))
16
16
  }
17
17
 
18
- findAll(filters: MaybeRefDeep<QueryFilters> = {}): Query[] {
18
+ findAll(filters: MaybeRefDeep<QueryFilters> = {}): Array<Query> {
19
19
  return super.findAll(cloneDeepUnref(filters))
20
20
  }
21
21
  }
@@ -29,12 +29,11 @@ import type {
29
29
  } from '@tanstack/query-core'
30
30
 
31
31
  export class QueryClient extends QC {
32
- constructor(config: MaybeRefDeep<QueryClientConfig> = {}) {
33
- const unreffedConfig = cloneDeepUnref(config)
34
- const vueQueryConfig: QueryClientConfig = {
35
- defaultOptions: unreffedConfig.defaultOptions,
36
- queryCache: unreffedConfig.queryCache || new QueryCache(),
37
- mutationCache: unreffedConfig.mutationCache || new MutationCache(),
32
+ constructor(config: QueryClientConfig = {}) {
33
+ const vueQueryConfig = {
34
+ defaultOptions: config.defaultOptions,
35
+ queryCache: config.queryCache || new QueryCache(),
36
+ mutationCache: config.mutationCache || new MutationCache(),
38
37
  }
39
38
  super(vueQueryConfig)
40
39
  }
@@ -57,7 +56,7 @@ export class QueryClient extends QC {
57
56
 
58
57
  getQueriesData<TData = unknown>(
59
58
  filters: MaybeRefDeep<QueryFilters>,
60
- ): [QueryKey, TData | undefined][] {
59
+ ): Array<[QueryKey, TData | undefined]> {
61
60
  return super.getQueriesData(cloneDeepUnref(filters))
62
61
  }
63
62
 
@@ -77,7 +76,7 @@ export class QueryClient extends QC {
77
76
  filters: MaybeRefDeep<QueryFilters>,
78
77
  updater: Updater<TData | undefined, TData | undefined>,
79
78
  options: MaybeRefDeep<SetDataOptions> = {},
80
- ): [QueryKey, TData | undefined][] {
79
+ ): Array<[QueryKey, TData | undefined]> {
81
80
  return super.setQueriesData(
82
81
  cloneDeepUnref(filters),
83
82
  updater,
@@ -134,17 +133,25 @@ export class QueryClient extends QC {
134
133
  TError = DefaultError,
135
134
  TData = TQueryFnData,
136
135
  TQueryKey extends QueryKey = QueryKey,
136
+ TPageParam = never,
137
137
  >(
138
- options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
138
+ options: FetchQueryOptions<
139
+ TQueryFnData,
140
+ TError,
141
+ TData,
142
+ TQueryKey,
143
+ TPageParam
144
+ >,
139
145
  ): Promise<TData>
140
146
  fetchQuery<
141
147
  TQueryFnData,
142
148
  TError = DefaultError,
143
149
  TData = TQueryFnData,
144
150
  TQueryKey extends QueryKey = QueryKey,
151
+ TPageParam = never,
145
152
  >(
146
153
  options: MaybeRefDeep<
147
- FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>
154
+ FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
148
155
  >,
149
156
  ): Promise<TData> {
150
157
  return super.fetchQuery(cloneDeepUnref(options))
package/src/types.ts CHANGED
@@ -1,4 +1,16 @@
1
- import type { Ref } from 'vue-demi'
1
+ import type { Ref, UnwrapRef } from 'vue-demi'
2
+
3
+ type Primitive = string | number | boolean | bigint | symbol | undefined | null
4
+ type UnwrapLeaf =
5
+ | Primitive
6
+ | Function
7
+ | Date
8
+ | Error
9
+ | RegExp
10
+ | Map<any, any>
11
+ | WeakMap<any, any>
12
+ | Set<any>
13
+ | WeakSet<any>
2
14
 
3
15
  export type MaybeRef<T> = Ref<T> | T
4
16
 
@@ -12,6 +24,16 @@ export type MaybeRefDeep<T> = MaybeRef<
12
24
  : T
13
25
  >
14
26
 
27
+ export type DeepUnwrapRef<T> = T extends UnwrapLeaf
28
+ ? T
29
+ : T extends Ref<infer U>
30
+ ? DeepUnwrapRef<U>
31
+ : T extends {}
32
+ ? {
33
+ [Property in keyof T]: DeepUnwrapRef<T[Property]>
34
+ }
35
+ : UnwrapRef<T>
36
+
15
37
  export type DistributiveOmit<T, K extends keyof any> = T extends any
16
38
  ? Omit<T, K>
17
39
  : never
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  computed,
3
+ getCurrentScope,
3
4
  onScopeDispose,
4
5
  reactive,
5
6
  readonly,
@@ -7,7 +8,7 @@ import {
7
8
  watch,
8
9
  } from 'vue-demi'
9
10
  import { useQueryClient } from './useQueryClient'
10
- import { cloneDeepUnref, updateState } from './utils'
11
+ import { cloneDeepUnref, shouldThrowError, updateState } from './utils'
11
12
  import type { ToRefs } from 'vue-demi'
12
13
  import type {
13
14
  DefaultedQueryObserverOptions,
@@ -64,6 +65,14 @@ export function useBaseQuery<
64
65
  >,
65
66
  queryClient?: QueryClient,
66
67
  ): UseBaseQueryReturnType<TData, TError> {
68
+ if (process.env.NODE_ENV === 'development') {
69
+ if (!getCurrentScope()) {
70
+ console.warn(
71
+ 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.',
72
+ )
73
+ }
74
+ }
75
+
67
76
  const client = queryClient || useQueryClient()
68
77
 
69
78
  const defaultedOptions = computed(() => {
@@ -109,7 +118,7 @@ export function useBaseQuery<
109
118
  observer.setOptions(defaultedOptions.value)
110
119
  updateState(state, observer.getCurrentResult())
111
120
  },
112
- { deep: true },
121
+ { flush: 'sync' },
113
122
  )
114
123
 
115
124
  onScopeDispose(() => {
@@ -117,31 +126,52 @@ export function useBaseQuery<
117
126
  })
118
127
 
119
128
  const suspense = () => {
120
- return new Promise<QueryObserverResult<TData, TError>>((resolve) => {
121
- let stopWatch = () => {
122
- //noop
123
- }
124
- const run = () => {
125
- if (defaultedOptions.value.enabled !== false) {
126
- const optimisticResult = observer.getOptimisticResult(
127
- defaultedOptions.value,
128
- )
129
- if (optimisticResult.isStale) {
130
- stopWatch()
131
- resolve(observer.fetchOptimistic(defaultedOptions.value))
132
- } else {
133
- stopWatch()
134
- resolve(optimisticResult)
129
+ return new Promise<QueryObserverResult<TData, TError>>(
130
+ (resolve, reject) => {
131
+ let stopWatch = () => {
132
+ //noop
133
+ }
134
+ const run = () => {
135
+ if (defaultedOptions.value.enabled !== false) {
136
+ const optimisticResult = observer.getOptimisticResult(
137
+ defaultedOptions.value,
138
+ )
139
+ if (optimisticResult.isStale) {
140
+ stopWatch()
141
+ observer
142
+ .fetchOptimistic(defaultedOptions.value)
143
+ .then(resolve, reject)
144
+ } else {
145
+ stopWatch()
146
+ resolve(optimisticResult)
147
+ }
135
148
  }
136
149
  }
137
- }
138
150
 
139
- run()
151
+ run()
140
152
 
141
- stopWatch = watch(defaultedOptions, run, { deep: true })
142
- })
153
+ stopWatch = watch(defaultedOptions, run)
154
+ },
155
+ )
143
156
  }
144
157
 
158
+ // Handle error boundary
159
+ watch(
160
+ () => state.error,
161
+ (error) => {
162
+ if (
163
+ state.isError &&
164
+ !state.isFetching &&
165
+ shouldThrowError(defaultedOptions.value.throwOnError, [
166
+ error as TError,
167
+ observer.getCurrentQuery(),
168
+ ])
169
+ ) {
170
+ throw error
171
+ }
172
+ },
173
+ )
174
+
145
175
  return {
146
176
  ...(toRefs(readonly(state)) as ToRefs<
147
177
  Readonly<QueryObserverResult<TData, TError>>
@@ -12,9 +12,8 @@ import type {
12
12
 
13
13
  import type { UseBaseQueryReturnType } from './useBaseQuery'
14
14
 
15
- import type { DistributiveOmit, MaybeRefDeep } from './types'
15
+ import type { DeepUnwrapRef, DistributiveOmit, MaybeRefDeep } from './types'
16
16
  import type { QueryClient } from './queryClient'
17
- import type { UnwrapRef } from 'vue-demi'
18
17
 
19
18
  export type UseInfiniteQueryOptions<
20
19
  TQueryFnData = unknown,
@@ -37,7 +36,7 @@ export type UseInfiniteQueryOptions<
37
36
  TError,
38
37
  TData,
39
38
  TQueryData,
40
- UnwrapRef<TQueryKey>,
39
+ DeepUnwrapRef<TQueryKey>,
41
40
  TPageParam
42
41
  >[Property]
43
42
  : MaybeRefDeep<
@@ -1,6 +1,5 @@
1
- import { computed, onScopeDispose, ref, watch } from 'vue-demi'
1
+ import { getCurrentScope, onScopeDispose, ref, watchSyncEffect } from 'vue-demi'
2
2
  import { useQueryClient } from './useQueryClient'
3
- import { cloneDeepUnref } from './utils'
4
3
  import type { Ref } from 'vue-demi'
5
4
  import type { QueryFilters as QF } from '@tanstack/query-core'
6
5
  import type { MaybeRefDeep } from './types'
@@ -12,22 +11,25 @@ export function useIsFetching(
12
11
  fetchingFilters: MaybeRefDeep<QF> = {},
13
12
  queryClient?: QueryClient,
14
13
  ): Ref<number> {
15
- const filters = computed(() => cloneDeepUnref(fetchingFilters))
14
+ if (process.env.NODE_ENV === 'development') {
15
+ if (!getCurrentScope()) {
16
+ console.warn(
17
+ 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.',
18
+ )
19
+ }
20
+ }
21
+
16
22
  const client = queryClient || useQueryClient()
17
23
 
18
- const isFetching = ref(client.isFetching(filters))
24
+ const isFetching = ref()
19
25
 
20
- const unsubscribe = client.getQueryCache().subscribe(() => {
21
- isFetching.value = client.isFetching(filters)
22
- })
26
+ const listener = () => {
27
+ isFetching.value = client.isFetching(fetchingFilters)
28
+ }
29
+
30
+ const unsubscribe = client.getQueryCache().subscribe(listener)
23
31
 
24
- watch(
25
- filters,
26
- () => {
27
- isFetching.value = client.isFetching(filters)
28
- },
29
- { deep: true },
30
- )
32
+ watchSyncEffect(listener)
31
33
 
32
34
  onScopeDispose(() => {
33
35
  unsubscribe()
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  computed,
3
+ getCurrentScope,
3
4
  onScopeDispose,
4
5
  reactive,
5
6
  readonly,
@@ -7,7 +8,7 @@ import {
7
8
  watch,
8
9
  } from 'vue-demi'
9
10
  import { MutationObserver } from '@tanstack/query-core'
10
- import { cloneDeepUnref, updateState } from './utils'
11
+ import { cloneDeepUnref, shouldThrowError, updateState } from './utils'
11
12
  import { useQueryClient } from './useQueryClient'
12
13
  import type { ToRefs } from 'vue-demi'
13
14
  import type {
@@ -64,6 +65,14 @@ export function useMutation<
64
65
  >,
65
66
  queryClient?: QueryClient,
66
67
  ): UseMutationReturnType<TData, TError, TVariables, TContext> {
68
+ if (process.env.NODE_ENV === 'development') {
69
+ if (!getCurrentScope()) {
70
+ console.warn(
71
+ 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.',
72
+ )
73
+ }
74
+ }
75
+
67
76
  const client = queryClient || useQueryClient()
68
77
  const options = computed(() => {
69
78
  return client.defaultMutationOptions(cloneDeepUnref(mutationOptions))
@@ -89,7 +98,7 @@ export function useMutation<
89
98
  () => {
90
99
  observer.setOptions(options.value)
91
100
  },
92
- { deep: true },
101
+ { flush: 'sync' },
93
102
  )
94
103
 
95
104
  onScopeDispose(() => {
@@ -100,6 +109,18 @@ export function useMutation<
100
109
  Readonly<MutationResult<TData, TError, TVariables, TContext>>
101
110
  >
102
111
 
112
+ watch(
113
+ () => state.error,
114
+ (error) => {
115
+ if (
116
+ error &&
117
+ shouldThrowError(options.value.throwOnError, [error as TError])
118
+ ) {
119
+ throw error
120
+ }
121
+ },
122
+ )
123
+
103
124
  return {
104
125
  ...resultRefs,
105
126
  mutate,