@tanstack/react-query 5.0.0-beta.8 → 5.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/codemods/coverage/base.css +224 -0
- package/build/codemods/coverage/block-navigation.js +87 -0
- package/build/codemods/coverage/clover.xml +6 -0
- package/build/codemods/coverage/coverage-final.json +1 -0
- package/build/codemods/coverage/favicon.png +0 -0
- package/build/codemods/coverage/index.html +101 -0
- package/build/codemods/coverage/prettify.css +1 -0
- package/build/codemods/coverage/prettify.js +2 -0
- package/build/codemods/coverage/sort-arrow-sprite.png +0 -0
- package/build/codemods/coverage/sorter.js +196 -0
- package/build/legacy/HydrationBoundary.cjs +37 -2
- package/build/legacy/HydrationBoundary.cjs.map +1 -1
- package/build/legacy/HydrationBoundary.d.cts +3 -1
- package/build/legacy/HydrationBoundary.d.ts +3 -1
- package/build/legacy/HydrationBoundary.js +37 -2
- package/build/legacy/HydrationBoundary.js.map +1 -1
- package/build/legacy/index.cjs +3 -0
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +1 -0
- package/build/legacy/index.d.ts +1 -0
- package/build/legacy/index.js +2 -0
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
- package/build/legacy/infiniteQueryOptions.d.cts +1 -1
- package/build/legacy/infiniteQueryOptions.d.ts +1 -1
- package/build/legacy/infiniteQueryOptions.js.map +1 -1
- package/build/legacy/queryOptions.cjs.map +1 -1
- package/build/legacy/queryOptions.d.cts +7 -3
- package/build/legacy/queryOptions.d.ts +7 -3
- package/build/legacy/queryOptions.js.map +1 -1
- package/build/legacy/suspense.cjs +3 -0
- package/build/legacy/suspense.cjs.map +1 -1
- package/build/legacy/suspense.d.cts +3 -2
- package/build/legacy/suspense.d.ts +3 -2
- package/build/legacy/suspense.js +2 -0
- package/build/legacy/suspense.js.map +1 -1
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +4 -4
- package/build/legacy/types.d.ts +4 -4
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.d.cts +4 -4
- package/build/legacy/useQueries.d.ts +4 -4
- package/build/legacy/useQueries.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs +47 -0
- package/build/legacy/useSuspenseQueries.cjs.map +1 -0
- package/build/legacy/useSuspenseQueries.d.cts +66 -0
- package/build/legacy/useSuspenseQueries.d.ts +66 -0
- package/build/legacy/useSuspenseQueries.js +23 -0
- package/build/legacy/useSuspenseQueries.js.map +1 -0
- package/build/legacy/useSuspenseQuery.cjs +2 -1
- package/build/legacy/useSuspenseQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseQuery.js +2 -1
- package/build/legacy/useSuspenseQuery.js.map +1 -1
- package/build/legacy/utils.cjs.map +1 -1
- package/build/legacy/utils.d.cts +1 -1
- package/build/legacy/utils.d.ts +1 -1
- package/build/legacy/utils.js.map +1 -1
- package/build/modern/HydrationBoundary.cjs +37 -2
- package/build/modern/HydrationBoundary.cjs.map +1 -1
- package/build/modern/HydrationBoundary.d.cts +3 -1
- package/build/modern/HydrationBoundary.d.ts +3 -1
- package/build/modern/HydrationBoundary.js +37 -2
- package/build/modern/HydrationBoundary.js.map +1 -1
- package/build/modern/index.cjs +3 -0
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +1 -0
- package/build/modern/index.d.ts +1 -0
- package/build/modern/index.js +2 -0
- package/build/modern/index.js.map +1 -1
- package/build/modern/infiniteQueryOptions.cjs.map +1 -1
- package/build/modern/infiniteQueryOptions.d.cts +1 -1
- package/build/modern/infiniteQueryOptions.d.ts +1 -1
- package/build/modern/infiniteQueryOptions.js.map +1 -1
- package/build/modern/queryOptions.cjs.map +1 -1
- package/build/modern/queryOptions.d.cts +7 -3
- package/build/modern/queryOptions.d.ts +7 -3
- package/build/modern/queryOptions.js.map +1 -1
- package/build/modern/suspense.cjs +3 -0
- package/build/modern/suspense.cjs.map +1 -1
- package/build/modern/suspense.d.cts +3 -2
- package/build/modern/suspense.d.ts +3 -2
- package/build/modern/suspense.js +2 -0
- package/build/modern/suspense.js.map +1 -1
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +4 -4
- package/build/modern/types.d.ts +4 -4
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.d.cts +4 -4
- package/build/modern/useQueries.d.ts +4 -4
- package/build/modern/useQueries.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs +47 -0
- package/build/modern/useSuspenseQueries.cjs.map +1 -0
- package/build/modern/useSuspenseQueries.d.cts +66 -0
- package/build/modern/useSuspenseQueries.d.ts +66 -0
- package/build/modern/useSuspenseQueries.js +23 -0
- package/build/modern/useSuspenseQueries.js.map +1 -0
- package/build/modern/useSuspenseQuery.cjs +2 -1
- package/build/modern/useSuspenseQuery.cjs.map +1 -1
- package/build/modern/useSuspenseQuery.js +2 -1
- package/build/modern/useSuspenseQuery.js.map +1 -1
- package/build/modern/utils.cjs.map +1 -1
- package/build/modern/utils.d.cts +1 -1
- package/build/modern/utils.d.ts +1 -1
- package/build/modern/utils.js.map +1 -1
- package/package.json +7 -3
- package/src/HydrationBoundary.tsx +78 -8
- package/src/__tests__/HydrationBoundary.test.tsx +111 -7
- package/src/__tests__/QueryResetErrorBoundary.test.tsx +10 -6
- package/src/__tests__/fine-grained-persister.test.tsx +163 -0
- package/src/__tests__/queryOptions.types.test.tsx +31 -0
- package/src/__tests__/ssr.test.tsx +2 -2
- package/src/__tests__/suspense.test.tsx +94 -386
- package/src/__tests__/useInfiniteQuery.test.tsx +44 -44
- package/src/__tests__/useInfiniteQuery.type.test.tsx +24 -13
- package/src/__tests__/useIsFetching.test.tsx +2 -2
- package/src/__tests__/useMutation.test.tsx +4 -4
- package/src/__tests__/useMutationState.test.tsx +4 -4
- package/src/__tests__/useQueries.test.tsx +65 -64
- package/src/__tests__/useQuery.test.tsx +142 -141
- package/src/__tests__/useQuery.types.test.tsx +34 -0
- package/src/__tests__/utils.tsx +0 -7
- package/src/index.ts +5 -0
- package/src/infiniteQueryOptions.ts +3 -1
- package/src/queryOptions.ts +11 -3
- package/src/suspense.ts +12 -0
- package/src/types.ts +18 -12
- package/src/useQueries.ts +34 -28
- package/src/useSuspenseQueries.ts +164 -0
- package/src/useSuspenseQuery.ts +2 -1
- package/src/utils.ts +1 -1
|
@@ -137,8 +137,8 @@ describe('React hydration', () => {
|
|
|
137
137
|
queryFn: () => dataQuery(['should change']),
|
|
138
138
|
})
|
|
139
139
|
await intermediateClient.prefetchQuery({
|
|
140
|
-
queryKey: ['added
|
|
141
|
-
queryFn: () => dataQuery(['added
|
|
140
|
+
queryKey: ['added'],
|
|
141
|
+
queryFn: () => dataQuery(['added']),
|
|
142
142
|
})
|
|
143
143
|
const dehydrated = dehydrate(intermediateClient)
|
|
144
144
|
intermediateClient.clear()
|
|
@@ -147,17 +147,121 @@ describe('React hydration', () => {
|
|
|
147
147
|
<QueryClientProvider client={queryClient}>
|
|
148
148
|
<HydrationBoundary state={dehydrated}>
|
|
149
149
|
<Page queryKey={['string']} />
|
|
150
|
-
<Page queryKey={['added
|
|
150
|
+
<Page queryKey={['added']} />
|
|
151
151
|
</HydrationBoundary>
|
|
152
152
|
</QueryClientProvider>,
|
|
153
153
|
)
|
|
154
154
|
|
|
155
|
-
// Existing
|
|
156
|
-
//
|
|
155
|
+
// Existing observer should not have updated at this point,
|
|
156
|
+
// as that would indicate a side effect in the render phase
|
|
157
|
+
rendered.getByText('string')
|
|
158
|
+
// New query data should be available immediately
|
|
159
|
+
rendered.getByText('added')
|
|
160
|
+
|
|
157
161
|
await sleep(10)
|
|
162
|
+
// After effects phase has had time to run, the observer should have updated
|
|
163
|
+
expect(rendered.queryByText('string')).toBeNull()
|
|
158
164
|
rendered.getByText('should change')
|
|
159
|
-
|
|
160
|
-
|
|
165
|
+
|
|
166
|
+
queryClient.clear()
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
// When we hydrate in transitions that are later aborted, it could be
|
|
170
|
+
// confusing to both developers and users if we suddenly updated existing
|
|
171
|
+
// state on the screen (why did this update when it was not stale, nothing
|
|
172
|
+
// remounted, I didn't change tabs etc?).
|
|
173
|
+
// Any queries that does not exist in the cache yet can still be hydrated
|
|
174
|
+
// since they don't have any observers on the current page that would update.
|
|
175
|
+
test('should hydrate new but not existing queries if transition is aborted', async () => {
|
|
176
|
+
const initialDehydratedState = JSON.parse(stringifiedState)
|
|
177
|
+
const queryCache = new QueryCache()
|
|
178
|
+
const queryClient = createQueryClient({ queryCache })
|
|
179
|
+
|
|
180
|
+
function Page({ queryKey }: { queryKey: [string] }) {
|
|
181
|
+
const { data } = useQuery({
|
|
182
|
+
queryKey,
|
|
183
|
+
queryFn: () => dataQuery(queryKey),
|
|
184
|
+
})
|
|
185
|
+
return (
|
|
186
|
+
<div>
|
|
187
|
+
<h1>{data}</h1>
|
|
188
|
+
</div>
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const rendered = render(
|
|
193
|
+
<QueryClientProvider client={queryClient}>
|
|
194
|
+
<HydrationBoundary state={initialDehydratedState}>
|
|
195
|
+
<Page queryKey={['string']} />
|
|
196
|
+
</HydrationBoundary>
|
|
197
|
+
</QueryClientProvider>,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
await rendered.findByText('string')
|
|
201
|
+
|
|
202
|
+
const intermediateCache = new QueryCache()
|
|
203
|
+
const intermediateClient = createQueryClient({
|
|
204
|
+
queryCache: intermediateCache,
|
|
205
|
+
})
|
|
206
|
+
await intermediateClient.prefetchQuery({
|
|
207
|
+
queryKey: ['string'],
|
|
208
|
+
queryFn: () => dataQuery(['should not change']),
|
|
209
|
+
})
|
|
210
|
+
await intermediateClient.prefetchQuery({
|
|
211
|
+
queryKey: ['added'],
|
|
212
|
+
queryFn: () => dataQuery(['added']),
|
|
213
|
+
})
|
|
214
|
+
const newDehydratedState = dehydrate(intermediateClient)
|
|
215
|
+
intermediateClient.clear()
|
|
216
|
+
|
|
217
|
+
function Thrower() {
|
|
218
|
+
throw new Promise(() => {
|
|
219
|
+
// Never resolve
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
// @ts-ignore
|
|
223
|
+
return null
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
React.startTransition(() => {
|
|
227
|
+
rendered.rerender(
|
|
228
|
+
<React.Suspense fallback="loading">
|
|
229
|
+
<QueryClientProvider client={queryClient}>
|
|
230
|
+
<HydrationBoundary state={newDehydratedState}>
|
|
231
|
+
<Page queryKey={['string']} />
|
|
232
|
+
<Page queryKey={['added']} />
|
|
233
|
+
<Thrower />
|
|
234
|
+
</HydrationBoundary>
|
|
235
|
+
</QueryClientProvider>
|
|
236
|
+
</React.Suspense>,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
rendered.getByText('loading')
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
React.startTransition(() => {
|
|
243
|
+
rendered.rerender(
|
|
244
|
+
<QueryClientProvider client={queryClient}>
|
|
245
|
+
<HydrationBoundary state={initialDehydratedState}>
|
|
246
|
+
<Page queryKey={['string']} />
|
|
247
|
+
<Page queryKey={['added']} />
|
|
248
|
+
</HydrationBoundary>
|
|
249
|
+
</QueryClientProvider>,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
// This query existed before the transition so it should stay the same
|
|
253
|
+
rendered.getByText('string')
|
|
254
|
+
expect(rendered.queryByText('should not change')).toBeNull()
|
|
255
|
+
// New query data should be available immediately because it was
|
|
256
|
+
// hydrated in the previous transition, even though the new dehydrated
|
|
257
|
+
// state did not contain it
|
|
258
|
+
rendered.getByText('added')
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
await sleep(10)
|
|
262
|
+
// It should stay the same even after effects have had a chance to run
|
|
263
|
+
rendered.getByText('string')
|
|
264
|
+
expect(rendered.queryByText('should not change')).toBeNull()
|
|
161
265
|
|
|
162
266
|
queryClient.clear()
|
|
163
267
|
})
|
|
@@ -3,7 +3,14 @@ import { ErrorBoundary } from 'react-error-boundary'
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
|
|
5
5
|
import { vi } from 'vitest'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
QueryCache,
|
|
8
|
+
QueryErrorResetBoundary,
|
|
9
|
+
useQueries,
|
|
10
|
+
useQuery,
|
|
11
|
+
useSuspenseQueries,
|
|
12
|
+
useSuspenseQuery,
|
|
13
|
+
} from '..'
|
|
7
14
|
import { createQueryClient, queryKey, renderWithClient, sleep } from './utils'
|
|
8
15
|
|
|
9
16
|
// TODO: This should be removed with the types for react-error-boundary get updated.
|
|
@@ -522,7 +529,7 @@ describe('QueryErrorResetBoundary', () => {
|
|
|
522
529
|
let renders = 0
|
|
523
530
|
|
|
524
531
|
function Page() {
|
|
525
|
-
const { data } =
|
|
532
|
+
const { data } = useSuspenseQuery({
|
|
526
533
|
queryKey: key,
|
|
527
534
|
queryFn: async () => {
|
|
528
535
|
fetchCount++
|
|
@@ -534,7 +541,6 @@ describe('QueryErrorResetBoundary', () => {
|
|
|
534
541
|
}
|
|
535
542
|
},
|
|
536
543
|
retry: false,
|
|
537
|
-
suspense: true,
|
|
538
544
|
})
|
|
539
545
|
renders++
|
|
540
546
|
return <div>{data}</div>
|
|
@@ -735,7 +741,7 @@ describe('QueryErrorResetBoundary', () => {
|
|
|
735
741
|
let succeed = false
|
|
736
742
|
|
|
737
743
|
function Page() {
|
|
738
|
-
const [{ data }] =
|
|
744
|
+
const [{ data }] = useSuspenseQueries({
|
|
739
745
|
queries: [
|
|
740
746
|
{
|
|
741
747
|
queryKey: key,
|
|
@@ -748,9 +754,7 @@ describe('QueryErrorResetBoundary', () => {
|
|
|
748
754
|
}
|
|
749
755
|
},
|
|
750
756
|
retry: false,
|
|
751
|
-
throwOnError: true,
|
|
752
757
|
retryOnMount: true,
|
|
753
|
-
suspense: true,
|
|
754
758
|
},
|
|
755
759
|
],
|
|
756
760
|
})
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { waitFor } from '@testing-library/react'
|
|
2
|
+
import '@testing-library/jest-dom'
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { QueryCache, hashKey } from '@tanstack/query-core'
|
|
5
|
+
import { vi } from 'vitest'
|
|
6
|
+
import { useQuery } from '..'
|
|
7
|
+
import {
|
|
8
|
+
PERSISTER_KEY_PREFIX,
|
|
9
|
+
experimental_createPersister,
|
|
10
|
+
} from '../../../query-persist-client-core/src'
|
|
11
|
+
import { createQueryClient, queryKey, renderWithClient, sleep } from './utils'
|
|
12
|
+
|
|
13
|
+
describe('fine grained persister', () => {
|
|
14
|
+
const queryCache = new QueryCache()
|
|
15
|
+
const queryClient = createQueryClient({ queryCache })
|
|
16
|
+
|
|
17
|
+
it('should restore query state from persister and not refetch', async () => {
|
|
18
|
+
const key = queryKey()
|
|
19
|
+
const hash = hashKey(key)
|
|
20
|
+
const spy = vi.fn(() => Promise.resolve('Works from queryFn'))
|
|
21
|
+
|
|
22
|
+
const mapStorage = new Map()
|
|
23
|
+
const storage = {
|
|
24
|
+
getItem: (itemKey: string) => Promise.resolve(mapStorage.get(itemKey)),
|
|
25
|
+
setItem: async (itemKey: string, value: unknown) => {
|
|
26
|
+
mapStorage.set(itemKey, value)
|
|
27
|
+
},
|
|
28
|
+
removeItem: async (itemKey: string) => {
|
|
29
|
+
mapStorage.delete(itemKey)
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await storage.setItem(
|
|
34
|
+
`${PERSISTER_KEY_PREFIX}-${hash}`,
|
|
35
|
+
JSON.stringify({
|
|
36
|
+
buster: '',
|
|
37
|
+
queryHash: hash,
|
|
38
|
+
queryKey: key,
|
|
39
|
+
state: {
|
|
40
|
+
dataUpdatedAt: Date.now(),
|
|
41
|
+
data: 'Works from persister',
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
function Test() {
|
|
47
|
+
const [_, setRef] = React.useState<HTMLDivElement | null>()
|
|
48
|
+
|
|
49
|
+
const { data } = useQuery({
|
|
50
|
+
queryKey: key,
|
|
51
|
+
queryFn: spy,
|
|
52
|
+
persister: experimental_createPersister({
|
|
53
|
+
storage,
|
|
54
|
+
}),
|
|
55
|
+
staleTime: 5000,
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
return <div ref={(value) => setRef(value)}>{data}</div>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const rendered = renderWithClient(queryClient, <Test />)
|
|
62
|
+
|
|
63
|
+
await waitFor(() => rendered.getByText('Works from persister'))
|
|
64
|
+
expect(spy).not.toHaveBeenCalled()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should restore query state from persister and refetch', async () => {
|
|
68
|
+
const key = queryKey()
|
|
69
|
+
const hash = hashKey(key)
|
|
70
|
+
const spy = vi.fn(async () => {
|
|
71
|
+
await sleep(5)
|
|
72
|
+
|
|
73
|
+
return 'Works from queryFn'
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const mapStorage = new Map()
|
|
77
|
+
const storage = {
|
|
78
|
+
getItem: (itemKey: string) => Promise.resolve(mapStorage.get(itemKey)),
|
|
79
|
+
setItem: async (itemKey: string, value: unknown) => {
|
|
80
|
+
mapStorage.set(itemKey, value)
|
|
81
|
+
},
|
|
82
|
+
removeItem: async (itemKey: string) => {
|
|
83
|
+
mapStorage.delete(itemKey)
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
await storage.setItem(
|
|
88
|
+
`${PERSISTER_KEY_PREFIX}-${hash}`,
|
|
89
|
+
JSON.stringify({
|
|
90
|
+
buster: '',
|
|
91
|
+
queryHash: hash,
|
|
92
|
+
queryKey: key,
|
|
93
|
+
state: {
|
|
94
|
+
dataUpdatedAt: Date.now(),
|
|
95
|
+
data: 'Works from persister',
|
|
96
|
+
},
|
|
97
|
+
}),
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
function Test() {
|
|
101
|
+
const [_, setRef] = React.useState<HTMLDivElement | null>()
|
|
102
|
+
|
|
103
|
+
const { data } = useQuery({
|
|
104
|
+
queryKey: key,
|
|
105
|
+
queryFn: spy,
|
|
106
|
+
persister: experimental_createPersister({
|
|
107
|
+
storage,
|
|
108
|
+
}),
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
return <div ref={(value) => setRef(value)}>{data}</div>
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const rendered = renderWithClient(queryClient, <Test />)
|
|
115
|
+
|
|
116
|
+
await waitFor(() => rendered.getByText('Works from persister'))
|
|
117
|
+
await waitFor(() => rendered.getByText('Works from queryFn'))
|
|
118
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should store query state to persister after fetch', async () => {
|
|
122
|
+
const key = queryKey()
|
|
123
|
+
const hash = hashKey(key)
|
|
124
|
+
const spy = vi.fn(() => Promise.resolve('Works from queryFn'))
|
|
125
|
+
|
|
126
|
+
const mapStorage = new Map()
|
|
127
|
+
const storage = {
|
|
128
|
+
getItem: (itemKey: string) => Promise.resolve(mapStorage.get(itemKey)),
|
|
129
|
+
setItem: async (itemKey: string, value: unknown) => {
|
|
130
|
+
mapStorage.set(itemKey, value)
|
|
131
|
+
},
|
|
132
|
+
removeItem: async (itemKey: string) => {
|
|
133
|
+
mapStorage.delete(itemKey)
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function Test() {
|
|
138
|
+
const [_, setRef] = React.useState<HTMLDivElement | null>()
|
|
139
|
+
|
|
140
|
+
const { data } = useQuery({
|
|
141
|
+
queryKey: key,
|
|
142
|
+
queryFn: spy,
|
|
143
|
+
persister: experimental_createPersister({
|
|
144
|
+
storage,
|
|
145
|
+
}),
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
return <div ref={(value) => setRef(value)}>{data}</div>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const rendered = renderWithClient(queryClient, <Test />)
|
|
152
|
+
|
|
153
|
+
await waitFor(() => rendered.getByText('Works from queryFn'))
|
|
154
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
155
|
+
|
|
156
|
+
const storedItem = await storage.getItem(`${PERSISTER_KEY_PREFIX}-${hash}`)
|
|
157
|
+
expect(JSON.parse(storedItem)).toMatchObject({
|
|
158
|
+
state: {
|
|
159
|
+
data: 'Works from queryFn',
|
|
160
|
+
},
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { queryOptions } from '../queryOptions'
|
|
2
|
+
import { doNotExecute } from './utils'
|
|
3
|
+
import type { Equal, Expect } from './utils'
|
|
4
|
+
|
|
5
|
+
describe('queryOptions', () => {
|
|
6
|
+
it('should not allow excess properties', () => {
|
|
7
|
+
doNotExecute(() => {
|
|
8
|
+
// @ts-expect-error this is a good error, because stallTime does not exist!
|
|
9
|
+
return queryOptions({
|
|
10
|
+
queryKey: ['key'],
|
|
11
|
+
queryFn: () => Promise.resolve(5),
|
|
12
|
+
stallTime: 1000,
|
|
13
|
+
})
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
it('should infer types for callbacks', () => {
|
|
17
|
+
doNotExecute(() => {
|
|
18
|
+
return queryOptions({
|
|
19
|
+
queryKey: ['key'],
|
|
20
|
+
queryFn: () => Promise.resolve(5),
|
|
21
|
+
staleTime: 1000,
|
|
22
|
+
select: (data) => {
|
|
23
|
+
// @ts-expect-error data is in fact inferred as unknown
|
|
24
|
+
// see https://github.com/microsoft/TypeScript/issues/47599
|
|
25
|
+
const result: Expect<Equal<number, typeof data>> = true
|
|
26
|
+
return result
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -132,7 +132,7 @@ describe('Server Side Rendering', () => {
|
|
|
132
132
|
queryKey: key,
|
|
133
133
|
queryFn,
|
|
134
134
|
getNextPageParam: () => undefined,
|
|
135
|
-
|
|
135
|
+
initialPageParam: 0,
|
|
136
136
|
})
|
|
137
137
|
return (
|
|
138
138
|
<ul>
|
|
@@ -146,7 +146,7 @@ describe('Server Side Rendering', () => {
|
|
|
146
146
|
await queryClient.prefetchInfiniteQuery({
|
|
147
147
|
queryKey: key,
|
|
148
148
|
queryFn,
|
|
149
|
-
|
|
149
|
+
initialPageParam: 0,
|
|
150
150
|
})
|
|
151
151
|
|
|
152
152
|
const markup = renderToString(
|