@tanstack/solid-query 5.0.5 → 5.2.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/package.json
CHANGED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, expect, expectTypeOf, 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, doNotExecute, sleep } from './utils'
|
|
8
|
+
import type { MutationState, MutationStatus } from '@tanstack/query-core'
|
|
9
|
+
|
|
10
|
+
describe('useMutationState', () => {
|
|
11
|
+
describe('types', () => {
|
|
12
|
+
it('should default to QueryState', () => {
|
|
13
|
+
doNotExecute(() => {
|
|
14
|
+
const result = useMutationState(() => ({
|
|
15
|
+
filters: { status: 'pending' },
|
|
16
|
+
}))
|
|
17
|
+
|
|
18
|
+
expectTypeOf<Array<MutationState>>(result())
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
it('should infer with select', () => {
|
|
22
|
+
doNotExecute(() => {
|
|
23
|
+
const result = useMutationState(() => ({
|
|
24
|
+
filters: { status: 'pending' },
|
|
25
|
+
select: (mutation) => mutation.state.status,
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
expectTypeOf<Array<MutationStatus>>(result())
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
it('should return variables after calling mutate', async () => {
|
|
33
|
+
const queryClient = createQueryClient()
|
|
34
|
+
const variables: Array<Array<unknown>> = []
|
|
35
|
+
const mutationKey = ['mutation']
|
|
36
|
+
|
|
37
|
+
function Variables() {
|
|
38
|
+
const states = useMutationState(() => ({
|
|
39
|
+
filters: { mutationKey, status: 'pending' },
|
|
40
|
+
select: (mutation) => mutation.state.variables,
|
|
41
|
+
}))
|
|
42
|
+
|
|
43
|
+
createEffect(() => {
|
|
44
|
+
variables.push(states())
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function Mutate() {
|
|
51
|
+
const mutation = createMutation(() => ({
|
|
52
|
+
mutationKey,
|
|
53
|
+
mutationFn: async (input: number) => {
|
|
54
|
+
await sleep(150)
|
|
55
|
+
return 'data' + input
|
|
56
|
+
},
|
|
57
|
+
}))
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div>
|
|
61
|
+
data: {mutation.data ?? 'null'}
|
|
62
|
+
<button onClick={() => mutation.mutate(1)}>mutate</button>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function Page() {
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
<Variables />
|
|
71
|
+
<Mutate />
|
|
72
|
+
</div>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const rendered = render(() => (
|
|
77
|
+
<QueryClientProvider client={queryClient}>
|
|
78
|
+
<Page />
|
|
79
|
+
</QueryClientProvider>
|
|
80
|
+
))
|
|
81
|
+
|
|
82
|
+
await waitFor(() => rendered.getByText('data: null'))
|
|
83
|
+
|
|
84
|
+
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
|
|
85
|
+
|
|
86
|
+
await waitFor(() => rendered.getByText('data: data1'))
|
|
87
|
+
|
|
88
|
+
expect(variables).toEqual([[], [1], []])
|
|
89
|
+
})
|
|
90
|
+
})
|
package/src/__tests__/utils.tsx
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createEffect, createMemo, createSignal, onCleanup } from 'solid-js'
|
|
2
|
+
import { replaceEqualDeep } from '@tanstack/query-core'
|
|
3
|
+
import { useQueryClient } from './QueryClientProvider'
|
|
4
|
+
import type {
|
|
5
|
+
DefaultError,
|
|
6
|
+
Mutation,
|
|
7
|
+
MutationCache,
|
|
8
|
+
MutationFilters,
|
|
9
|
+
MutationState,
|
|
10
|
+
} from '@tanstack/query-core'
|
|
11
|
+
import type { Accessor } from 'solid-js'
|
|
12
|
+
import type { QueryClient } from './QueryClient'
|
|
13
|
+
|
|
14
|
+
type MutationStateOptions<TResult = MutationState> = {
|
|
15
|
+
filters?: MutationFilters
|
|
16
|
+
select?: (
|
|
17
|
+
mutation: Mutation<unknown, DefaultError, unknown, unknown>,
|
|
18
|
+
) => TResult
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getResult<TResult = MutationState>(
|
|
22
|
+
mutationCache: MutationCache,
|
|
23
|
+
options: MutationStateOptions<TResult>,
|
|
24
|
+
): Array<TResult> {
|
|
25
|
+
return mutationCache
|
|
26
|
+
.findAll(options.filters)
|
|
27
|
+
.map(
|
|
28
|
+
(mutation): TResult =>
|
|
29
|
+
(options.select
|
|
30
|
+
? options.select(
|
|
31
|
+
mutation as Mutation<unknown, DefaultError, unknown, unknown>,
|
|
32
|
+
)
|
|
33
|
+
: mutation.state) as TResult,
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function useMutationState<TResult = MutationState>(
|
|
38
|
+
options: Accessor<MutationStateOptions<TResult>> = () => ({}),
|
|
39
|
+
queryClient?: Accessor<QueryClient>,
|
|
40
|
+
): Accessor<Array<TResult>> {
|
|
41
|
+
const client = createMemo(() => useQueryClient(queryClient?.()))
|
|
42
|
+
const mutationCache = createMemo(() => client().getMutationCache())
|
|
43
|
+
|
|
44
|
+
const [result, setResult] = createSignal(
|
|
45
|
+
getResult(mutationCache(), options()),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
createEffect(() => {
|
|
49
|
+
const unsubscribe = mutationCache().subscribe(() => {
|
|
50
|
+
const nextResult = replaceEqualDeep(
|
|
51
|
+
result(),
|
|
52
|
+
getResult(mutationCache(), options()),
|
|
53
|
+
)
|
|
54
|
+
if (result() !== nextResult) {
|
|
55
|
+
setResult(nextResult)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
onCleanup(unsubscribe)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
return result
|
|
63
|
+
}
|