@tanstack/solid-query 5.0.0-beta.9 → 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/dev.cjs +176 -80
- package/build/dev.js +178 -82
- package/build/index.cjs +176 -80
- package/build/index.d.cts +9 -5
- package/build/index.d.ts +9 -5
- package/build/index.js +178 -82
- package/package.json +7 -3
- package/src/QueryClientProvider.tsx +14 -7
- package/src/__tests__/createInfiniteQuery.test.tsx +59 -52
- package/src/__tests__/createMutation.test.tsx +22 -4
- package/src/__tests__/createQueries.test.tsx +83 -87
- package/src/__tests__/createQuery.test.tsx +115 -201
- package/src/__tests__/suspense.test.tsx +35 -5
- package/src/__tests__/transition.test.tsx +1 -2
- package/src/__tests__/useIsFetching.test.tsx +2 -2
- package/src/__tests__/useIsMutating.test.tsx +3 -3
- package/src/__tests__/utils.tsx +1 -8
- package/src/createBaseQuery.ts +95 -61
- package/src/createMutation.ts +3 -3
- package/src/createQueries.ts +156 -52
- package/src/index.ts +1 -0
- package/src/isRestoring.ts +6 -0
- package/src/utils.ts +1 -1
package/build/dev.cjs
CHANGED
|
@@ -21,17 +21,17 @@ exports.useQueryClient = (queryClient) => {
|
|
|
21
21
|
if (!client) {
|
|
22
22
|
throw new Error("No QueryClient set, use QueryClientProvider to set one");
|
|
23
23
|
}
|
|
24
|
-
return client;
|
|
24
|
+
return client();
|
|
25
25
|
};
|
|
26
26
|
exports.QueryClientProvider = (props) => {
|
|
27
|
-
solidJs.
|
|
27
|
+
solidJs.createRenderEffect((unmount) => {
|
|
28
|
+
unmount?.();
|
|
28
29
|
props.client.mount();
|
|
30
|
+
return props.client.unmount.bind(props.client);
|
|
29
31
|
});
|
|
30
32
|
solidJs.onCleanup(() => props.client.unmount());
|
|
31
33
|
return web.createComponent(exports.QueryClientContext.Provider, {
|
|
32
|
-
|
|
33
|
-
return props.client;
|
|
34
|
-
},
|
|
34
|
+
value: () => props.client,
|
|
35
35
|
get children() {
|
|
36
36
|
return props.children;
|
|
37
37
|
}
|
|
@@ -45,6 +45,9 @@ function shouldThrowError(throwError, params) {
|
|
|
45
45
|
}
|
|
46
46
|
return !!throwError;
|
|
47
47
|
}
|
|
48
|
+
var IsRestoringContext = solidJs.createContext(() => false);
|
|
49
|
+
exports.useIsRestoring = () => solidJs.useContext(IsRestoringContext);
|
|
50
|
+
exports.IsRestoringProvider = IsRestoringContext.Provider;
|
|
48
51
|
|
|
49
52
|
// src/createBaseQuery.ts
|
|
50
53
|
function reconcileFn(store$1, result, reconcileOption) {
|
|
@@ -78,21 +81,31 @@ var hydrateableObserverResult = (query, result) => {
|
|
|
78
81
|
};
|
|
79
82
|
function createBaseQuery(options, Observer, queryClient) {
|
|
80
83
|
const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
|
|
81
|
-
const
|
|
82
|
-
defaultedOptions
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
const isRestoring = exports.useIsRestoring();
|
|
85
|
+
const defaultedOptions = solidJs.createMemo(
|
|
86
|
+
() => solidJs.mergeProps(client().defaultQueryOptions(options()), {
|
|
87
|
+
get _optimisticResults() {
|
|
88
|
+
return isRestoring() ? "isRestoring" : "optimistic";
|
|
89
|
+
},
|
|
90
|
+
structuralSharing: false,
|
|
91
|
+
...web.isServer && { retry: false, throwOnError: true }
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
const [observer, setObserver] = solidJs.createSignal(
|
|
95
|
+
new Observer(client(), solidJs.untrack(defaultedOptions))
|
|
96
|
+
);
|
|
97
|
+
solidJs.createComputed(
|
|
98
|
+
solidJs.on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
|
|
99
|
+
defer: true
|
|
100
|
+
})
|
|
101
|
+
);
|
|
89
102
|
const [state, setState] = store.createStore(
|
|
90
|
-
observer.getOptimisticResult(defaultedOptions)
|
|
103
|
+
observer().getOptimisticResult(defaultedOptions())
|
|
91
104
|
);
|
|
92
105
|
const createServerSubscriber = (resolve, reject) => {
|
|
93
|
-
return observer.subscribe((result) => {
|
|
106
|
+
return observer().subscribe((result) => {
|
|
94
107
|
queryCore.notifyManager.batchCalls(() => {
|
|
95
|
-
const query = observer.getCurrentQuery();
|
|
108
|
+
const query = observer().getCurrentQuery();
|
|
96
109
|
const unwrappedResult = hydrateableObserverResult(query, result);
|
|
97
110
|
if (unwrappedResult.isError) {
|
|
98
111
|
reject(unwrappedResult.error);
|
|
@@ -103,44 +116,36 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
103
116
|
});
|
|
104
117
|
};
|
|
105
118
|
const createClientSubscriber = () => {
|
|
106
|
-
|
|
119
|
+
const obs = observer();
|
|
120
|
+
return obs.subscribe((result) => {
|
|
107
121
|
queryCore.notifyManager.batchCalls(() => {
|
|
108
|
-
const reconcileOptions =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
const reconcileOptions = obs.options.reconcile;
|
|
123
|
+
setState((store) => {
|
|
124
|
+
return reconcileFn(
|
|
125
|
+
store,
|
|
126
|
+
result,
|
|
127
|
+
reconcileOptions === void 0 ? "id" : reconcileOptions
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
if (queryResource()?.data && result.data && !queryResource.loading && isRestoring())
|
|
117
131
|
mutate(state);
|
|
118
|
-
|
|
119
|
-
setState((store) => {
|
|
120
|
-
return reconcileFn(
|
|
121
|
-
store,
|
|
122
|
-
result,
|
|
123
|
-
reconcileOptions === void 0 ? "id" : reconcileOptions
|
|
124
|
-
);
|
|
125
|
-
});
|
|
132
|
+
else
|
|
126
133
|
refetch();
|
|
127
|
-
}
|
|
128
134
|
})();
|
|
129
135
|
});
|
|
130
136
|
};
|
|
131
137
|
let unsubscribe = null;
|
|
132
138
|
const [queryResource, { refetch, mutate }] = solidJs.createResource(
|
|
133
139
|
() => {
|
|
140
|
+
const obs = observer();
|
|
134
141
|
return new Promise((resolve, reject) => {
|
|
135
|
-
if (web.isServer)
|
|
142
|
+
if (web.isServer)
|
|
136
143
|
unsubscribe = createServerSubscriber(resolve, reject);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (!state.isLoading) {
|
|
143
|
-
const query = observer.getCurrentQuery();
|
|
144
|
+
else if (!unsubscribe && !isRestoring())
|
|
145
|
+
unsubscribe = createClientSubscriber();
|
|
146
|
+
obs.updateResult();
|
|
147
|
+
if (!state.isLoading && !isRestoring()) {
|
|
148
|
+
const query = obs.getCurrentQuery();
|
|
144
149
|
resolve(hydrateableObserverResult(query, state));
|
|
145
150
|
}
|
|
146
151
|
});
|
|
@@ -148,7 +153,9 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
148
153
|
{
|
|
149
154
|
initialValue: state,
|
|
150
155
|
// If initialData is provided, we resolve the resource immediately
|
|
151
|
-
ssrLoadFrom
|
|
156
|
+
get ssrLoadFrom() {
|
|
157
|
+
return options().initialData ? "initial" : "server";
|
|
158
|
+
},
|
|
152
159
|
get deferStream() {
|
|
153
160
|
return options().deferStream;
|
|
154
161
|
},
|
|
@@ -161,29 +168,43 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
161
168
|
* Note that this is only invoked on the client, for queries that were originally run on the server.
|
|
162
169
|
*/
|
|
163
170
|
onHydrated(_k, info) {
|
|
171
|
+
const defaultOptions = defaultedOptions();
|
|
164
172
|
if (info.value) {
|
|
165
173
|
queryCore.hydrate(client(), {
|
|
166
174
|
queries: [
|
|
167
175
|
{
|
|
168
|
-
queryKey:
|
|
169
|
-
queryHash:
|
|
176
|
+
queryKey: defaultOptions.queryKey,
|
|
177
|
+
queryHash: defaultOptions.queryHash,
|
|
170
178
|
state: info.value
|
|
171
179
|
}
|
|
172
180
|
]
|
|
173
181
|
});
|
|
174
182
|
}
|
|
175
|
-
if (
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
observer.setOptions(newOptions);
|
|
181
|
-
setState(observer.getOptimisticResult(newOptions));
|
|
182
|
-
unsubscribe = createClientSubscriber();
|
|
183
|
+
if (unsubscribe)
|
|
184
|
+
return;
|
|
185
|
+
const newOptions = { ...defaultOptions };
|
|
186
|
+
if (defaultOptions.staleTime || !defaultOptions.initialData) {
|
|
187
|
+
newOptions.refetchOnMount = false;
|
|
183
188
|
}
|
|
189
|
+
observer().setOptions(newOptions);
|
|
190
|
+
setState(observer().getOptimisticResult(newOptions));
|
|
191
|
+
unsubscribe = createClientSubscriber();
|
|
184
192
|
}
|
|
185
193
|
}
|
|
186
194
|
);
|
|
195
|
+
solidJs.createComputed(
|
|
196
|
+
solidJs.on(
|
|
197
|
+
[isRestoring, observer],
|
|
198
|
+
([restoring]) => {
|
|
199
|
+
const unsub = unsubscribe;
|
|
200
|
+
queueMicrotask(() => unsub?.());
|
|
201
|
+
unsubscribe = null;
|
|
202
|
+
if (!restoring)
|
|
203
|
+
refetch();
|
|
204
|
+
},
|
|
205
|
+
{ defer: true }
|
|
206
|
+
)
|
|
207
|
+
);
|
|
187
208
|
solidJs.onCleanup(() => {
|
|
188
209
|
if (unsubscribe) {
|
|
189
210
|
unsubscribe();
|
|
@@ -192,8 +213,11 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
192
213
|
});
|
|
193
214
|
solidJs.createComputed(
|
|
194
215
|
solidJs.on(
|
|
195
|
-
|
|
196
|
-
() =>
|
|
216
|
+
[observer, defaultedOptions],
|
|
217
|
+
([obs, opts]) => {
|
|
218
|
+
obs.setOptions(opts);
|
|
219
|
+
setState(obs.getOptimisticResult(opts));
|
|
220
|
+
},
|
|
197
221
|
{
|
|
198
222
|
// Defer because we don't need to trigger on first render
|
|
199
223
|
// This only cares about changes to options after the observer is created
|
|
@@ -205,9 +229,10 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
205
229
|
solidJs.on(
|
|
206
230
|
() => state.status,
|
|
207
231
|
() => {
|
|
208
|
-
|
|
232
|
+
const obs = observer();
|
|
233
|
+
if (state.isError && !state.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
209
234
|
state.error,
|
|
210
|
-
|
|
235
|
+
obs.getCurrentQuery()
|
|
211
236
|
])) {
|
|
212
237
|
throw state.error;
|
|
213
238
|
}
|
|
@@ -253,9 +278,9 @@ function createInfiniteQuery(options, queryClient) {
|
|
|
253
278
|
);
|
|
254
279
|
}
|
|
255
280
|
function createMutation(options, queryClient) {
|
|
256
|
-
const client = exports.useQueryClient(queryClient?.());
|
|
281
|
+
const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
|
|
257
282
|
const observer = new queryCore.MutationObserver(
|
|
258
|
-
client,
|
|
283
|
+
client(),
|
|
259
284
|
options()
|
|
260
285
|
);
|
|
261
286
|
const mutate = (variables, mutateOptions) => {
|
|
@@ -304,43 +329,114 @@ function useIsMutating(filters, queryClient) {
|
|
|
304
329
|
return mutations;
|
|
305
330
|
}
|
|
306
331
|
function createQueries(queriesOptions, queryClient) {
|
|
307
|
-
const client = exports.useQueryClient(queryClient?.());
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
332
|
+
const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
|
|
333
|
+
const isRestoring = exports.useIsRestoring();
|
|
334
|
+
const defaultedQueries = solidJs.createMemo(
|
|
335
|
+
() => queriesOptions().queries.map(
|
|
336
|
+
(options) => solidJs.mergeProps(client().defaultQueryOptions(options), {
|
|
337
|
+
get _optimisticResults() {
|
|
338
|
+
return isRestoring() ? "isRestoring" : "optimistic";
|
|
339
|
+
}
|
|
340
|
+
})
|
|
341
|
+
)
|
|
342
|
+
);
|
|
313
343
|
const observer = new queryCore.QueriesObserver(
|
|
314
|
-
client,
|
|
315
|
-
defaultedQueries,
|
|
344
|
+
client(),
|
|
345
|
+
defaultedQueries(),
|
|
316
346
|
queriesOptions().combine ? {
|
|
317
347
|
combine: queriesOptions().combine
|
|
318
348
|
} : void 0
|
|
319
349
|
);
|
|
320
350
|
const [state, setState] = store.createStore(
|
|
321
|
-
observer.getOptimisticResult(defaultedQueries)[1]()
|
|
351
|
+
observer.getOptimisticResult(defaultedQueries())[1]()
|
|
322
352
|
);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
353
|
+
solidJs.createRenderEffect(
|
|
354
|
+
solidJs.on(
|
|
355
|
+
() => queriesOptions().queries.length,
|
|
356
|
+
() => setState(observer.getOptimisticResult(defaultedQueries())[1]())
|
|
357
|
+
)
|
|
358
|
+
);
|
|
359
|
+
const dataResources = solidJs.createMemo(
|
|
360
|
+
solidJs.on(
|
|
361
|
+
() => state.length,
|
|
362
|
+
() => state.map((queryRes) => {
|
|
363
|
+
const dataPromise = () => new Promise((resolve) => {
|
|
364
|
+
if (queryRes.isFetching && queryRes.isLoading)
|
|
365
|
+
return;
|
|
366
|
+
resolve(store.unwrap(queryRes.data));
|
|
367
|
+
});
|
|
368
|
+
return solidJs.createResource(dataPromise);
|
|
369
|
+
})
|
|
370
|
+
)
|
|
371
|
+
);
|
|
372
|
+
solidJs.batch(() => {
|
|
373
|
+
const dataResources_ = dataResources();
|
|
374
|
+
for (let index = 0; index < dataResources_.length; index++) {
|
|
375
|
+
const dataResource = dataResources_[index];
|
|
376
|
+
dataResource[1].mutate(() => store.unwrap(state[index].data));
|
|
377
|
+
dataResource[1].refetch();
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
let taskQueue = [];
|
|
381
|
+
const subscribeToObserver = () => observer.subscribe((result) => {
|
|
382
|
+
taskQueue.push(() => {
|
|
383
|
+
solidJs.batch(() => {
|
|
384
|
+
const dataResources_ = dataResources();
|
|
385
|
+
for (let index = 0; index < dataResources_.length; index++) {
|
|
386
|
+
const dataResource = dataResources_[index];
|
|
387
|
+
const unwrappedResult = { ...store.unwrap(result[index]) };
|
|
388
|
+
setState(index, store.unwrap(unwrappedResult));
|
|
389
|
+
dataResource[1].mutate(() => store.unwrap(state[index].data));
|
|
390
|
+
dataResource[1].refetch();
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
queueMicrotask(() => {
|
|
395
|
+
const taskToRun = taskQueue.pop();
|
|
396
|
+
if (taskToRun)
|
|
397
|
+
taskToRun();
|
|
398
|
+
taskQueue = [];
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
let unsubscribe = () => void 0;
|
|
402
|
+
solidJs.createComputed((cleanup) => {
|
|
403
|
+
cleanup?.();
|
|
404
|
+
unsubscribe = isRestoring() ? () => void 0 : subscribeToObserver();
|
|
405
|
+
return () => queueMicrotask(unsubscribe);
|
|
327
406
|
});
|
|
328
407
|
solidJs.onCleanup(unsubscribe);
|
|
408
|
+
solidJs.onMount(() => {
|
|
409
|
+
observer.setQueries(
|
|
410
|
+
defaultedQueries(),
|
|
411
|
+
queriesOptions().combine ? {
|
|
412
|
+
combine: queriesOptions().combine
|
|
413
|
+
} : void 0,
|
|
414
|
+
{ listeners: false }
|
|
415
|
+
);
|
|
416
|
+
});
|
|
329
417
|
solidJs.createComputed(() => {
|
|
330
|
-
const updatedQueries = queriesOptions().queries.map((options) => {
|
|
331
|
-
const defaultedOptions = client.defaultQueryOptions(options);
|
|
332
|
-
defaultedOptions._optimisticResults = "optimistic";
|
|
333
|
-
return defaultedOptions;
|
|
334
|
-
});
|
|
335
418
|
observer.setQueries(
|
|
336
|
-
|
|
419
|
+
defaultedQueries(),
|
|
337
420
|
queriesOptions().combine ? {
|
|
338
421
|
combine: queriesOptions().combine
|
|
339
422
|
} : void 0,
|
|
340
423
|
{ listeners: false }
|
|
341
424
|
);
|
|
342
425
|
});
|
|
343
|
-
|
|
426
|
+
const handler = (index) => ({
|
|
427
|
+
get(target, prop) {
|
|
428
|
+
if (prop === "data") {
|
|
429
|
+
return dataResources()[index][0]();
|
|
430
|
+
}
|
|
431
|
+
return Reflect.get(target, prop);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
const getProxies = () => state.map((s, index) => {
|
|
435
|
+
return new Proxy(s, handler(index));
|
|
436
|
+
});
|
|
437
|
+
const [proxifiedState, setProxifiedState] = store.createStore(getProxies());
|
|
438
|
+
solidJs.createRenderEffect(() => setProxifiedState(getProxies()));
|
|
439
|
+
return proxifiedState;
|
|
344
440
|
}
|
|
345
441
|
|
|
346
442
|
exports.createInfiniteQuery = createInfiniteQuery;
|