@tanstack/solid-query 5.0.0-beta.20 → 5.0.0-beta.21
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 +7 -3
- package/build/index.d.ts +7 -3
- package/build/index.js +178 -82
- package/package.json +1 -1
- package/src/QueryClientProvider.tsx +14 -7
- package/src/__tests__/createQueries.test.tsx +1 -1
- package/src/__tests__/createQuery.test.tsx +8 -15
- package/src/__tests__/transition.test.tsx +1 -2
- package/src/__tests__/utils.tsx +1 -1
- package/src/createBaseQuery.ts +95 -61
- package/src/createMutation.ts +3 -3
- package/src/createQueries.ts +121 -25
- package/src/index.ts +1 -0
- package/src/isRestoring.ts +6 -0
package/src/createBaseQuery.ts
CHANGED
|
@@ -8,12 +8,16 @@ import {
|
|
|
8
8
|
createComputed,
|
|
9
9
|
createMemo,
|
|
10
10
|
createResource,
|
|
11
|
+
createSignal,
|
|
12
|
+
mergeProps,
|
|
11
13
|
on,
|
|
12
14
|
onCleanup,
|
|
15
|
+
untrack,
|
|
13
16
|
} from 'solid-js'
|
|
14
17
|
import { createStore, reconcile, unwrap } from 'solid-js/store'
|
|
15
18
|
import { useQueryClient } from './QueryClientProvider'
|
|
16
19
|
import { shouldThrowError } from './utils'
|
|
20
|
+
import { useIsRestoring } from './isRestoring'
|
|
17
21
|
import type { CreateBaseQueryOptions } from './types'
|
|
18
22
|
import type { Accessor } from 'solid-js'
|
|
19
23
|
import type { QueryClient } from './QueryClient'
|
|
@@ -104,18 +108,31 @@ export function createBaseQuery<
|
|
|
104
108
|
| QueryObserverResult<TData, TError>
|
|
105
109
|
|
|
106
110
|
const client = createMemo(() => useQueryClient(queryClient?.()))
|
|
111
|
+
const isRestoring = useIsRestoring()
|
|
107
112
|
|
|
108
|
-
const defaultedOptions =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
const defaultedOptions = createMemo(() =>
|
|
114
|
+
mergeProps(client().defaultQueryOptions(options()), {
|
|
115
|
+
get _optimisticResults() {
|
|
116
|
+
return isRestoring() ? 'isRestoring' : 'optimistic'
|
|
117
|
+
},
|
|
118
|
+
structuralSharing: false,
|
|
119
|
+
...(isServer && { retry: false, throwOnError: true }),
|
|
120
|
+
}),
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
const [observer, setObserver] = createSignal(
|
|
124
|
+
new Observer(client(), untrack(defaultedOptions)),
|
|
125
|
+
)
|
|
126
|
+
// we set the value in a computed because `createMemo`
|
|
127
|
+
// returns undefined during transitions
|
|
128
|
+
createComputed(
|
|
129
|
+
on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
|
|
130
|
+
defer: true,
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
116
133
|
|
|
117
134
|
const [state, setState] = createStore<QueryObserverResult<TData, TError>>(
|
|
118
|
-
observer.getOptimisticResult(defaultedOptions),
|
|
135
|
+
observer().getOptimisticResult(defaultedOptions()),
|
|
119
136
|
)
|
|
120
137
|
|
|
121
138
|
const createServerSubscriber = (
|
|
@@ -124,9 +141,9 @@ export function createBaseQuery<
|
|
|
124
141
|
) => void,
|
|
125
142
|
reject: (reason?: any) => void,
|
|
126
143
|
) => {
|
|
127
|
-
return observer.subscribe((result) => {
|
|
144
|
+
return observer().subscribe((result) => {
|
|
128
145
|
notifyManager.batchCalls(() => {
|
|
129
|
-
const query = observer.getCurrentQuery()
|
|
146
|
+
const query = observer().getCurrentQuery()
|
|
130
147
|
const unwrappedResult = hydrateableObserverResult(query, result)
|
|
131
148
|
|
|
132
149
|
if (unwrappedResult.isError) {
|
|
@@ -139,32 +156,30 @@ export function createBaseQuery<
|
|
|
139
156
|
}
|
|
140
157
|
|
|
141
158
|
const createClientSubscriber = () => {
|
|
142
|
-
|
|
159
|
+
const obs = observer()
|
|
160
|
+
return obs.subscribe((result) => {
|
|
143
161
|
notifyManager.batchCalls(() => {
|
|
144
162
|
// @ts-expect-error - This will error because the reconcile option does not
|
|
145
163
|
// exist on the query-core QueryObserverResult type
|
|
146
|
-
const reconcileOptions =
|
|
164
|
+
const reconcileOptions = obs.options.reconcile
|
|
165
|
+
|
|
166
|
+
setState((store) => {
|
|
167
|
+
return reconcileFn(
|
|
168
|
+
store,
|
|
169
|
+
result,
|
|
170
|
+
reconcileOptions === undefined ? 'id' : reconcileOptions,
|
|
171
|
+
)
|
|
172
|
+
})
|
|
147
173
|
// If the query has data we dont suspend but instead mutate the resource
|
|
148
174
|
// This could happen when placeholderData/initialData is defined
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
)
|
|
156
|
-
})
|
|
175
|
+
if (
|
|
176
|
+
queryResource()?.data &&
|
|
177
|
+
result.data &&
|
|
178
|
+
!queryResource.loading &&
|
|
179
|
+
isRestoring()
|
|
180
|
+
)
|
|
157
181
|
mutate(state)
|
|
158
|
-
|
|
159
|
-
setState((store) => {
|
|
160
|
-
return reconcileFn(
|
|
161
|
-
store,
|
|
162
|
-
result,
|
|
163
|
-
reconcileOptions === undefined ? 'id' : reconcileOptions,
|
|
164
|
-
)
|
|
165
|
-
})
|
|
166
|
-
refetch()
|
|
167
|
-
}
|
|
182
|
+
else refetch()
|
|
168
183
|
})()
|
|
169
184
|
})
|
|
170
185
|
}
|
|
@@ -178,17 +193,16 @@ export function createBaseQuery<
|
|
|
178
193
|
ResourceData | undefined
|
|
179
194
|
>(
|
|
180
195
|
() => {
|
|
196
|
+
const obs = observer()
|
|
181
197
|
return new Promise((resolve, reject) => {
|
|
182
|
-
if (isServer)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
}
|
|
198
|
+
if (isServer) unsubscribe = createServerSubscriber(resolve, reject)
|
|
199
|
+
else if (!unsubscribe && !isRestoring())
|
|
200
|
+
unsubscribe = createClientSubscriber()
|
|
201
|
+
|
|
202
|
+
obs.updateResult()
|
|
189
203
|
|
|
190
|
-
if (!state.isLoading) {
|
|
191
|
-
const query =
|
|
204
|
+
if (!state.isLoading && !isRestoring()) {
|
|
205
|
+
const query = obs.getCurrentQuery()
|
|
192
206
|
resolve(hydrateableObserverResult(query, state))
|
|
193
207
|
}
|
|
194
208
|
})
|
|
@@ -197,7 +211,9 @@ export function createBaseQuery<
|
|
|
197
211
|
initialValue: state,
|
|
198
212
|
|
|
199
213
|
// If initialData is provided, we resolve the resource immediately
|
|
200
|
-
ssrLoadFrom
|
|
214
|
+
get ssrLoadFrom() {
|
|
215
|
+
return options().initialData ? 'initial' : 'server'
|
|
216
|
+
},
|
|
201
217
|
|
|
202
218
|
get deferStream() {
|
|
203
219
|
return options().deferStream
|
|
@@ -212,37 +228,50 @@ export function createBaseQuery<
|
|
|
212
228
|
* Note that this is only invoked on the client, for queries that were originally run on the server.
|
|
213
229
|
*/
|
|
214
230
|
onHydrated(_k, info) {
|
|
231
|
+
const defaultOptions = defaultedOptions()
|
|
215
232
|
if (info.value) {
|
|
216
233
|
hydrate(client(), {
|
|
217
234
|
queries: [
|
|
218
235
|
{
|
|
219
|
-
queryKey:
|
|
220
|
-
queryHash:
|
|
236
|
+
queryKey: defaultOptions.queryKey,
|
|
237
|
+
queryHash: defaultOptions.queryHash,
|
|
221
238
|
state: info.value,
|
|
222
239
|
},
|
|
223
240
|
],
|
|
224
241
|
})
|
|
225
242
|
}
|
|
226
243
|
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
// Setting the options as an immutable object to prevent
|
|
237
|
-
// wonky behavior with observer subscriptions
|
|
238
|
-
observer.setOptions(newOptions)
|
|
239
|
-
setState(observer.getOptimisticResult(newOptions))
|
|
240
|
-
unsubscribe = createClientSubscriber()
|
|
244
|
+
if (unsubscribe) return
|
|
245
|
+
/**
|
|
246
|
+
* Do not refetch query on mount if query was fetched on server,
|
|
247
|
+
* even if `staleTime` is not set.
|
|
248
|
+
*/
|
|
249
|
+
const newOptions = { ...defaultOptions }
|
|
250
|
+
if (defaultOptions.staleTime || !defaultOptions.initialData) {
|
|
251
|
+
newOptions.refetchOnMount = false
|
|
241
252
|
}
|
|
253
|
+
// Setting the options as an immutable object to prevent
|
|
254
|
+
// wonky behavior with observer subscriptions
|
|
255
|
+
observer().setOptions(newOptions)
|
|
256
|
+
setState(observer().getOptimisticResult(newOptions))
|
|
257
|
+
unsubscribe = createClientSubscriber()
|
|
242
258
|
},
|
|
243
259
|
},
|
|
244
260
|
)
|
|
245
261
|
|
|
262
|
+
createComputed(
|
|
263
|
+
on(
|
|
264
|
+
[isRestoring, observer],
|
|
265
|
+
([restoring]) => {
|
|
266
|
+
const unsub = unsubscribe
|
|
267
|
+
queueMicrotask(() => unsub?.())
|
|
268
|
+
unsubscribe = null
|
|
269
|
+
if (!restoring) refetch()
|
|
270
|
+
},
|
|
271
|
+
{ defer: true },
|
|
272
|
+
),
|
|
273
|
+
)
|
|
274
|
+
|
|
246
275
|
onCleanup(() => {
|
|
247
276
|
if (unsubscribe) {
|
|
248
277
|
unsubscribe()
|
|
@@ -252,8 +281,11 @@ export function createBaseQuery<
|
|
|
252
281
|
|
|
253
282
|
createComputed(
|
|
254
283
|
on(
|
|
255
|
-
|
|
256
|
-
() =>
|
|
284
|
+
[observer, defaultedOptions],
|
|
285
|
+
([obs, opts]) => {
|
|
286
|
+
obs.setOptions(opts)
|
|
287
|
+
setState(obs.getOptimisticResult(opts))
|
|
288
|
+
},
|
|
257
289
|
{
|
|
258
290
|
// Defer because we don't need to trigger on first render
|
|
259
291
|
// This only cares about changes to options after the observer is created
|
|
@@ -266,12 +298,14 @@ export function createBaseQuery<
|
|
|
266
298
|
on(
|
|
267
299
|
() => state.status,
|
|
268
300
|
() => {
|
|
301
|
+
const obs = observer()
|
|
269
302
|
if (
|
|
270
303
|
state.isError &&
|
|
271
304
|
!state.isFetching &&
|
|
272
|
-
|
|
305
|
+
!isRestoring() &&
|
|
306
|
+
shouldThrowError(obs.options.throwOnError, [
|
|
273
307
|
state.error,
|
|
274
|
-
|
|
308
|
+
obs.getCurrentQuery(),
|
|
275
309
|
])
|
|
276
310
|
) {
|
|
277
311
|
throw state.error
|
package/src/createMutation.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MutationObserver } from '@tanstack/query-core'
|
|
2
|
-
import { createComputed, on, onCleanup } from 'solid-js'
|
|
2
|
+
import { createComputed, createMemo, on, onCleanup } from 'solid-js'
|
|
3
3
|
import { createStore } from 'solid-js/store'
|
|
4
4
|
import { useQueryClient } from './QueryClientProvider'
|
|
5
5
|
import { shouldThrowError } from './utils'
|
|
@@ -22,10 +22,10 @@ export function createMutation<
|
|
|
22
22
|
options: CreateMutationOptions<TData, TError, TVariables, TContext>,
|
|
23
23
|
queryClient?: Accessor<QueryClient>,
|
|
24
24
|
): CreateMutationResult<TData, TError, TVariables, TContext> {
|
|
25
|
-
const client = useQueryClient(queryClient?.())
|
|
25
|
+
const client = createMemo(() => useQueryClient(queryClient?.()))
|
|
26
26
|
|
|
27
27
|
const observer = new MutationObserver<TData, TError, TVariables, TContext>(
|
|
28
|
-
client,
|
|
28
|
+
client(),
|
|
29
29
|
options(),
|
|
30
30
|
)
|
|
31
31
|
|
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
|
|
@@ -159,7 +171,7 @@ export type QueriesResults<
|
|
|
159
171
|
|
|
160
172
|
export function createQueries<
|
|
161
173
|
T extends Array<any>,
|
|
162
|
-
TCombinedResult = QueriesResults<T>,
|
|
174
|
+
TCombinedResult extends QueriesResults<T> = QueriesResults<T>,
|
|
163
175
|
>(
|
|
164
176
|
queriesOptions: Accessor<{
|
|
165
177
|
queries: readonly [...QueriesOptions<T>]
|
|
@@ -167,17 +179,22 @@ export function createQueries<
|
|
|
167
179
|
}>,
|
|
168
180
|
queryClient?: Accessor<QueryClient>,
|
|
169
181
|
): TCombinedResult {
|
|
170
|
-
const client = useQueryClient(queryClient?.())
|
|
182
|
+
const client = createMemo(() => useQueryClient(queryClient?.()))
|
|
183
|
+
const isRestoring = useIsRestoring()
|
|
171
184
|
|
|
172
|
-
const defaultedQueries =
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
+
)
|
|
177
194
|
|
|
178
195
|
const observer = new QueriesObserver(
|
|
179
|
-
client,
|
|
180
|
-
defaultedQueries,
|
|
196
|
+
client(),
|
|
197
|
+
defaultedQueries(),
|
|
181
198
|
queriesOptions().combine
|
|
182
199
|
? ({
|
|
183
200
|
combine: queriesOptions().combine,
|
|
@@ -185,27 +202,89 @@ export function createQueries<
|
|
|
185
202
|
: undefined,
|
|
186
203
|
)
|
|
187
204
|
|
|
188
|
-
// @ts-expect-error - Types issue with solid-js createStore
|
|
189
205
|
const [state, setState] = createStore<TCombinedResult>(
|
|
190
|
-
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
|
+
),
|
|
191
229
|
)
|
|
192
230
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
+
}
|
|
197
238
|
})
|
|
198
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
|
+
})
|
|
199
271
|
onCleanup(unsubscribe)
|
|
200
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
|
+
|
|
201
285
|
createComputed(() => {
|
|
202
|
-
const updatedQueries = queriesOptions().queries.map((options) => {
|
|
203
|
-
const defaultedOptions = client.defaultQueryOptions(options)
|
|
204
|
-
defaultedOptions._optimisticResults = 'optimistic'
|
|
205
|
-
return defaultedOptions
|
|
206
|
-
})
|
|
207
286
|
observer.setQueries(
|
|
208
|
-
|
|
287
|
+
defaultedQueries(),
|
|
209
288
|
queriesOptions().combine
|
|
210
289
|
? ({
|
|
211
290
|
combine: queriesOptions().combine,
|
|
@@ -215,5 +294,22 @@ export function createQueries<
|
|
|
215
294
|
)
|
|
216
295
|
})
|
|
217
296
|
|
|
218
|
-
|
|
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
|
|
219
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
|