@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/src/createQueries.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import { QueriesObserver
|
|
2
|
-
import { createComputed, onCleanup } from 'solid-js'
|
|
1
|
+
import { QueriesObserver } from '@tanstack/query-core'
|
|
3
2
|
import { createStore, unwrap } from 'solid-js/store'
|
|
3
|
+
import {
|
|
4
|
+
batch,
|
|
5
|
+
createComputed,
|
|
6
|
+
createMemo,
|
|
7
|
+
createRenderEffect,
|
|
8
|
+
createResource,
|
|
9
|
+
mergeProps,
|
|
10
|
+
on,
|
|
11
|
+
onCleanup,
|
|
12
|
+
onMount,
|
|
13
|
+
} from 'solid-js'
|
|
4
14
|
import { useQueryClient } from './QueryClientProvider'
|
|
15
|
+
import { useIsRestoring } from './isRestoring'
|
|
16
|
+
import type { CreateQueryResult, SolidQueryOptions } from './types'
|
|
5
17
|
import type { Accessor } from 'solid-js'
|
|
6
18
|
import type { QueryClient } from './QueryClient'
|
|
7
19
|
import type {
|
|
@@ -10,8 +22,8 @@ import type {
|
|
|
10
22
|
QueriesPlaceholderDataFunction,
|
|
11
23
|
QueryFunction,
|
|
12
24
|
QueryKey,
|
|
25
|
+
QueryObserverResult,
|
|
13
26
|
} from '@tanstack/query-core'
|
|
14
|
-
import type { CreateQueryResult, SolidQueryOptions } from './types'
|
|
15
27
|
|
|
16
28
|
// This defines the `UseQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.
|
|
17
29
|
// `placeholderData` function does not have a parameter
|
|
@@ -95,63 +107,71 @@ type GetResults<T> =
|
|
|
95
107
|
* QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
|
|
96
108
|
*/
|
|
97
109
|
export type QueriesOptions<
|
|
98
|
-
T extends any
|
|
99
|
-
Result extends any
|
|
110
|
+
T extends Array<any>,
|
|
111
|
+
Result extends Array<any> = [],
|
|
100
112
|
Depth extends ReadonlyArray<number> = [],
|
|
101
113
|
> = Depth['length'] extends MAXIMUM_DEPTH
|
|
102
|
-
? CreateQueryOptionsForCreateQueries
|
|
114
|
+
? Array<CreateQueryOptionsForCreateQueries>
|
|
103
115
|
: T extends []
|
|
104
116
|
? []
|
|
105
117
|
: T extends [infer Head]
|
|
106
118
|
? [...Result, GetOptions<Head>]
|
|
107
119
|
: T extends [infer Head, ...infer Tail]
|
|
108
120
|
? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>
|
|
109
|
-
: unknown
|
|
121
|
+
: Array<unknown> extends T
|
|
110
122
|
? T
|
|
111
123
|
: // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
|
|
112
124
|
// use this to infer the param types in the case of Array.map() argument
|
|
113
|
-
T extends
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
T extends Array<
|
|
126
|
+
CreateQueryOptionsForCreateQueries<
|
|
127
|
+
infer TQueryFnData,
|
|
128
|
+
infer TError,
|
|
129
|
+
infer TData,
|
|
130
|
+
infer TQueryKey
|
|
131
|
+
>
|
|
132
|
+
>
|
|
133
|
+
? Array<
|
|
134
|
+
CreateQueryOptionsForCreateQueries<TQueryFnData, TError, TData, TQueryKey>
|
|
135
|
+
>
|
|
120
136
|
: // Fallback
|
|
121
|
-
CreateQueryOptionsForCreateQueries
|
|
137
|
+
Array<CreateQueryOptionsForCreateQueries>
|
|
122
138
|
|
|
123
139
|
/**
|
|
124
140
|
* QueriesResults reducer recursively maps type param to results
|
|
125
141
|
*/
|
|
126
142
|
export type QueriesResults<
|
|
127
|
-
T extends any
|
|
128
|
-
Result extends any
|
|
143
|
+
T extends Array<any>,
|
|
144
|
+
Result extends Array<any> = [],
|
|
129
145
|
Depth extends ReadonlyArray<number> = [],
|
|
130
146
|
> = Depth['length'] extends MAXIMUM_DEPTH
|
|
131
|
-
? CreateQueryResult
|
|
147
|
+
? Array<CreateQueryResult>
|
|
132
148
|
: T extends []
|
|
133
149
|
? []
|
|
134
150
|
: T extends [infer Head]
|
|
135
151
|
? [...Result, GetResults<Head>]
|
|
136
152
|
: T extends [infer Head, ...infer Tail]
|
|
137
153
|
? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>
|
|
138
|
-
: T extends
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
: T extends Array<
|
|
155
|
+
CreateQueryOptionsForCreateQueries<
|
|
156
|
+
infer TQueryFnData,
|
|
157
|
+
infer TError,
|
|
158
|
+
infer TData,
|
|
159
|
+
any
|
|
160
|
+
>
|
|
161
|
+
>
|
|
144
162
|
? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
Array<
|
|
164
|
+
CreateQueryResult<
|
|
165
|
+
unknown extends TData ? TQueryFnData : TData,
|
|
166
|
+
unknown extends TError ? DefaultError : TError
|
|
167
|
+
>
|
|
168
|
+
>
|
|
149
169
|
: // Fallback
|
|
150
|
-
CreateQueryResult
|
|
170
|
+
Array<CreateQueryResult>
|
|
151
171
|
|
|
152
172
|
export function createQueries<
|
|
153
|
-
T extends any
|
|
154
|
-
TCombinedResult = QueriesResults<T>,
|
|
173
|
+
T extends Array<any>,
|
|
174
|
+
TCombinedResult extends QueriesResults<T> = QueriesResults<T>,
|
|
155
175
|
>(
|
|
156
176
|
queriesOptions: Accessor<{
|
|
157
177
|
queries: readonly [...QueriesOptions<T>]
|
|
@@ -159,17 +179,22 @@ export function createQueries<
|
|
|
159
179
|
}>,
|
|
160
180
|
queryClient?: Accessor<QueryClient>,
|
|
161
181
|
): TCombinedResult {
|
|
162
|
-
const client = useQueryClient(queryClient?.())
|
|
182
|
+
const client = createMemo(() => useQueryClient(queryClient?.()))
|
|
183
|
+
const isRestoring = useIsRestoring()
|
|
163
184
|
|
|
164
|
-
const defaultedQueries =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
185
|
+
const defaultedQueries = createMemo(() =>
|
|
186
|
+
queriesOptions().queries.map((options) =>
|
|
187
|
+
mergeProps(client().defaultQueryOptions(options), {
|
|
188
|
+
get _optimisticResults() {
|
|
189
|
+
return isRestoring() ? 'isRestoring' : 'optimistic'
|
|
190
|
+
},
|
|
191
|
+
}),
|
|
192
|
+
),
|
|
193
|
+
)
|
|
169
194
|
|
|
170
195
|
const observer = new QueriesObserver(
|
|
171
|
-
client,
|
|
172
|
-
defaultedQueries,
|
|
196
|
+
client(),
|
|
197
|
+
defaultedQueries(),
|
|
173
198
|
queriesOptions().combine
|
|
174
199
|
? ({
|
|
175
200
|
combine: queriesOptions().combine,
|
|
@@ -177,27 +202,89 @@ export function createQueries<
|
|
|
177
202
|
: undefined,
|
|
178
203
|
)
|
|
179
204
|
|
|
180
|
-
// @ts-expect-error - Types issue with solid-js createStore
|
|
181
205
|
const [state, setState] = createStore<TCombinedResult>(
|
|
182
|
-
observer.getOptimisticResult(defaultedQueries)[1](),
|
|
206
|
+
observer.getOptimisticResult(defaultedQueries())[1](),
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
createRenderEffect(
|
|
210
|
+
on(
|
|
211
|
+
() => queriesOptions().queries.length,
|
|
212
|
+
() => setState(observer.getOptimisticResult(defaultedQueries())[1]()),
|
|
213
|
+
),
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
const dataResources = createMemo(
|
|
217
|
+
on(
|
|
218
|
+
() => state.length,
|
|
219
|
+
() =>
|
|
220
|
+
state.map((queryRes) => {
|
|
221
|
+
const dataPromise = () =>
|
|
222
|
+
new Promise((resolve) => {
|
|
223
|
+
if (queryRes.isFetching && queryRes.isLoading) return
|
|
224
|
+
resolve(unwrap(queryRes.data))
|
|
225
|
+
})
|
|
226
|
+
return createResource(dataPromise)
|
|
227
|
+
}),
|
|
228
|
+
),
|
|
183
229
|
)
|
|
184
230
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
231
|
+
batch(() => {
|
|
232
|
+
const dataResources_ = dataResources()
|
|
233
|
+
for (let index = 0; index < dataResources_.length; index++) {
|
|
234
|
+
const dataResource = dataResources_[index]!
|
|
235
|
+
dataResource[1].mutate(() => unwrap(state[index]!.data))
|
|
236
|
+
dataResource[1].refetch()
|
|
237
|
+
}
|
|
189
238
|
})
|
|
190
239
|
|
|
240
|
+
let taskQueue: Array<() => void> = []
|
|
241
|
+
const subscribeToObserver = () =>
|
|
242
|
+
observer.subscribe((result) => {
|
|
243
|
+
taskQueue.push(() => {
|
|
244
|
+
batch(() => {
|
|
245
|
+
const dataResources_ = dataResources()
|
|
246
|
+
for (let index = 0; index < dataResources_.length; index++) {
|
|
247
|
+
const dataResource = dataResources_[index]!
|
|
248
|
+
const unwrappedResult = { ...unwrap(result[index]!) }
|
|
249
|
+
// @ts-expect-error typescript pedantry regarding the possible range of index
|
|
250
|
+
setState(index, unwrap(unwrappedResult))
|
|
251
|
+
dataResource[1].mutate(() => unwrap(state[index]!.data))
|
|
252
|
+
dataResource[1].refetch()
|
|
253
|
+
}
|
|
254
|
+
})
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
queueMicrotask(() => {
|
|
258
|
+
const taskToRun = taskQueue.pop()
|
|
259
|
+
if (taskToRun) taskToRun()
|
|
260
|
+
taskQueue = []
|
|
261
|
+
})
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
let unsubscribe: () => void = () => undefined
|
|
265
|
+
createComputed<() => void>((cleanup) => {
|
|
266
|
+
cleanup?.()
|
|
267
|
+
unsubscribe = isRestoring() ? () => undefined : subscribeToObserver()
|
|
268
|
+
// cleanup needs to be scheduled after synchronous effects take place
|
|
269
|
+
return () => queueMicrotask(unsubscribe)
|
|
270
|
+
})
|
|
191
271
|
onCleanup(unsubscribe)
|
|
192
272
|
|
|
273
|
+
onMount(() => {
|
|
274
|
+
observer.setQueries(
|
|
275
|
+
defaultedQueries(),
|
|
276
|
+
queriesOptions().combine
|
|
277
|
+
? ({
|
|
278
|
+
combine: queriesOptions().combine,
|
|
279
|
+
} as QueriesObserverOptions<TCombinedResult>)
|
|
280
|
+
: undefined,
|
|
281
|
+
{ listeners: false },
|
|
282
|
+
)
|
|
283
|
+
})
|
|
284
|
+
|
|
193
285
|
createComputed(() => {
|
|
194
|
-
const updatedQueries = queriesOptions().queries.map((options) => {
|
|
195
|
-
const defaultedOptions = client.defaultQueryOptions(options)
|
|
196
|
-
defaultedOptions._optimisticResults = 'optimistic'
|
|
197
|
-
return defaultedOptions
|
|
198
|
-
})
|
|
199
286
|
observer.setQueries(
|
|
200
|
-
|
|
287
|
+
defaultedQueries(),
|
|
201
288
|
queriesOptions().combine
|
|
202
289
|
? ({
|
|
203
290
|
combine: queriesOptions().combine,
|
|
@@ -207,5 +294,22 @@ export function createQueries<
|
|
|
207
294
|
)
|
|
208
295
|
})
|
|
209
296
|
|
|
210
|
-
|
|
297
|
+
const handler = (index: number) => ({
|
|
298
|
+
get(target: QueryObserverResult, prop: keyof QueryObserverResult): any {
|
|
299
|
+
if (prop === 'data') {
|
|
300
|
+
return dataResources()[index]![0]()
|
|
301
|
+
}
|
|
302
|
+
return Reflect.get(target, prop)
|
|
303
|
+
},
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
const getProxies = () =>
|
|
307
|
+
state.map((s, index) => {
|
|
308
|
+
return new Proxy(s, handler(index))
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
const [proxifiedState, setProxifiedState] = createStore(getProxies())
|
|
312
|
+
createRenderEffect(() => setProxifiedState(getProxies()))
|
|
313
|
+
|
|
314
|
+
return proxifiedState as TCombinedResult
|
|
211
315
|
}
|
package/src/index.ts
CHANGED
|
@@ -27,3 +27,4 @@ export { createInfiniteQuery } from './createInfiniteQuery'
|
|
|
27
27
|
export { createMutation } from './createMutation'
|
|
28
28
|
export { useIsMutating } from './useIsMutating'
|
|
29
29
|
export { createQueries } from './createQueries'
|
|
30
|
+
export { useIsRestoring, IsRestoringProvider } from './isRestoring'
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Accessor, createContext, useContext } from 'solid-js'
|
|
2
|
+
|
|
3
|
+
const IsRestoringContext = createContext<Accessor<boolean>>(() => false)
|
|
4
|
+
|
|
5
|
+
export const useIsRestoring = () => useContext(IsRestoringContext)
|
|
6
|
+
export const IsRestoringProvider = IsRestoringContext.Provider
|
package/src/utils.ts
CHANGED