@tanstack/solid-query 4.24.10 → 5.0.0-alpha.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.
- package/build/cjs/index.js +300 -0
- package/build/cjs/index.js.map +1 -0
- package/build/esm/index.js +285 -0
- package/build/esm/index.js.map +1 -0
- package/build/source/QueryClientProvider.jsx +21 -0
- package/build/source/__tests__/QueryClientProvider.test.jsx +120 -0
- package/build/{solid → source}/__tests__/createInfiniteQuery.test.jsx +228 -372
- package/build/{solid → source}/__tests__/createMutation.test.jsx +174 -165
- package/build/{solid → source}/__tests__/createQueries.test.jsx +86 -367
- package/build/{solid → source}/__tests__/createQuery.test.jsx +991 -943
- package/build/{solid → source}/__tests__/createQuery.types.test.jsx +35 -24
- package/build/{solid → source}/__tests__/suspense.test.jsx +177 -148
- package/build/{solid → source}/__tests__/transition.test.jsx +7 -4
- package/build/{solid → source}/__tests__/useIsFetching.test.jsx +68 -85
- package/build/{solid → source}/__tests__/useIsMutating.test.jsx +78 -93
- package/build/{solid → source}/__tests__/utils.jsx +3 -9
- package/build/source/createBaseQuery.js +147 -0
- package/build/source/createInfiniteQuery.js +8 -0
- package/build/{solid → source}/createMutation.js +7 -9
- package/build/source/createQueries.js +32 -0
- package/build/source/createQuery.js +6 -0
- package/build/{solid → source}/index.js +5 -3
- package/build/source/setBatchUpdatesFn.js +3 -0
- package/build/source/useIsFetching.js +12 -0
- package/build/source/useIsMutating.js +12 -0
- package/build/source/utils.js +7 -0
- package/build/types/QueryClientProvider.d.ts +9 -0
- package/build/{lib → types}/__tests__/utils.d.ts +3 -8
- package/build/types/createBaseQuery.d.ts +4 -0
- package/build/types/createInfiniteQuery.d.ts +3 -0
- package/build/types/createMutation.d.ts +3 -0
- package/build/{lib → types}/createQueries.d.ts +10 -8
- package/build/types/createQuery.d.ts +11 -0
- package/build/{lib → types}/index.d.ts +4 -3
- package/build/types/setBatchUpdatesFn.d.ts +1 -0
- package/build/types/types.d.ts +33 -0
- package/build/types/useIsFetching.d.ts +8 -0
- package/build/types/useIsMutating.d.ts +8 -0
- package/build/types/utils.d.ts +1 -0
- package/build/umd/index.js +2 -0
- package/build/umd/index.js.map +1 -0
- package/package.json +25 -17
- package/src/QueryClientProvider.tsx +17 -86
- package/src/__tests__/QueryClientProvider.test.tsx +37 -140
- package/src/__tests__/createInfiniteQuery.test.tsx +277 -508
- package/src/__tests__/createMutation.test.tsx +177 -225
- package/src/__tests__/createQueries.test.tsx +180 -528
- package/src/__tests__/createQuery.test.tsx +970 -1200
- package/src/__tests__/createQuery.types.test.tsx +30 -25
- package/src/__tests__/suspense.test.tsx +141 -178
- package/src/__tests__/transition.test.tsx +7 -4
- package/src/__tests__/useIsFetching.test.tsx +77 -122
- package/src/__tests__/useIsMutating.test.tsx +83 -128
- package/src/__tests__/utils.tsx +4 -11
- package/src/createBaseQuery.ts +148 -60
- package/src/createInfiniteQuery.ts +16 -94
- package/src/createMutation.ts +9 -63
- package/src/createQueries.ts +44 -55
- package/src/createQuery.ts +42 -127
- package/src/index.ts +6 -3
- package/src/setBatchUpdatesFn.ts +4 -0
- package/src/types.ts +81 -75
- package/src/useIsFetching.ts +12 -44
- package/src/useIsMutating.ts +13 -29
- package/src/utils.ts +5 -79
- package/build/lib/QueryClientProvider.d.ts +0 -24
- package/build/lib/QueryClientProvider.esm.js +0 -74
- package/build/lib/QueryClientProvider.esm.js.map +0 -1
- package/build/lib/QueryClientProvider.js +0 -80
- package/build/lib/QueryClientProvider.js.map +0 -1
- package/build/lib/QueryClientProvider.mjs +0 -74
- package/build/lib/QueryClientProvider.mjs.map +0 -1
- package/build/lib/createBaseQuery.d.ts +0 -4
- package/build/lib/createBaseQuery.esm.js +0 -93
- package/build/lib/createBaseQuery.esm.js.map +0 -1
- package/build/lib/createBaseQuery.js +0 -97
- package/build/lib/createBaseQuery.js.map +0 -1
- package/build/lib/createBaseQuery.mjs +0 -93
- package/build/lib/createBaseQuery.mjs.map +0 -1
- package/build/lib/createInfiniteQuery.d.ts +0 -5
- package/build/lib/createInfiniteQuery.esm.js +0 -20
- package/build/lib/createInfiniteQuery.esm.js.map +0 -1
- package/build/lib/createInfiniteQuery.js +0 -24
- package/build/lib/createInfiniteQuery.js.map +0 -1
- package/build/lib/createInfiniteQuery.mjs +0 -20
- package/build/lib/createInfiniteQuery.mjs.map +0 -1
- package/build/lib/createMutation.d.ts +0 -6
- package/build/lib/createMutation.esm.js +0 -45
- package/build/lib/createMutation.esm.js.map +0 -1
- package/build/lib/createMutation.js +0 -49
- package/build/lib/createMutation.js.map +0 -1
- package/build/lib/createMutation.mjs +0 -45
- package/build/lib/createMutation.mjs.map +0 -1
- package/build/lib/createQueries.esm.js +0 -54
- package/build/lib/createQueries.esm.js.map +0 -1
- package/build/lib/createQueries.js +0 -58
- package/build/lib/createQueries.js.map +0 -1
- package/build/lib/createQueries.mjs +0 -54
- package/build/lib/createQueries.mjs.map +0 -1
- package/build/lib/createQuery.d.ts +0 -23
- package/build/lib/createQuery.esm.js +0 -25
- package/build/lib/createQuery.esm.js.map +0 -1
- package/build/lib/createQuery.js +0 -29
- package/build/lib/createQuery.js.map +0 -1
- package/build/lib/createQuery.mjs +0 -25
- package/build/lib/createQuery.mjs.map +0 -1
- package/build/lib/index.esm.js +0 -9
- package/build/lib/index.esm.js.map +0 -1
- package/build/lib/index.js +0 -31
- package/build/lib/index.js.map +0 -1
- package/build/lib/index.mjs +0 -9
- package/build/lib/index.mjs.map +0 -1
- package/build/lib/types.d.ts +0 -47
- package/build/lib/useIsFetching.d.ts +0 -7
- package/build/lib/useIsFetching.esm.js +0 -29
- package/build/lib/useIsFetching.esm.js.map +0 -1
- package/build/lib/useIsFetching.js +0 -33
- package/build/lib/useIsFetching.js.map +0 -1
- package/build/lib/useIsFetching.mjs +0 -29
- package/build/lib/useIsFetching.mjs.map +0 -1
- package/build/lib/useIsMutating.d.ts +0 -8
- package/build/lib/useIsMutating.esm.js +0 -22
- package/build/lib/useIsMutating.esm.js.map +0 -1
- package/build/lib/useIsMutating.js +0 -26
- package/build/lib/useIsMutating.js.map +0 -1
- package/build/lib/useIsMutating.mjs +0 -22
- package/build/lib/useIsMutating.mjs.map +0 -1
- package/build/lib/utils.d.ts +0 -14
- package/build/lib/utils.esm.js +0 -63
- package/build/lib/utils.esm.js.map +0 -1
- package/build/lib/utils.js +0 -72
- package/build/lib/utils.js.map +0 -1
- package/build/lib/utils.mjs +0 -63
- package/build/lib/utils.mjs.map +0 -1
- package/build/solid/QueryClientProvider.jsx +0 -49
- package/build/solid/__tests__/QueryClientProvider.test.jsx +0 -185
- package/build/solid/createBaseQuery.js +0 -81
- package/build/solid/createInfiniteQuery.js +0 -16
- package/build/solid/createQueries.js +0 -39
- package/build/solid/createQuery.js +0 -16
- package/build/solid/useIsFetching.js +0 -23
- package/build/solid/useIsMutating.js +0 -16
- package/build/solid/utils.js +0 -45
- package/build/umd/index.development.js +0 -3577
- package/build/umd/index.development.js.map +0 -1
- package/build/umd/index.production.js +0 -2
- package/build/umd/index.production.js.map +0 -1
- /package/build/{solid → source}/types.js +0 -0
- /package/build/{lib → types}/__tests__/QueryClientProvider.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createInfiniteQuery.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createMutation.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createQueries.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createQuery.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createQuery.types.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/suspense.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/transition.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/useIsFetching.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/useIsMutating.test.d.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fireEvent, render, screen, waitFor } from 'solid-testing-library';
|
|
2
|
-
import {
|
|
2
|
+
import { createEffect, createRenderEffect, createSignal, Show } from 'solid-js';
|
|
3
3
|
import { createQuery, QueryCache, QueryClientProvider, useIsFetching } from '..';
|
|
4
4
|
import { createQueryClient, queryKey, setActTimeout, sleep } from './utils';
|
|
5
5
|
describe('useIsFetching', () => {
|
|
@@ -14,14 +14,14 @@ describe('useIsFetching', () => {
|
|
|
14
14
|
}
|
|
15
15
|
function Query() {
|
|
16
16
|
const [ready, setReady] = createSignal(false);
|
|
17
|
-
createQuery(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return ready();
|
|
17
|
+
createQuery(() => ({
|
|
18
|
+
queryKey: key,
|
|
19
|
+
queryFn: async () => {
|
|
20
|
+
await sleep(50);
|
|
21
|
+
return 'test';
|
|
23
22
|
},
|
|
24
|
-
|
|
23
|
+
enabled: ready(),
|
|
24
|
+
}));
|
|
25
25
|
return <button onClick={() => setReady(true)}>setReady</button>;
|
|
26
26
|
}
|
|
27
27
|
function Page() {
|
|
@@ -52,17 +52,23 @@ describe('useIsFetching', () => {
|
|
|
52
52
|
return null;
|
|
53
53
|
}
|
|
54
54
|
function FirstQuery() {
|
|
55
|
-
createQuery(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
createQuery(() => ({
|
|
56
|
+
queryKey: key1,
|
|
57
|
+
queryFn: async () => {
|
|
58
|
+
await sleep(150);
|
|
59
|
+
return 'data';
|
|
60
|
+
},
|
|
61
|
+
}));
|
|
59
62
|
return null;
|
|
60
63
|
}
|
|
61
64
|
function SecondQuery() {
|
|
62
|
-
createQuery(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
createQuery(() => ({
|
|
66
|
+
queryKey: key2,
|
|
67
|
+
queryFn: async () => {
|
|
68
|
+
await sleep(200);
|
|
69
|
+
return 'data';
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
66
72
|
return null;
|
|
67
73
|
}
|
|
68
74
|
function Page() {
|
|
@@ -70,7 +76,7 @@ describe('useIsFetching', () => {
|
|
|
70
76
|
createEffect(() => {
|
|
71
77
|
setActTimeout(() => {
|
|
72
78
|
setRenderSecond(true);
|
|
73
|
-
},
|
|
79
|
+
}, 100);
|
|
74
80
|
});
|
|
75
81
|
return (<>
|
|
76
82
|
<IsFetching />
|
|
@@ -92,22 +98,32 @@ describe('useIsFetching', () => {
|
|
|
92
98
|
const key2 = queryKey();
|
|
93
99
|
const isFetchings = [];
|
|
94
100
|
function One() {
|
|
95
|
-
createQuery(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
createQuery(() => ({
|
|
102
|
+
queryKey: key1,
|
|
103
|
+
queryFn: async () => {
|
|
104
|
+
await sleep(10);
|
|
105
|
+
return 'test';
|
|
106
|
+
},
|
|
107
|
+
}));
|
|
99
108
|
return null;
|
|
100
109
|
}
|
|
101
110
|
function Two() {
|
|
102
|
-
createQuery(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
111
|
+
createQuery(() => ({
|
|
112
|
+
queryKey: key2,
|
|
113
|
+
queryFn: async () => {
|
|
114
|
+
await sleep(20);
|
|
115
|
+
return 'test';
|
|
116
|
+
},
|
|
117
|
+
}));
|
|
106
118
|
return null;
|
|
107
119
|
}
|
|
108
120
|
function Page() {
|
|
109
121
|
const [started, setStarted] = createSignal(false);
|
|
110
|
-
const isFetching = useIsFetching(
|
|
122
|
+
const isFetching = useIsFetching(() => ({
|
|
123
|
+
filters: {
|
|
124
|
+
queryKey: key1,
|
|
125
|
+
},
|
|
126
|
+
}));
|
|
111
127
|
createRenderEffect(() => {
|
|
112
128
|
isFetchings.push(isFetching());
|
|
113
129
|
});
|
|
@@ -132,69 +148,17 @@ describe('useIsFetching', () => {
|
|
|
132
148
|
// at no point should we have isFetching: 2
|
|
133
149
|
expect(isFetchings).toEqual(expect.not.arrayContaining([2]));
|
|
134
150
|
});
|
|
135
|
-
describe('with custom context', () => {
|
|
136
|
-
it('should update as queries start and stop fetching', async () => {
|
|
137
|
-
const context = createContext(undefined);
|
|
138
|
-
const queryCache = new QueryCache();
|
|
139
|
-
const queryClient = createQueryClient({ queryCache });
|
|
140
|
-
const key = queryKey();
|
|
141
|
-
function Page() {
|
|
142
|
-
const [ready, setReady] = createSignal(false);
|
|
143
|
-
const isFetching = useIsFetching(undefined, { context: context });
|
|
144
|
-
createQuery(key, async () => {
|
|
145
|
-
await sleep(50);
|
|
146
|
-
return 'test';
|
|
147
|
-
}, {
|
|
148
|
-
get enabled() {
|
|
149
|
-
return ready();
|
|
150
|
-
},
|
|
151
|
-
context,
|
|
152
|
-
});
|
|
153
|
-
return (<div>
|
|
154
|
-
<div>isFetching: {isFetching}</div>
|
|
155
|
-
<button onClick={() => setReady(true)}>setReady</button>
|
|
156
|
-
</div>);
|
|
157
|
-
}
|
|
158
|
-
render(() => (<QueryClientProvider client={queryClient} context={context}>
|
|
159
|
-
<Page />
|
|
160
|
-
</QueryClientProvider>));
|
|
161
|
-
await screen.findByText('isFetching: 0');
|
|
162
|
-
fireEvent.click(screen.getByRole('button', { name: /setReady/i }));
|
|
163
|
-
await screen.findByText('isFetching: 1');
|
|
164
|
-
await screen.findByText('isFetching: 0');
|
|
165
|
-
});
|
|
166
|
-
it('should throw if the context is not passed to useIsFetching', async () => {
|
|
167
|
-
const context = createContext(undefined);
|
|
168
|
-
const queryCache = new QueryCache();
|
|
169
|
-
const queryClient = createQueryClient({ queryCache });
|
|
170
|
-
const key = queryKey();
|
|
171
|
-
function Page() {
|
|
172
|
-
const isFetching = useIsFetching();
|
|
173
|
-
createQuery(key, async () => 'test', {
|
|
174
|
-
enabled: true,
|
|
175
|
-
context,
|
|
176
|
-
useErrorBoundary: true,
|
|
177
|
-
});
|
|
178
|
-
return (<div>
|
|
179
|
-
<div>isFetching: {isFetching}</div>
|
|
180
|
-
</div>);
|
|
181
|
-
}
|
|
182
|
-
render(() => (<QueryClientProvider client={queryClient} context={context}>
|
|
183
|
-
<ErrorBoundary fallback={() => <div>error boundary</div>}>
|
|
184
|
-
<Page />
|
|
185
|
-
</ErrorBoundary>
|
|
186
|
-
</QueryClientProvider>));
|
|
187
|
-
await waitFor(() => screen.getByText('error boundary'));
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
151
|
it('should show the correct fetching state when mounted after a query', async () => {
|
|
191
152
|
const queryClient = createQueryClient();
|
|
192
153
|
const key = queryKey();
|
|
193
154
|
function Page() {
|
|
194
|
-
createQuery(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
155
|
+
createQuery(() => ({
|
|
156
|
+
queryKey: key,
|
|
157
|
+
queryFn: async () => {
|
|
158
|
+
await sleep(10);
|
|
159
|
+
return 'test';
|
|
160
|
+
},
|
|
161
|
+
}));
|
|
198
162
|
const isFetching = useIsFetching();
|
|
199
163
|
return (<div>
|
|
200
164
|
<div>isFetching: {isFetching()}</div>
|
|
@@ -206,4 +170,23 @@ describe('useIsFetching', () => {
|
|
|
206
170
|
await screen.findByText('isFetching: 1');
|
|
207
171
|
await screen.findByText('isFetching: 0');
|
|
208
172
|
});
|
|
173
|
+
it('should use provided custom queryClient', async () => {
|
|
174
|
+
const queryClient = createQueryClient();
|
|
175
|
+
const key = queryKey();
|
|
176
|
+
function Page() {
|
|
177
|
+
createQuery(() => ({
|
|
178
|
+
queryKey: key,
|
|
179
|
+
queryFn: async () => {
|
|
180
|
+
await sleep(10);
|
|
181
|
+
return 'test';
|
|
182
|
+
},
|
|
183
|
+
}), () => queryClient);
|
|
184
|
+
const isFetching = useIsFetching(() => ({ queryClient }));
|
|
185
|
+
return (<div>
|
|
186
|
+
<div>isFetching: {isFetching}</div>
|
|
187
|
+
</div>);
|
|
188
|
+
}
|
|
189
|
+
render(() => <Page></Page>);
|
|
190
|
+
await screen.findByText('isFetching: 1');
|
|
191
|
+
});
|
|
209
192
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fireEvent, screen, waitFor } from 'solid-testing-library';
|
|
2
|
-
import { createMutation,
|
|
2
|
+
import { createMutation, QueryClientProvider, useIsMutating } from '..';
|
|
3
3
|
import { createQueryClient, sleep } from './utils';
|
|
4
|
-
import {
|
|
4
|
+
import { createEffect, createRenderEffect, createSignal, Show } from 'solid-js';
|
|
5
5
|
import { render } from 'solid-testing-library';
|
|
6
6
|
import * as MutationCacheModule from '../../../query-core/src/mutationCache';
|
|
7
7
|
import { setActTimeout } from './utils';
|
|
@@ -17,14 +17,20 @@ describe('useIsMutating', () => {
|
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
function Mutations() {
|
|
20
|
-
const { mutate: mutate1 } = createMutation(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
})
|
|
20
|
+
const { mutate: mutate1 } = createMutation(() => ({
|
|
21
|
+
mutationKey: ['mutation1'],
|
|
22
|
+
mutationFn: async () => {
|
|
23
|
+
await sleep(150);
|
|
24
|
+
return 'data';
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
const { mutate: mutate2 } = createMutation(() => ({
|
|
28
|
+
mutationKey: ['mutation2'],
|
|
29
|
+
mutationFn: async () => {
|
|
30
|
+
await sleep(50);
|
|
31
|
+
return 'data';
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
28
34
|
createEffect(() => {
|
|
29
35
|
mutate1();
|
|
30
36
|
setActTimeout(() => {
|
|
@@ -48,21 +54,29 @@ describe('useIsMutating', () => {
|
|
|
48
54
|
const isMutatings = [];
|
|
49
55
|
const queryClient = createQueryClient();
|
|
50
56
|
function IsMutating() {
|
|
51
|
-
const isMutating = useIsMutating(
|
|
57
|
+
const isMutating = useIsMutating(() => ({
|
|
58
|
+
filters: { mutationKey: ['mutation1'] },
|
|
59
|
+
}));
|
|
52
60
|
createRenderEffect(() => {
|
|
53
61
|
isMutatings.push(isMutating());
|
|
54
62
|
});
|
|
55
63
|
return null;
|
|
56
64
|
}
|
|
57
65
|
function Page() {
|
|
58
|
-
const { mutate: mutate1 } = createMutation(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
})
|
|
66
|
+
const { mutate: mutate1 } = createMutation(() => ({
|
|
67
|
+
mutationKey: ['mutation1'],
|
|
68
|
+
mutationFn: async () => {
|
|
69
|
+
await sleep(100);
|
|
70
|
+
return 'data';
|
|
71
|
+
},
|
|
72
|
+
}));
|
|
73
|
+
const { mutate: mutate2 } = createMutation(() => ({
|
|
74
|
+
mutationKey: ['mutation2'],
|
|
75
|
+
mutationFn: async () => {
|
|
76
|
+
await sleep(100);
|
|
77
|
+
return 'data';
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
66
80
|
createEffect(() => {
|
|
67
81
|
mutate1();
|
|
68
82
|
mutate2();
|
|
@@ -79,23 +93,31 @@ describe('useIsMutating', () => {
|
|
|
79
93
|
const isMutatings = [];
|
|
80
94
|
const queryClient = createQueryClient();
|
|
81
95
|
function IsMutating() {
|
|
82
|
-
const isMutating = useIsMutating({
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
const isMutating = useIsMutating(() => ({
|
|
97
|
+
filters: {
|
|
98
|
+
predicate: (mutation) => mutation.options.mutationKey?.[0] === 'mutation1',
|
|
99
|
+
},
|
|
100
|
+
}));
|
|
85
101
|
createRenderEffect(() => {
|
|
86
102
|
isMutatings.push(isMutating());
|
|
87
103
|
});
|
|
88
104
|
return null;
|
|
89
105
|
}
|
|
90
106
|
function Page() {
|
|
91
|
-
const { mutate: mutate1 } = createMutation(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})
|
|
107
|
+
const { mutate: mutate1 } = createMutation(() => ({
|
|
108
|
+
mutationKey: ['mutation1'],
|
|
109
|
+
mutationFn: async () => {
|
|
110
|
+
await sleep(100);
|
|
111
|
+
return 'data';
|
|
112
|
+
},
|
|
113
|
+
}));
|
|
114
|
+
const { mutate: mutate2 } = createMutation(() => ({
|
|
115
|
+
mutationKey: ['mutation2'],
|
|
116
|
+
mutationFn: async () => {
|
|
117
|
+
await sleep(100);
|
|
118
|
+
return 'data';
|
|
119
|
+
},
|
|
120
|
+
}));
|
|
99
121
|
createEffect(() => {
|
|
100
122
|
mutate1();
|
|
101
123
|
mutate2();
|
|
@@ -129,10 +151,13 @@ describe('useIsMutating', () => {
|
|
|
129
151
|
}
|
|
130
152
|
function Page() {
|
|
131
153
|
const [mounted, setMounted] = createSignal(true);
|
|
132
|
-
const { mutate: mutate1 } = createMutation(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
154
|
+
const { mutate: mutate1 } = createMutation(() => ({
|
|
155
|
+
mutationKey: ['mutation1'],
|
|
156
|
+
mutationFn: async () => {
|
|
157
|
+
await sleep(10);
|
|
158
|
+
return 'data';
|
|
159
|
+
},
|
|
160
|
+
}));
|
|
136
161
|
createEffect(() => {
|
|
137
162
|
mutate1();
|
|
138
163
|
});
|
|
@@ -152,65 +177,25 @@ describe('useIsMutating', () => {
|
|
|
152
177
|
await sleep(20);
|
|
153
178
|
MutationCacheSpy.mockRestore();
|
|
154
179
|
});
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
isMutatings.push(isMutating());
|
|
164
|
-
});
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
function Page() {
|
|
168
|
-
const { mutate: mutate1 } = createMutation(['mutation1'], async () => {
|
|
169
|
-
await sleep(150);
|
|
170
|
-
return 'data';
|
|
171
|
-
}, { context });
|
|
172
|
-
const { mutate: mutate2 } = createMutation(['mutation2'], async () => {
|
|
173
|
-
await sleep(50);
|
|
180
|
+
it('should use provided custom queryClient', async () => {
|
|
181
|
+
const queryClient = createQueryClient();
|
|
182
|
+
function Page() {
|
|
183
|
+
const isMutating = useIsMutating(() => ({ queryClient }));
|
|
184
|
+
const { mutate } = createMutation(() => ({
|
|
185
|
+
mutationKey: ['mutation1'],
|
|
186
|
+
mutationFn: async () => {
|
|
187
|
+
await sleep(10);
|
|
174
188
|
return 'data';
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
</QueryClientProvider>));
|
|
187
|
-
await waitFor(() => expect(isMutatings).toEqual([0, 1, 2, 1, 0]));
|
|
188
|
-
});
|
|
189
|
-
it('should throw if the context is not passed to useIsMutating', async () => {
|
|
190
|
-
const context = createContext(undefined);
|
|
191
|
-
const isMutatings = [];
|
|
192
|
-
const queryClient = new QueryClient();
|
|
193
|
-
function IsMutating() {
|
|
194
|
-
const isMutating = useIsMutating(undefined);
|
|
195
|
-
isMutatings.push(isMutating());
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
function Page() {
|
|
199
|
-
const { mutate } = createMutation(['mutation'], async () => 'data', {
|
|
200
|
-
useErrorBoundary: true,
|
|
201
|
-
context,
|
|
202
|
-
});
|
|
203
|
-
createEffect(() => {
|
|
204
|
-
mutate();
|
|
205
|
-
});
|
|
206
|
-
return <IsMutating />;
|
|
207
|
-
}
|
|
208
|
-
render(() => (<QueryClientProvider client={queryClient} context={context}>
|
|
209
|
-
<ErrorBoundary fallback={() => <div>error boundary</div>}>
|
|
210
|
-
<Page />
|
|
211
|
-
</ErrorBoundary>
|
|
212
|
-
</QueryClientProvider>));
|
|
213
|
-
await waitFor(() => screen.getByText('error boundary'));
|
|
214
|
-
});
|
|
189
|
+
},
|
|
190
|
+
}), () => queryClient);
|
|
191
|
+
createEffect(() => {
|
|
192
|
+
mutate();
|
|
193
|
+
});
|
|
194
|
+
return (<div>
|
|
195
|
+
<div>mutating: {isMutating}</div>
|
|
196
|
+
</div>);
|
|
197
|
+
}
|
|
198
|
+
render(() => <Page></Page>);
|
|
199
|
+
await waitFor(() => screen.findByText('mutating: 1'));
|
|
215
200
|
});
|
|
216
201
|
});
|
|
@@ -2,8 +2,8 @@ import { QueryClient } from '@tanstack/query-core';
|
|
|
2
2
|
import { createEffect, createSignal, onCleanup, Show } from 'solid-js';
|
|
3
3
|
let queryKeyCount = 0;
|
|
4
4
|
export function queryKey() {
|
|
5
|
-
|
|
6
|
-
return
|
|
5
|
+
queryKeyCount++;
|
|
6
|
+
return [`query_${queryKeyCount}`];
|
|
7
7
|
}
|
|
8
8
|
export const Blink = (props) => {
|
|
9
9
|
const [shouldShow, setShouldShow] = createSignal(true);
|
|
@@ -17,8 +17,7 @@ export const Blink = (props) => {
|
|
|
17
17
|
</Show>);
|
|
18
18
|
};
|
|
19
19
|
export function createQueryClient(config) {
|
|
20
|
-
|
|
21
|
-
return new QueryClient({ logger: mockLogger, ...config });
|
|
20
|
+
return new QueryClient(config);
|
|
22
21
|
}
|
|
23
22
|
export function mockVisibilityState(value) {
|
|
24
23
|
return jest.spyOn(document, 'visibilityState', 'get').mockReturnValue(value);
|
|
@@ -26,11 +25,6 @@ export function mockVisibilityState(value) {
|
|
|
26
25
|
export function mockNavigatorOnLine(value) {
|
|
27
26
|
return jest.spyOn(navigator, 'onLine', 'get').mockReturnValue(value);
|
|
28
27
|
}
|
|
29
|
-
export const mockLogger = {
|
|
30
|
-
log: jest.fn(),
|
|
31
|
-
warn: jest.fn(),
|
|
32
|
-
error: jest.fn(),
|
|
33
|
-
};
|
|
34
28
|
export function sleep(timeout) {
|
|
35
29
|
return new Promise((resolve, _reject) => {
|
|
36
30
|
setTimeout(resolve, timeout);
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { hydrate } from '@tanstack/query-core';
|
|
2
|
+
import { notifyManager } from '@tanstack/query-core';
|
|
3
|
+
import { isServer } from 'solid-js/web';
|
|
4
|
+
import { createComputed, createMemo, createResource, on, onCleanup, onMount, } from 'solid-js';
|
|
5
|
+
import { createStore, unwrap } from 'solid-js/store';
|
|
6
|
+
import { useQueryClient } from './QueryClientProvider';
|
|
7
|
+
import { shouldThrowError } from './utils';
|
|
8
|
+
// Base Query Function that is used to create the query.
|
|
9
|
+
export function createBaseQuery(options, Observer, queryClient) {
|
|
10
|
+
const client = createMemo(() => useQueryClient(queryClient?.()));
|
|
11
|
+
const defaultedOptions = client().defaultQueryOptions(options());
|
|
12
|
+
defaultedOptions._optimisticResults = 'optimistic';
|
|
13
|
+
if (isServer) {
|
|
14
|
+
defaultedOptions.retry = false;
|
|
15
|
+
defaultedOptions.throwErrors = true;
|
|
16
|
+
}
|
|
17
|
+
const observer = new Observer(client(), defaultedOptions);
|
|
18
|
+
const [state, setState] = createStore(observer.getOptimisticResult(defaultedOptions));
|
|
19
|
+
const createServerSubscriber = (resolve, reject) => {
|
|
20
|
+
return observer.subscribe((result) => {
|
|
21
|
+
notifyManager.batchCalls(() => {
|
|
22
|
+
const unwrappedResult = { ...unwrap(result) };
|
|
23
|
+
if (unwrappedResult.isError) {
|
|
24
|
+
if (process.env['NODE_ENV'] === 'development') {
|
|
25
|
+
console.error(unwrappedResult.error);
|
|
26
|
+
}
|
|
27
|
+
reject(unwrappedResult.error);
|
|
28
|
+
}
|
|
29
|
+
if (unwrappedResult.isSuccess) {
|
|
30
|
+
resolve(unwrappedResult);
|
|
31
|
+
}
|
|
32
|
+
})();
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
const createClientSubscriber = () => {
|
|
36
|
+
return observer.subscribe((result) => {
|
|
37
|
+
notifyManager.batchCalls(() => {
|
|
38
|
+
const unwrappedResult = { ...unwrap(result) };
|
|
39
|
+
// If the query has data we dont suspend but instead mutate the resource
|
|
40
|
+
// This could happen when placeholderData/initialData is defined
|
|
41
|
+
if (queryResource()?.data &&
|
|
42
|
+
unwrappedResult.data &&
|
|
43
|
+
!queryResource.loading) {
|
|
44
|
+
setState(unwrappedResult);
|
|
45
|
+
mutate(state);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
setState(unwrappedResult);
|
|
49
|
+
refetch();
|
|
50
|
+
}
|
|
51
|
+
})();
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Unsubscribe is set lazily, so that we can subscribe after hydration when needed.
|
|
56
|
+
*/
|
|
57
|
+
let unsubscribe = null;
|
|
58
|
+
const [queryResource, { refetch, mutate }] = createResource(() => {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
if (isServer) {
|
|
61
|
+
unsubscribe = createServerSubscriber(resolve, reject);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (!unsubscribe) {
|
|
65
|
+
unsubscribe = createClientSubscriber();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!state.isLoading) {
|
|
69
|
+
resolve(state);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}, {
|
|
73
|
+
initialValue: state,
|
|
74
|
+
// If initialData is provided, we resolve the resource immediately
|
|
75
|
+
ssrLoadFrom: options().initialData ? 'initial' : 'server',
|
|
76
|
+
get deferStream() {
|
|
77
|
+
return options().deferStream;
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* If this resource was populated on the server (either sync render, or streamed in over time), onHydrated
|
|
81
|
+
* will be called. This is the point at which we can hydrate the query cache state, and setup the query subscriber.
|
|
82
|
+
*
|
|
83
|
+
* Leveraging onHydrated allows us to plug into the async and streaming support that solidjs resources already support.
|
|
84
|
+
*
|
|
85
|
+
* Note that this is only invoked on the client, for queries that were originally run on the server.
|
|
86
|
+
*/
|
|
87
|
+
onHydrated(_k, info) {
|
|
88
|
+
if (info.value) {
|
|
89
|
+
hydrate(client(), {
|
|
90
|
+
queries: [
|
|
91
|
+
{
|
|
92
|
+
queryKey: defaultedOptions.queryKey,
|
|
93
|
+
queryHash: defaultedOptions.queryHash,
|
|
94
|
+
state: info.value,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (!unsubscribe) {
|
|
100
|
+
/**
|
|
101
|
+
* Do not refetch query on mount if query was fetched on server,
|
|
102
|
+
* even if `staleTime` is not set.
|
|
103
|
+
*/
|
|
104
|
+
const newOptions = { ...defaultedOptions };
|
|
105
|
+
if (defaultedOptions.staleTime || !defaultedOptions.initialData) {
|
|
106
|
+
newOptions.refetchOnMount = false;
|
|
107
|
+
}
|
|
108
|
+
// Setting the options as an immutable object to prevent
|
|
109
|
+
// wonky behavior with observer subscriptions
|
|
110
|
+
observer.setOptions(newOptions);
|
|
111
|
+
setState(observer.getOptimisticResult(newOptions));
|
|
112
|
+
unsubscribe = createClientSubscriber();
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
onCleanup(() => {
|
|
117
|
+
if (unsubscribe) {
|
|
118
|
+
unsubscribe();
|
|
119
|
+
unsubscribe = null;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
onMount(() => {
|
|
123
|
+
observer.setOptions(defaultedOptions, { listeners: false });
|
|
124
|
+
});
|
|
125
|
+
createComputed(() => {
|
|
126
|
+
observer.setOptions(client().defaultQueryOptions(options()));
|
|
127
|
+
});
|
|
128
|
+
createComputed(on(() => state.status, () => {
|
|
129
|
+
if (state.isError &&
|
|
130
|
+
!state.isFetching &&
|
|
131
|
+
shouldThrowError(observer.options.throwErrors, [
|
|
132
|
+
state.error,
|
|
133
|
+
observer.getCurrentQuery(),
|
|
134
|
+
])) {
|
|
135
|
+
throw state.error;
|
|
136
|
+
}
|
|
137
|
+
}));
|
|
138
|
+
const handler = {
|
|
139
|
+
get(target, prop) {
|
|
140
|
+
if (prop === 'data') {
|
|
141
|
+
return queryResource()?.data;
|
|
142
|
+
}
|
|
143
|
+
return Reflect.get(target, prop);
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
return new Proxy(state, handler);
|
|
147
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { InfiniteQueryObserver } from '@tanstack/query-core';
|
|
2
|
+
import { createBaseQuery } from './createBaseQuery';
|
|
3
|
+
import { createMemo } from 'solid-js';
|
|
4
|
+
export function createInfiniteQuery(options, queryClient) {
|
|
5
|
+
return createBaseQuery(createMemo(() => options()),
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
7
|
+
InfiniteQueryObserver, queryClient);
|
|
8
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MutationObserver } from '@tanstack/query-core';
|
|
2
2
|
import { useQueryClient } from './QueryClientProvider';
|
|
3
3
|
import { createComputed, onCleanup, on } from 'solid-js';
|
|
4
4
|
import { createStore } from 'solid-js/store';
|
|
5
5
|
import { shouldThrowError } from './utils';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const observer = new MutationObserver(
|
|
6
|
+
// HOOK
|
|
7
|
+
export function createMutation(options, queryClient) {
|
|
8
|
+
const client = useQueryClient(queryClient?.());
|
|
9
|
+
const observer = new MutationObserver(client, options());
|
|
10
10
|
const mutate = (variables, mutateOptions) => {
|
|
11
11
|
observer.mutate(variables, mutateOptions).catch(noop);
|
|
12
12
|
};
|
|
@@ -16,13 +16,11 @@ export function createMutation(arg1, arg2, arg3) {
|
|
|
16
16
|
mutateAsync: observer.getCurrentResult().mutate,
|
|
17
17
|
});
|
|
18
18
|
createComputed(() => {
|
|
19
|
-
|
|
20
|
-
setOptions(newParsedOptions);
|
|
21
|
-
observer.setOptions(newParsedOptions);
|
|
19
|
+
observer.setOptions(options());
|
|
22
20
|
});
|
|
23
21
|
createComputed(on(() => state.status, () => {
|
|
24
22
|
if (state.isError &&
|
|
25
|
-
shouldThrowError(observer.options.
|
|
23
|
+
shouldThrowError(observer.options.throwErrors, [state.error])) {
|
|
26
24
|
throw state.error;
|
|
27
25
|
}
|
|
28
26
|
}));
|