@tanstack/solid-query 5.59.17 → 5.59.20
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/package.json +4 -3
- package/src/__tests__/QueryClientProvider.test.tsx +0 -180
- package/src/__tests__/createInfiniteQuery.test.tsx +0 -2093
- package/src/__tests__/createMutation.test.tsx +0 -1238
- package/src/__tests__/createQueries.test.tsx +0 -732
- package/src/__tests__/createQuery.test-d.tsx +0 -98
- package/src/__tests__/createQuery.test.tsx +0 -6055
- package/src/__tests__/infiniteQueryOptions.test-d.tsx +0 -81
- package/src/__tests__/queryOptions.test-d.tsx +0 -146
- package/src/__tests__/suspense.test.tsx +0 -956
- package/src/__tests__/transition.test.tsx +0 -60
- package/src/__tests__/useIsFetching.test.tsx +0 -251
- package/src/__tests__/useIsMutating.test.tsx +0 -248
- package/src/__tests__/useMutationState.test-d.tsx +0 -21
- package/src/__tests__/useMutationState.test.tsx +0 -68
- package/src/__tests__/utils.tsx +0 -61
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'vitest'
|
|
2
|
-
import { fireEvent, render, waitFor } from '@solidjs/testing-library'
|
|
3
|
-
import { Show, Suspense, createSignal, startTransition } from 'solid-js'
|
|
4
|
-
import { QueryCache, QueryClientProvider, createQuery } from '..'
|
|
5
|
-
import { createQueryClient, queryKey, sleep } from './utils'
|
|
6
|
-
|
|
7
|
-
describe("createQuery's in Suspense mode with transitions", () => {
|
|
8
|
-
const queryCache = new QueryCache()
|
|
9
|
-
const queryClient = createQueryClient({ queryCache })
|
|
10
|
-
|
|
11
|
-
it('should render the content when the transition is done', async () => {
|
|
12
|
-
const key = queryKey()
|
|
13
|
-
|
|
14
|
-
function Suspended() {
|
|
15
|
-
const state = createQuery(() => ({
|
|
16
|
-
queryKey: key,
|
|
17
|
-
queryFn: async () => {
|
|
18
|
-
await sleep(10)
|
|
19
|
-
return true
|
|
20
|
-
},
|
|
21
|
-
}))
|
|
22
|
-
return <Show when={state.data}>Message</Show>
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function Page() {
|
|
26
|
-
const [showSignal, setShowSignal] = createSignal(false)
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div>
|
|
30
|
-
<button
|
|
31
|
-
aria-label="toggle"
|
|
32
|
-
onClick={() =>
|
|
33
|
-
startTransition(() => setShowSignal((value) => !value))
|
|
34
|
-
}
|
|
35
|
-
>
|
|
36
|
-
{showSignal() ? 'Hide' : 'Show'}
|
|
37
|
-
</button>
|
|
38
|
-
<Suspense fallback="Loading">
|
|
39
|
-
<Show when={showSignal()}>
|
|
40
|
-
<Suspended />
|
|
41
|
-
</Show>
|
|
42
|
-
</Suspense>
|
|
43
|
-
</div>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const rendered = render(() => (
|
|
48
|
-
<QueryClientProvider client={queryClient}>
|
|
49
|
-
<Page />
|
|
50
|
-
</QueryClientProvider>
|
|
51
|
-
))
|
|
52
|
-
|
|
53
|
-
await waitFor(() => rendered.getByText('Show'))
|
|
54
|
-
fireEvent.click(rendered.getByLabelText('toggle'))
|
|
55
|
-
|
|
56
|
-
await waitFor(() => rendered.getByText('Message'))
|
|
57
|
-
// verify that the button also updated. See https://github.com/solidjs/solid/issues/1249
|
|
58
|
-
await waitFor(() => rendered.getByText('Hide'))
|
|
59
|
-
})
|
|
60
|
-
})
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { fireEvent, render, waitFor } from '@solidjs/testing-library'
|
|
3
|
-
import { Show, createEffect, createRenderEffect, createSignal } from 'solid-js'
|
|
4
|
-
import { QueryCache, QueryClientProvider, createQuery, useIsFetching } from '..'
|
|
5
|
-
import { createQueryClient, queryKey, setActTimeout, sleep } from './utils'
|
|
6
|
-
|
|
7
|
-
describe('useIsFetching', () => {
|
|
8
|
-
// See https://github.com/tannerlinsley/react-query/issues/105
|
|
9
|
-
it('should update as queries start and stop fetching', async () => {
|
|
10
|
-
const queryCache = new QueryCache()
|
|
11
|
-
const queryClient = createQueryClient({ queryCache })
|
|
12
|
-
const key = queryKey()
|
|
13
|
-
|
|
14
|
-
function IsFetching() {
|
|
15
|
-
const isFetching = useIsFetching()
|
|
16
|
-
return <div>isFetching: {isFetching()}</div>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function Query() {
|
|
20
|
-
const [ready, setReady] = createSignal(false)
|
|
21
|
-
|
|
22
|
-
createQuery(() => ({
|
|
23
|
-
queryKey: key,
|
|
24
|
-
queryFn: async () => {
|
|
25
|
-
await sleep(50)
|
|
26
|
-
return 'test'
|
|
27
|
-
},
|
|
28
|
-
enabled: ready(),
|
|
29
|
-
}))
|
|
30
|
-
|
|
31
|
-
return <button onClick={() => setReady(true)}>setReady</button>
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function Page() {
|
|
35
|
-
return (
|
|
36
|
-
<div>
|
|
37
|
-
<IsFetching />
|
|
38
|
-
<Query />
|
|
39
|
-
</div>
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const rendered = render(() => (
|
|
44
|
-
<QueryClientProvider client={queryClient}>
|
|
45
|
-
<Page />
|
|
46
|
-
</QueryClientProvider>
|
|
47
|
-
))
|
|
48
|
-
|
|
49
|
-
await rendered.findByText('isFetching: 0')
|
|
50
|
-
fireEvent.click(rendered.getByRole('button', { name: /setReady/i }))
|
|
51
|
-
await rendered.findByText('isFetching: 1')
|
|
52
|
-
await rendered.findByText('isFetching: 0')
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should not update state while rendering', async () => {
|
|
56
|
-
const queryCache = new QueryCache()
|
|
57
|
-
const queryClient = createQueryClient({ queryCache })
|
|
58
|
-
|
|
59
|
-
const key1 = queryKey()
|
|
60
|
-
const key2 = queryKey()
|
|
61
|
-
|
|
62
|
-
const isFetchingArray: Array<number> = []
|
|
63
|
-
|
|
64
|
-
function IsFetching() {
|
|
65
|
-
const isFetching = useIsFetching()
|
|
66
|
-
createRenderEffect(() => {
|
|
67
|
-
isFetchingArray.push(isFetching())
|
|
68
|
-
})
|
|
69
|
-
return null
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function FirstQuery() {
|
|
73
|
-
createQuery(() => ({
|
|
74
|
-
queryKey: key1,
|
|
75
|
-
queryFn: async () => {
|
|
76
|
-
await sleep(150)
|
|
77
|
-
return 'data'
|
|
78
|
-
},
|
|
79
|
-
}))
|
|
80
|
-
return null
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function SecondQuery() {
|
|
84
|
-
createQuery(() => ({
|
|
85
|
-
queryKey: key2,
|
|
86
|
-
queryFn: async () => {
|
|
87
|
-
await sleep(200)
|
|
88
|
-
return 'data'
|
|
89
|
-
},
|
|
90
|
-
}))
|
|
91
|
-
return null
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function Page() {
|
|
95
|
-
const [renderSecond, setRenderSecond] = createSignal(false)
|
|
96
|
-
|
|
97
|
-
createEffect(() => {
|
|
98
|
-
setActTimeout(() => {
|
|
99
|
-
setRenderSecond(true)
|
|
100
|
-
}, 100)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<>
|
|
105
|
-
<IsFetching />
|
|
106
|
-
<FirstQuery />
|
|
107
|
-
<Show when={renderSecond()}>
|
|
108
|
-
<SecondQuery />
|
|
109
|
-
</Show>
|
|
110
|
-
</>
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
render(() => (
|
|
115
|
-
<QueryClientProvider client={queryClient}>
|
|
116
|
-
<Page />
|
|
117
|
-
</QueryClientProvider>
|
|
118
|
-
))
|
|
119
|
-
// unlike react, Updating renderSecond wont cause a rerender for FirstQuery
|
|
120
|
-
await waitFor(() => expect(isFetchingArray).toEqual([0, 1, 2, 1, 0]))
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
it('should be able to filter', async () => {
|
|
124
|
-
const queryClient = createQueryClient()
|
|
125
|
-
const key1 = queryKey()
|
|
126
|
-
const key2 = queryKey()
|
|
127
|
-
|
|
128
|
-
const isFetchingArray: Array<number> = []
|
|
129
|
-
|
|
130
|
-
function One() {
|
|
131
|
-
createQuery(() => ({
|
|
132
|
-
queryKey: key1,
|
|
133
|
-
queryFn: async () => {
|
|
134
|
-
await sleep(10)
|
|
135
|
-
return 'test'
|
|
136
|
-
},
|
|
137
|
-
}))
|
|
138
|
-
return null
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function Two() {
|
|
142
|
-
createQuery(() => ({
|
|
143
|
-
queryKey: key2,
|
|
144
|
-
queryFn: async () => {
|
|
145
|
-
await sleep(20)
|
|
146
|
-
return 'test'
|
|
147
|
-
},
|
|
148
|
-
}))
|
|
149
|
-
return null
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function Page() {
|
|
153
|
-
const [started, setStarted] = createSignal(false)
|
|
154
|
-
const isFetching = useIsFetching(() => ({
|
|
155
|
-
queryKey: key1,
|
|
156
|
-
}))
|
|
157
|
-
|
|
158
|
-
createRenderEffect(() => {
|
|
159
|
-
isFetchingArray.push(isFetching())
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<div>
|
|
164
|
-
<button onClick={() => setStarted(true)}>setStarted</button>
|
|
165
|
-
<div>isFetching: {isFetching()}</div>
|
|
166
|
-
<Show when={started()}>
|
|
167
|
-
<>
|
|
168
|
-
<One />
|
|
169
|
-
<Two />
|
|
170
|
-
</>
|
|
171
|
-
</Show>
|
|
172
|
-
</div>
|
|
173
|
-
)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const rendered = render(() => (
|
|
177
|
-
<QueryClientProvider client={queryClient}>
|
|
178
|
-
<Page />
|
|
179
|
-
</QueryClientProvider>
|
|
180
|
-
))
|
|
181
|
-
|
|
182
|
-
await rendered.findByText('isFetching: 0')
|
|
183
|
-
fireEvent.click(rendered.getByRole('button', { name: /setStarted/i }))
|
|
184
|
-
await rendered.findByText('isFetching: 1')
|
|
185
|
-
await rendered.findByText('isFetching: 0')
|
|
186
|
-
// at no point should we have isFetching: 2
|
|
187
|
-
expect(isFetchingArray).toEqual(expect.not.arrayContaining([2]))
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
it('should show the correct fetching state when mounted after a query', async () => {
|
|
191
|
-
const queryClient = createQueryClient()
|
|
192
|
-
const key = queryKey()
|
|
193
|
-
|
|
194
|
-
function Page() {
|
|
195
|
-
createQuery(() => ({
|
|
196
|
-
queryKey: key,
|
|
197
|
-
queryFn: async () => {
|
|
198
|
-
await sleep(10)
|
|
199
|
-
return 'test'
|
|
200
|
-
},
|
|
201
|
-
}))
|
|
202
|
-
|
|
203
|
-
const isFetching = useIsFetching()
|
|
204
|
-
|
|
205
|
-
return (
|
|
206
|
-
<div>
|
|
207
|
-
<div>isFetching: {isFetching()}</div>
|
|
208
|
-
</div>
|
|
209
|
-
)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const rendered = render(() => (
|
|
213
|
-
<QueryClientProvider client={queryClient}>
|
|
214
|
-
<Page />
|
|
215
|
-
</QueryClientProvider>
|
|
216
|
-
))
|
|
217
|
-
|
|
218
|
-
await rendered.findByText('isFetching: 1')
|
|
219
|
-
await rendered.findByText('isFetching: 0')
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
it('should use provided custom queryClient', async () => {
|
|
223
|
-
const queryClient = createQueryClient()
|
|
224
|
-
const key = queryKey()
|
|
225
|
-
|
|
226
|
-
function Page() {
|
|
227
|
-
createQuery(
|
|
228
|
-
() => ({
|
|
229
|
-
queryKey: key,
|
|
230
|
-
queryFn: async () => {
|
|
231
|
-
await sleep(10)
|
|
232
|
-
return 'test'
|
|
233
|
-
},
|
|
234
|
-
}),
|
|
235
|
-
() => queryClient,
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
const isFetching = useIsFetching(undefined, () => queryClient)
|
|
239
|
-
|
|
240
|
-
return (
|
|
241
|
-
<div>
|
|
242
|
-
<div>isFetching: {isFetching()}</div>
|
|
243
|
-
</div>
|
|
244
|
-
)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const rendered = render(() => <Page></Page>)
|
|
248
|
-
|
|
249
|
-
await rendered.findByText('isFetching: 1')
|
|
250
|
-
})
|
|
251
|
-
})
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import { fireEvent, render, waitFor } from '@solidjs/testing-library'
|
|
3
|
-
import { Show, createEffect, createRenderEffect, createSignal } from 'solid-js'
|
|
4
|
-
import * as QueryCore from '@tanstack/query-core'
|
|
5
|
-
import { QueryClientProvider, createMutation, useIsMutating } from '..'
|
|
6
|
-
import { createQueryClient, setActTimeout, sleep } from './utils'
|
|
7
|
-
|
|
8
|
-
describe('useIsMutating', () => {
|
|
9
|
-
it('should return the number of fetching mutations', async () => {
|
|
10
|
-
const isMutatingArray: Array<number> = []
|
|
11
|
-
const queryClient = createQueryClient()
|
|
12
|
-
|
|
13
|
-
function IsMutating() {
|
|
14
|
-
const isMutating = useIsMutating()
|
|
15
|
-
createRenderEffect(() => {
|
|
16
|
-
isMutatingArray.push(isMutating())
|
|
17
|
-
})
|
|
18
|
-
return null
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function Mutations() {
|
|
22
|
-
const { mutate: mutate1 } = createMutation(() => ({
|
|
23
|
-
mutationKey: ['mutation1'],
|
|
24
|
-
mutationFn: async () => {
|
|
25
|
-
await sleep(150)
|
|
26
|
-
return 'data'
|
|
27
|
-
},
|
|
28
|
-
}))
|
|
29
|
-
const { mutate: mutate2 } = createMutation(() => ({
|
|
30
|
-
mutationKey: ['mutation2'],
|
|
31
|
-
mutationFn: async () => {
|
|
32
|
-
await sleep(50)
|
|
33
|
-
return 'data'
|
|
34
|
-
},
|
|
35
|
-
}))
|
|
36
|
-
|
|
37
|
-
createEffect(() => {
|
|
38
|
-
mutate1()
|
|
39
|
-
setActTimeout(() => {
|
|
40
|
-
mutate2()
|
|
41
|
-
}, 50)
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
return null
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function Page() {
|
|
48
|
-
return (
|
|
49
|
-
<div>
|
|
50
|
-
<IsMutating />
|
|
51
|
-
<Mutations />
|
|
52
|
-
</div>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
render(() => (
|
|
57
|
-
<QueryClientProvider client={queryClient}>
|
|
58
|
-
<Page />
|
|
59
|
-
</QueryClientProvider>
|
|
60
|
-
))
|
|
61
|
-
await waitFor(() => expect(isMutatingArray).toEqual([0, 1, 2, 1, 0]))
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should filter correctly by mutationKey', async () => {
|
|
65
|
-
const isMutatingArray: Array<number> = []
|
|
66
|
-
const queryClient = createQueryClient()
|
|
67
|
-
|
|
68
|
-
function IsMutating() {
|
|
69
|
-
const isMutating = useIsMutating(() => ({ mutationKey: ['mutation1'] }))
|
|
70
|
-
createRenderEffect(() => {
|
|
71
|
-
isMutatingArray.push(isMutating())
|
|
72
|
-
})
|
|
73
|
-
return null
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function Page() {
|
|
77
|
-
const { mutate: mutate1 } = createMutation(() => ({
|
|
78
|
-
mutationKey: ['mutation1'],
|
|
79
|
-
mutationFn: async () => {
|
|
80
|
-
await sleep(100)
|
|
81
|
-
return 'data'
|
|
82
|
-
},
|
|
83
|
-
}))
|
|
84
|
-
const { mutate: mutate2 } = createMutation(() => ({
|
|
85
|
-
mutationKey: ['mutation2'],
|
|
86
|
-
mutationFn: async () => {
|
|
87
|
-
await sleep(100)
|
|
88
|
-
return 'data'
|
|
89
|
-
},
|
|
90
|
-
}))
|
|
91
|
-
|
|
92
|
-
createEffect(() => {
|
|
93
|
-
mutate1()
|
|
94
|
-
mutate2()
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
return <IsMutating />
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
render(() => (
|
|
101
|
-
<QueryClientProvider client={queryClient}>
|
|
102
|
-
<Page />
|
|
103
|
-
</QueryClientProvider>
|
|
104
|
-
))
|
|
105
|
-
// Unlike React, IsMutating Wont re-render twice with mutation2
|
|
106
|
-
await waitFor(() => expect(isMutatingArray).toEqual([0, 1, 0]))
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it('should filter correctly by predicate', async () => {
|
|
110
|
-
const isMutatingArray: Array<number> = []
|
|
111
|
-
const queryClient = createQueryClient()
|
|
112
|
-
|
|
113
|
-
function IsMutating() {
|
|
114
|
-
const isMutating = useIsMutating(() => ({
|
|
115
|
-
predicate: (mutation) =>
|
|
116
|
-
mutation.options.mutationKey?.[0] === 'mutation1',
|
|
117
|
-
}))
|
|
118
|
-
createRenderEffect(() => {
|
|
119
|
-
isMutatingArray.push(isMutating())
|
|
120
|
-
})
|
|
121
|
-
return null
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function Page() {
|
|
125
|
-
const { mutate: mutate1 } = createMutation(() => ({
|
|
126
|
-
mutationKey: ['mutation1'],
|
|
127
|
-
mutationFn: async () => {
|
|
128
|
-
await sleep(100)
|
|
129
|
-
return 'data'
|
|
130
|
-
},
|
|
131
|
-
}))
|
|
132
|
-
const { mutate: mutate2 } = createMutation(() => ({
|
|
133
|
-
mutationKey: ['mutation2'],
|
|
134
|
-
mutationFn: async () => {
|
|
135
|
-
await sleep(100)
|
|
136
|
-
return 'data'
|
|
137
|
-
},
|
|
138
|
-
}))
|
|
139
|
-
|
|
140
|
-
createEffect(() => {
|
|
141
|
-
mutate1()
|
|
142
|
-
mutate2()
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
return <IsMutating />
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
render(() => (
|
|
149
|
-
<QueryClientProvider client={queryClient}>
|
|
150
|
-
<Page />
|
|
151
|
-
</QueryClientProvider>
|
|
152
|
-
))
|
|
153
|
-
|
|
154
|
-
// Again, No unnecessary re-renders like React
|
|
155
|
-
await waitFor(() => expect(isMutatingArray).toEqual([0, 1, 0]))
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
it('should use provided custom queryClient', async () => {
|
|
159
|
-
const queryClient = createQueryClient()
|
|
160
|
-
|
|
161
|
-
function Page() {
|
|
162
|
-
const isMutating = useIsMutating(undefined, () => queryClient)
|
|
163
|
-
const { mutate } = createMutation(
|
|
164
|
-
() => ({
|
|
165
|
-
mutationKey: ['mutation1'],
|
|
166
|
-
mutationFn: async () => {
|
|
167
|
-
await sleep(10)
|
|
168
|
-
return 'data'
|
|
169
|
-
},
|
|
170
|
-
}),
|
|
171
|
-
() => queryClient,
|
|
172
|
-
)
|
|
173
|
-
createEffect(() => {
|
|
174
|
-
mutate()
|
|
175
|
-
})
|
|
176
|
-
return (
|
|
177
|
-
<div>
|
|
178
|
-
<div>mutating: {isMutating()}</div>
|
|
179
|
-
</div>
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const rendered = render(() => <Page></Page>)
|
|
184
|
-
|
|
185
|
-
await waitFor(() => rendered.findByText('mutating: 1'))
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
it('should not change state if unmounted', async () => {
|
|
189
|
-
// We have to mock the MutationCache to not unsubscribe
|
|
190
|
-
// the listener when the component is unmounted
|
|
191
|
-
class MutationCacheMock extends QueryCore.MutationCache {
|
|
192
|
-
subscribe(listener: any) {
|
|
193
|
-
super.subscribe(listener)
|
|
194
|
-
return () => void 0
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const MutationCacheSpy = vi
|
|
199
|
-
.spyOn(QueryCore, 'MutationCache')
|
|
200
|
-
.mockImplementation((fn) => {
|
|
201
|
-
return new MutationCacheMock(fn)
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
const queryClient = createQueryClient()
|
|
205
|
-
|
|
206
|
-
function IsMutating() {
|
|
207
|
-
useIsMutating()
|
|
208
|
-
return null
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function Page() {
|
|
212
|
-
const [mounted, setMounted] = createSignal(true)
|
|
213
|
-
const { mutate: mutate1 } = createMutation(() => ({
|
|
214
|
-
mutationKey: ['mutation1'],
|
|
215
|
-
mutationFn: async () => {
|
|
216
|
-
await sleep(10)
|
|
217
|
-
return 'data'
|
|
218
|
-
},
|
|
219
|
-
}))
|
|
220
|
-
|
|
221
|
-
createEffect(() => {
|
|
222
|
-
mutate1()
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
return (
|
|
226
|
-
<div>
|
|
227
|
-
<button onClick={() => setMounted(false)}>unmount</button>
|
|
228
|
-
<Show when={mounted()}>
|
|
229
|
-
<IsMutating />
|
|
230
|
-
</Show>
|
|
231
|
-
</div>
|
|
232
|
-
)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const rendered = render(() => (
|
|
236
|
-
<QueryClientProvider client={queryClient}>
|
|
237
|
-
<Page />
|
|
238
|
-
</QueryClientProvider>
|
|
239
|
-
))
|
|
240
|
-
fireEvent.click(rendered.getByText('unmount'))
|
|
241
|
-
|
|
242
|
-
// Should not display the console error
|
|
243
|
-
// "Warning: Can't perform a React state update on an unmounted component"
|
|
244
|
-
|
|
245
|
-
await sleep(20)
|
|
246
|
-
MutationCacheSpy.mockRestore()
|
|
247
|
-
})
|
|
248
|
-
})
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
-
import { useMutationState } from '../useMutationState'
|
|
3
|
-
import type { MutationState, MutationStatus } from '@tanstack/query-core'
|
|
4
|
-
|
|
5
|
-
describe('useMutationState', () => {
|
|
6
|
-
it('should default to QueryState', () => {
|
|
7
|
-
const result = useMutationState(() => ({
|
|
8
|
-
filters: { status: 'pending' },
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
|
-
expectTypeOf(result()).toEqualTypeOf<Array<MutationState>>()
|
|
12
|
-
})
|
|
13
|
-
it('should infer with select', () => {
|
|
14
|
-
const result = useMutationState(() => ({
|
|
15
|
-
filters: { status: 'pending' },
|
|
16
|
-
select: (mutation) => mutation.state.status,
|
|
17
|
-
}))
|
|
18
|
-
|
|
19
|
-
expectTypeOf(result()).toEqualTypeOf<Array<MutationStatus>>()
|
|
20
|
-
})
|
|
21
|
-
})
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { fireEvent, render, waitFor } from '@solidjs/testing-library'
|
|
3
|
-
import { createEffect } from 'solid-js'
|
|
4
|
-
import { useMutationState } from '../useMutationState'
|
|
5
|
-
import { createMutation } from '../createMutation'
|
|
6
|
-
import { QueryClientProvider } from '../QueryClientProvider'
|
|
7
|
-
import { createQueryClient, sleep } from './utils'
|
|
8
|
-
|
|
9
|
-
describe('useMutationState', () => {
|
|
10
|
-
it('should return variables after calling mutate', async () => {
|
|
11
|
-
const queryClient = createQueryClient()
|
|
12
|
-
const variables: Array<Array<unknown>> = []
|
|
13
|
-
const mutationKey = ['mutation']
|
|
14
|
-
|
|
15
|
-
function Variables() {
|
|
16
|
-
const states = useMutationState(() => ({
|
|
17
|
-
filters: { mutationKey, status: 'pending' },
|
|
18
|
-
select: (mutation) => mutation.state.variables,
|
|
19
|
-
}))
|
|
20
|
-
|
|
21
|
-
createEffect(() => {
|
|
22
|
-
variables.push(states())
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
return null
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function Mutate() {
|
|
29
|
-
const mutation = createMutation(() => ({
|
|
30
|
-
mutationKey,
|
|
31
|
-
mutationFn: async (input: number) => {
|
|
32
|
-
await sleep(150)
|
|
33
|
-
return 'data' + input
|
|
34
|
-
},
|
|
35
|
-
}))
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div>
|
|
39
|
-
data: {mutation.data ?? 'null'}
|
|
40
|
-
<button onClick={() => mutation.mutate(1)}>mutate</button>
|
|
41
|
-
</div>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function Page() {
|
|
46
|
-
return (
|
|
47
|
-
<div>
|
|
48
|
-
<Variables />
|
|
49
|
-
<Mutate />
|
|
50
|
-
</div>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const rendered = render(() => (
|
|
55
|
-
<QueryClientProvider client={queryClient}>
|
|
56
|
-
<Page />
|
|
57
|
-
</QueryClientProvider>
|
|
58
|
-
))
|
|
59
|
-
|
|
60
|
-
await waitFor(() => rendered.getByText('data: null'))
|
|
61
|
-
|
|
62
|
-
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
|
|
63
|
-
|
|
64
|
-
await waitFor(() => rendered.getByText('data: data1'))
|
|
65
|
-
|
|
66
|
-
expect(variables).toEqual([[], [1], []])
|
|
67
|
-
})
|
|
68
|
-
})
|
package/src/__tests__/utils.tsx
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { vi } from 'vitest'
|
|
2
|
-
import { Show, createEffect, createSignal, onCleanup } from 'solid-js'
|
|
3
|
-
import { onlineManager } from '@tanstack/query-core'
|
|
4
|
-
import { QueryClient } from '../QueryClient'
|
|
5
|
-
import type { QueryClientConfig } from '..'
|
|
6
|
-
import type { ParentProps } from 'solid-js'
|
|
7
|
-
import type { MockInstance } from 'vitest'
|
|
8
|
-
|
|
9
|
-
let queryKeyCount = 0
|
|
10
|
-
export function queryKey() {
|
|
11
|
-
queryKeyCount++
|
|
12
|
-
return [`query_${queryKeyCount}`]
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function Blink(
|
|
16
|
-
props: {
|
|
17
|
-
duration: number
|
|
18
|
-
} & ParentProps,
|
|
19
|
-
) {
|
|
20
|
-
const [shouldShow, setShouldShow] = createSignal<boolean>(true)
|
|
21
|
-
|
|
22
|
-
createEffect(() => {
|
|
23
|
-
setShouldShow(true)
|
|
24
|
-
const timeout = setActTimeout(() => setShouldShow(false), props.duration)
|
|
25
|
-
onCleanup(() => clearTimeout(timeout))
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<Show when={shouldShow()} fallback={<>off</>}>
|
|
30
|
-
<>{props.children}</>
|
|
31
|
-
</Show>
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function createQueryClient(config?: QueryClientConfig): QueryClient {
|
|
36
|
-
return new QueryClient(config)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function mockVisibilityState(
|
|
40
|
-
value: DocumentVisibilityState,
|
|
41
|
-
): MockInstance<() => DocumentVisibilityState> {
|
|
42
|
-
return vi.spyOn(document, 'visibilityState', 'get').mockReturnValue(value)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function mockOnlineManagerIsOnline(
|
|
46
|
-
value: boolean,
|
|
47
|
-
): MockInstance<() => boolean> {
|
|
48
|
-
return vi.spyOn(onlineManager, 'isOnline').mockReturnValue(value)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function sleep(timeout: number): Promise<void> {
|
|
52
|
-
return new Promise((resolve, _reject) => {
|
|
53
|
-
setTimeout(resolve, timeout)
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function setActTimeout(fn: () => void, ms?: number) {
|
|
58
|
-
return setTimeout(() => {
|
|
59
|
-
fn()
|
|
60
|
-
}, ms)
|
|
61
|
-
}
|