@tanstack/query-core 5.0.0-alpha.1 → 5.0.0-alpha.3
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/lib/index.d.ts +1 -1
- package/build/lib/index.esm.js +1 -1
- package/build/lib/index.js +1 -0
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +1 -1
- package/build/lib/infiniteQueryObserver.d.ts +2 -2
- package/build/lib/infiniteQueryObserver.esm.js.map +1 -1
- package/build/lib/infiniteQueryObserver.js.map +1 -1
- package/build/lib/infiniteQueryObserver.mjs.map +1 -1
- package/build/lib/mutation.d.ts +5 -4
- package/build/lib/mutation.esm.js +16 -2
- package/build/lib/mutation.esm.js.map +1 -1
- package/build/lib/mutation.js +16 -2
- package/build/lib/mutation.js.map +1 -1
- package/build/lib/mutation.mjs +16 -2
- package/build/lib/mutation.mjs.map +1 -1
- package/build/lib/mutationCache.d.ts +5 -4
- package/build/lib/mutationCache.esm.js.map +1 -1
- package/build/lib/mutationCache.js.map +1 -1
- package/build/lib/mutationCache.mjs.map +1 -1
- package/build/lib/mutationObserver.d.ts +2 -2
- package/build/lib/mutationObserver.esm.js +1 -0
- package/build/lib/mutationObserver.esm.js.map +1 -1
- package/build/lib/mutationObserver.js +1 -0
- package/build/lib/mutationObserver.js.map +1 -1
- package/build/lib/mutationObserver.mjs +1 -0
- package/build/lib/mutationObserver.mjs.map +1 -1
- package/build/lib/queriesObserver.esm.js +1 -5
- package/build/lib/queriesObserver.esm.js.map +1 -1
- package/build/lib/queriesObserver.js +1 -5
- package/build/lib/queriesObserver.js.map +1 -1
- package/build/lib/queriesObserver.mjs +1 -5
- package/build/lib/queriesObserver.mjs.map +1 -1
- package/build/lib/query.d.ts +4 -4
- package/build/lib/query.esm.js +2 -0
- package/build/lib/query.esm.js.map +1 -1
- package/build/lib/query.js +2 -0
- package/build/lib/query.js.map +1 -1
- package/build/lib/query.mjs +2 -0
- package/build/lib/query.mjs.map +1 -1
- package/build/lib/queryCache.d.ts +5 -4
- package/build/lib/queryCache.esm.js.map +1 -1
- package/build/lib/queryCache.js.map +1 -1
- package/build/lib/queryCache.mjs.map +1 -1
- package/build/lib/queryClient.d.ts +7 -7
- package/build/lib/queryClient.esm.js.map +1 -1
- package/build/lib/queryClient.js.map +1 -1
- package/build/lib/queryClient.mjs.map +1 -1
- package/build/lib/queryObserver.d.ts +2 -2
- package/build/lib/queryObserver.esm.js.map +1 -1
- package/build/lib/queryObserver.js.map +1 -1
- package/build/lib/queryObserver.mjs.map +1 -1
- package/build/lib/retryer.d.ts +5 -5
- package/build/lib/retryer.esm.js.map +1 -1
- package/build/lib/retryer.js.map +1 -1
- package/build/lib/retryer.mjs.map +1 -1
- package/build/lib/types.d.ts +38 -38
- package/build/umd/index.development.js +21 -7
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +7 -1
- package/src/infiniteQueryObserver.ts +2 -2
- package/src/mutation.ts +34 -7
- package/src/mutationCache.ts +11 -4
- package/src/mutationObserver.ts +3 -2
- package/src/queriesObserver.ts +3 -7
- package/src/query.ts +18 -5
- package/src/queryCache.ts +12 -4
- package/src/queryClient.ts +7 -7
- package/src/queryObserver.ts +2 -2
- package/src/retryer.ts +5 -5
- package/src/tests/mutationCache.test.tsx +54 -10
- package/src/tests/mutations.test.tsx +31 -0
- package/src/tests/queryCache.test.tsx +18 -6
- package/src/types.ts +44 -36
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -11,7 +11,13 @@ export { MutationObserver } from './mutationObserver'
|
|
|
11
11
|
export { notifyManager } from './notifyManager'
|
|
12
12
|
export { focusManager } from './focusManager'
|
|
13
13
|
export { onlineManager } from './onlineManager'
|
|
14
|
-
export {
|
|
14
|
+
export {
|
|
15
|
+
hashKey,
|
|
16
|
+
replaceEqualDeep,
|
|
17
|
+
isServer,
|
|
18
|
+
matchQuery,
|
|
19
|
+
keepPreviousData,
|
|
20
|
+
} from './utils'
|
|
15
21
|
export type { MutationFilters, QueryFilters, Updater } from './utils'
|
|
16
22
|
export { isCancelledError } from './retryer'
|
|
17
23
|
export {
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
InfiniteQueryObserverOptions,
|
|
7
7
|
InfiniteQueryObserverResult,
|
|
8
8
|
QueryKey,
|
|
9
|
-
|
|
9
|
+
DefaultError,
|
|
10
10
|
} from './types'
|
|
11
11
|
import type { QueryClient } from './queryClient'
|
|
12
12
|
import type { NotifyOptions, ObserverFetchOptions } from './queryObserver'
|
|
@@ -24,7 +24,7 @@ type InfiniteQueryObserverListener<TData, TError> = (
|
|
|
24
24
|
|
|
25
25
|
export class InfiniteQueryObserver<
|
|
26
26
|
TQueryFnData = unknown,
|
|
27
|
-
TError =
|
|
27
|
+
TError = DefaultError,
|
|
28
28
|
TData = InfiniteData<TQueryFnData>,
|
|
29
29
|
TQueryData = TQueryFnData,
|
|
30
30
|
TQueryKey extends QueryKey = QueryKey,
|
package/src/mutation.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type {
|
|
|
2
2
|
MutationOptions,
|
|
3
3
|
MutationStatus,
|
|
4
4
|
MutationMeta,
|
|
5
|
-
|
|
5
|
+
DefaultError,
|
|
6
6
|
} from './types'
|
|
7
7
|
import type { MutationCache } from './mutationCache'
|
|
8
8
|
import type { MutationObserver } from './mutationObserver'
|
|
@@ -23,7 +23,7 @@ interface MutationConfig<TData, TError, TVariables, TContext> {
|
|
|
23
23
|
|
|
24
24
|
export interface MutationState<
|
|
25
25
|
TData = unknown,
|
|
26
|
-
TError =
|
|
26
|
+
TError = DefaultError,
|
|
27
27
|
TVariables = void,
|
|
28
28
|
TContext = unknown,
|
|
29
29
|
> {
|
|
@@ -80,31 +80,40 @@ export type Action<TData, TError, TVariables, TContext> =
|
|
|
80
80
|
|
|
81
81
|
export class Mutation<
|
|
82
82
|
TData = unknown,
|
|
83
|
-
TError =
|
|
83
|
+
TError = DefaultError,
|
|
84
84
|
TVariables = void,
|
|
85
85
|
TContext = unknown,
|
|
86
86
|
> extends Removable {
|
|
87
87
|
state: MutationState<TData, TError, TVariables, TContext>
|
|
88
|
-
|
|
88
|
+
options!: MutationOptions<TData, TError, TVariables, TContext>
|
|
89
89
|
readonly mutationId: number
|
|
90
90
|
|
|
91
91
|
#observers: MutationObserver<TData, TError, TVariables, TContext>[]
|
|
92
|
+
#defaultOptions?: MutationOptions<TData, TError, TVariables, TContext>
|
|
92
93
|
#mutationCache: MutationCache
|
|
93
94
|
#retryer?: Retryer<TData>
|
|
94
95
|
|
|
95
96
|
constructor(config: MutationConfig<TData, TError, TVariables, TContext>) {
|
|
96
97
|
super()
|
|
97
98
|
|
|
98
|
-
this.options = config.options
|
|
99
99
|
this.mutationId = config.mutationId
|
|
100
|
+
this.#defaultOptions = config.defaultOptions
|
|
100
101
|
this.#mutationCache = config.mutationCache
|
|
101
102
|
this.#observers = []
|
|
102
103
|
this.state = config.state || getDefaultState()
|
|
103
104
|
|
|
104
|
-
this.
|
|
105
|
+
this.setOptions(config.options)
|
|
105
106
|
this.scheduleGc()
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
setOptions(
|
|
110
|
+
options?: MutationOptions<TData, TError, TVariables, TContext>,
|
|
111
|
+
): void {
|
|
112
|
+
this.options = { ...this.#defaultOptions, ...options }
|
|
113
|
+
|
|
114
|
+
this.updateGcTime(this.options.gcTime)
|
|
115
|
+
}
|
|
116
|
+
|
|
108
117
|
get meta(): MutationMeta | undefined {
|
|
109
118
|
return this.options.meta
|
|
110
119
|
}
|
|
@@ -211,6 +220,15 @@ export class Mutation<
|
|
|
211
220
|
|
|
212
221
|
await this.options.onSuccess?.(data, variables, this.state.context)
|
|
213
222
|
|
|
223
|
+
// Notify cache callback
|
|
224
|
+
await this.#mutationCache.config.onSettled?.(
|
|
225
|
+
data,
|
|
226
|
+
null,
|
|
227
|
+
this.state.variables,
|
|
228
|
+
this.state.context,
|
|
229
|
+
this as Mutation<unknown, unknown, unknown, unknown>,
|
|
230
|
+
)
|
|
231
|
+
|
|
214
232
|
await this.options.onSettled?.(data, null, variables, this.state.context)
|
|
215
233
|
|
|
216
234
|
this.#dispatch({ type: 'success', data })
|
|
@@ -219,7 +237,7 @@ export class Mutation<
|
|
|
219
237
|
try {
|
|
220
238
|
// Notify cache callback
|
|
221
239
|
await this.#mutationCache.config.onError?.(
|
|
222
|
-
error,
|
|
240
|
+
error as any,
|
|
223
241
|
variables,
|
|
224
242
|
this.state.context,
|
|
225
243
|
this as Mutation<unknown, unknown, unknown, unknown>,
|
|
@@ -231,6 +249,15 @@ export class Mutation<
|
|
|
231
249
|
this.state.context,
|
|
232
250
|
)
|
|
233
251
|
|
|
252
|
+
// Notify cache callback
|
|
253
|
+
await this.#mutationCache.config.onSettled?.(
|
|
254
|
+
undefined,
|
|
255
|
+
error as any,
|
|
256
|
+
this.state.variables,
|
|
257
|
+
this.state.context,
|
|
258
|
+
this as Mutation<unknown, unknown, unknown, unknown>,
|
|
259
|
+
)
|
|
260
|
+
|
|
234
261
|
await this.options.onSettled?.(
|
|
235
262
|
undefined,
|
|
236
263
|
error as TError,
|
package/src/mutationCache.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MutationObserver } from './mutationObserver'
|
|
2
|
-
import type { NotifyEvent, MutationOptions,
|
|
2
|
+
import type { NotifyEvent, MutationOptions, DefaultError } from './types'
|
|
3
3
|
import type { QueryClient } from './queryClient'
|
|
4
4
|
import { notifyManager } from './notifyManager'
|
|
5
5
|
import type { Action, MutationState } from './mutation'
|
|
@@ -12,7 +12,7 @@ import { Subscribable } from './subscribable'
|
|
|
12
12
|
|
|
13
13
|
interface MutationCacheConfig {
|
|
14
14
|
onError?: (
|
|
15
|
-
error:
|
|
15
|
+
error: DefaultError,
|
|
16
16
|
variables: unknown,
|
|
17
17
|
context: unknown,
|
|
18
18
|
mutation: Mutation<unknown, unknown, unknown>,
|
|
@@ -25,7 +25,14 @@ interface MutationCacheConfig {
|
|
|
25
25
|
) => Promise<unknown> | unknown
|
|
26
26
|
onMutate?: (
|
|
27
27
|
variables: unknown,
|
|
28
|
-
mutation: Mutation<unknown, unknown, unknown
|
|
28
|
+
mutation: Mutation<unknown, unknown, unknown>,
|
|
29
|
+
) => Promise<unknown> | unknown
|
|
30
|
+
onSettled?: (
|
|
31
|
+
data: unknown | undefined,
|
|
32
|
+
error: DefaultError | null,
|
|
33
|
+
variables: unknown,
|
|
34
|
+
context: unknown,
|
|
35
|
+
mutation: Mutation<unknown, unknown, unknown>,
|
|
29
36
|
) => Promise<unknown> | unknown
|
|
30
37
|
}
|
|
31
38
|
|
|
@@ -126,7 +133,7 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
|
|
|
126
133
|
|
|
127
134
|
find<
|
|
128
135
|
TData = unknown,
|
|
129
|
-
TError =
|
|
136
|
+
TError = DefaultError,
|
|
130
137
|
TVariables = any,
|
|
131
138
|
TContext = unknown,
|
|
132
139
|
>(
|
package/src/mutationObserver.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
MutateOptions,
|
|
8
8
|
MutationObserverResult,
|
|
9
9
|
MutationObserverOptions,
|
|
10
|
-
|
|
10
|
+
DefaultError,
|
|
11
11
|
} from './types'
|
|
12
12
|
import { shallowEqualObjects } from './utils'
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ type MutationObserverListener<TData, TError, TVariables, TContext> = (
|
|
|
21
21
|
|
|
22
22
|
export class MutationObserver<
|
|
23
23
|
TData = unknown,
|
|
24
|
-
TError =
|
|
24
|
+
TError = DefaultError,
|
|
25
25
|
TVariables = void,
|
|
26
26
|
TContext = unknown,
|
|
27
27
|
> extends Subscribable<
|
|
@@ -64,6 +64,7 @@ export class MutationObserver<
|
|
|
64
64
|
observer: this,
|
|
65
65
|
})
|
|
66
66
|
}
|
|
67
|
+
this.#currentMutation?.setOptions(this.options)
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
protected onUnsubscribe(): void {
|
package/src/queriesObserver.ts
CHANGED
|
@@ -26,7 +26,6 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
|
|
|
26
26
|
#result: QueryObserverResult[]
|
|
27
27
|
#queries: QueryObserverOptions[]
|
|
28
28
|
#observers: QueryObserver[]
|
|
29
|
-
#observersMap: Record<string, QueryObserver>
|
|
30
29
|
|
|
31
30
|
constructor(client: QueryClient, queries?: QueryObserverOptions[]) {
|
|
32
31
|
super()
|
|
@@ -35,7 +34,6 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
|
|
|
35
34
|
this.#queries = []
|
|
36
35
|
this.#result = []
|
|
37
36
|
this.#observers = []
|
|
38
|
-
this.#observersMap = {}
|
|
39
37
|
|
|
40
38
|
if (queries) {
|
|
41
39
|
this.setQueries(queries)
|
|
@@ -82,9 +80,6 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
|
|
|
82
80
|
)
|
|
83
81
|
|
|
84
82
|
const newObservers = newObserverMatches.map((match) => match.observer)
|
|
85
|
-
const newObserversMap = Object.fromEntries(
|
|
86
|
-
newObservers.map((observer) => [observer.options.queryHash, observer]),
|
|
87
|
-
)
|
|
88
83
|
const newResult = newObservers.map((observer) =>
|
|
89
84
|
observer.getCurrentResult(),
|
|
90
85
|
)
|
|
@@ -97,7 +92,6 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
|
|
|
97
92
|
}
|
|
98
93
|
|
|
99
94
|
this.#observers = newObservers
|
|
100
|
-
this.#observersMap = newObserversMap
|
|
101
95
|
this.#result = newResult
|
|
102
96
|
|
|
103
97
|
if (!this.hasListeners()) {
|
|
@@ -166,7 +160,9 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
|
|
|
166
160
|
|
|
167
161
|
const getObserver = (options: QueryObserverOptions): QueryObserver => {
|
|
168
162
|
const defaultedOptions = this.#client.defaultQueryOptions(options)
|
|
169
|
-
const currentObserver = this.#
|
|
163
|
+
const currentObserver = this.#observers.find(
|
|
164
|
+
(o) => o.options.queryHash === defaultedOptions.queryHash,
|
|
165
|
+
)
|
|
170
166
|
return (
|
|
171
167
|
currentObserver ?? new QueryObserver(this.#client, defaultedOptions)
|
|
172
168
|
)
|
package/src/query.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
CancelOptions,
|
|
10
10
|
SetDataOptions,
|
|
11
11
|
FetchStatus,
|
|
12
|
-
|
|
12
|
+
DefaultError,
|
|
13
13
|
} from './types'
|
|
14
14
|
import type { QueryCache } from './queryCache'
|
|
15
15
|
import type { QueryObserver } from './queryObserver'
|
|
@@ -34,7 +34,7 @@ interface QueryConfig<
|
|
|
34
34
|
state?: QueryState<TData, TError>
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export interface QueryState<TData = unknown, TError =
|
|
37
|
+
export interface QueryState<TData = unknown, TError = DefaultError> {
|
|
38
38
|
data: TData | undefined
|
|
39
39
|
dataUpdateCount: number
|
|
40
40
|
dataUpdatedAt: number
|
|
@@ -65,7 +65,7 @@ export interface FetchContext<
|
|
|
65
65
|
|
|
66
66
|
export interface QueryBehavior<
|
|
67
67
|
TQueryFnData = unknown,
|
|
68
|
-
TError =
|
|
68
|
+
TError = DefaultError,
|
|
69
69
|
TData = TQueryFnData,
|
|
70
70
|
TQueryKey extends QueryKey = QueryKey,
|
|
71
71
|
> {
|
|
@@ -142,7 +142,7 @@ export interface SetStateOptions {
|
|
|
142
142
|
|
|
143
143
|
export class Query<
|
|
144
144
|
TQueryFnData = unknown,
|
|
145
|
-
TError =
|
|
145
|
+
TError = DefaultError,
|
|
146
146
|
TData = TQueryFnData,
|
|
147
147
|
TQueryKey extends QueryKey = QueryKey,
|
|
148
148
|
> extends Removable {
|
|
@@ -433,7 +433,15 @@ export class Query<
|
|
|
433
433
|
|
|
434
434
|
if (!isCancelledError(error)) {
|
|
435
435
|
// Notify cache callback
|
|
436
|
-
this.#cache.config.onError?.(
|
|
436
|
+
this.#cache.config.onError?.(
|
|
437
|
+
error as any,
|
|
438
|
+
this as Query<any, any, any, any>,
|
|
439
|
+
)
|
|
440
|
+
this.#cache.config.onSettled?.(
|
|
441
|
+
this.state.data,
|
|
442
|
+
error as any,
|
|
443
|
+
this as Query<any, any, any, any>,
|
|
444
|
+
)
|
|
437
445
|
}
|
|
438
446
|
|
|
439
447
|
if (!this.isFetchingOptimistic) {
|
|
@@ -462,6 +470,11 @@ export class Query<
|
|
|
462
470
|
|
|
463
471
|
// Notify cache callback
|
|
464
472
|
this.#cache.config.onSuccess?.(data, this as Query<any, any, any, any>)
|
|
473
|
+
this.#cache.config.onSettled?.(
|
|
474
|
+
data,
|
|
475
|
+
this.state.error as any,
|
|
476
|
+
this as Query<any, any, any, any>,
|
|
477
|
+
)
|
|
465
478
|
|
|
466
479
|
if (!this.isFetchingOptimistic) {
|
|
467
480
|
// Schedule query gc after fetching
|
package/src/queryCache.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
NotifyEvent,
|
|
7
7
|
QueryKey,
|
|
8
8
|
QueryOptions,
|
|
9
|
-
|
|
9
|
+
DefaultError,
|
|
10
10
|
WithRequired,
|
|
11
11
|
} from './types'
|
|
12
12
|
import { notifyManager } from './notifyManager'
|
|
@@ -17,8 +17,16 @@ import type { QueryObserver } from './queryObserver'
|
|
|
17
17
|
// TYPES
|
|
18
18
|
|
|
19
19
|
interface QueryCacheConfig {
|
|
20
|
-
onError?: (
|
|
20
|
+
onError?: (
|
|
21
|
+
error: DefaultError,
|
|
22
|
+
query: Query<unknown, unknown, unknown>,
|
|
23
|
+
) => void
|
|
21
24
|
onSuccess?: (data: unknown, query: Query<unknown, unknown, unknown>) => void
|
|
25
|
+
onSettled?: (
|
|
26
|
+
data: unknown | undefined,
|
|
27
|
+
error: DefaultError | null,
|
|
28
|
+
query: Query<unknown, unknown, unknown>,
|
|
29
|
+
) => void
|
|
22
30
|
createStore?: () => QueryStore
|
|
23
31
|
}
|
|
24
32
|
|
|
@@ -150,7 +158,7 @@ export class QueryCache extends Subscribable<QueryCacheListener> {
|
|
|
150
158
|
|
|
151
159
|
get<
|
|
152
160
|
TQueryFnData = unknown,
|
|
153
|
-
TError =
|
|
161
|
+
TError = DefaultError,
|
|
154
162
|
TData = TQueryFnData,
|
|
155
163
|
TQueryKey extends QueryKey = QueryKey,
|
|
156
164
|
>(
|
|
@@ -165,7 +173,7 @@ export class QueryCache extends Subscribable<QueryCacheListener> {
|
|
|
165
173
|
return [...this.#queries.values()]
|
|
166
174
|
}
|
|
167
175
|
|
|
168
|
-
find<TQueryFnData = unknown, TError =
|
|
176
|
+
find<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData>(
|
|
169
177
|
filters: WithRequired<QueryFilters, 'queryKey'>,
|
|
170
178
|
): Query<TQueryFnData, TError, TData> | undefined {
|
|
171
179
|
if (typeof filters.exact === 'undefined') {
|
package/src/queryClient.ts
CHANGED
|
@@ -24,7 +24,7 @@ import type {
|
|
|
24
24
|
RefetchQueryFilters,
|
|
25
25
|
ResetOptions,
|
|
26
26
|
SetDataOptions,
|
|
27
|
-
|
|
27
|
+
DefaultError,
|
|
28
28
|
} from './types'
|
|
29
29
|
import type { QueryState } from './query'
|
|
30
30
|
import { QueryCache } from './queryCache'
|
|
@@ -177,7 +177,7 @@ export class QueryClient {
|
|
|
177
177
|
)
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
getQueryState<TQueryFnData = unknown, TError =
|
|
180
|
+
getQueryState<TQueryFnData = unknown, TError = DefaultError>(
|
|
181
181
|
queryKey: QueryKey,
|
|
182
182
|
): QueryState<TQueryFnData, TError> | undefined {
|
|
183
183
|
return this.#queryCache.find<TQueryFnData, TError>({ queryKey })?.state
|
|
@@ -272,7 +272,7 @@ export class QueryClient {
|
|
|
272
272
|
|
|
273
273
|
fetchQuery<
|
|
274
274
|
TQueryFnData,
|
|
275
|
-
TError =
|
|
275
|
+
TError = DefaultError,
|
|
276
276
|
TData = TQueryFnData,
|
|
277
277
|
TQueryKey extends QueryKey = QueryKey,
|
|
278
278
|
TPageParam = never,
|
|
@@ -301,7 +301,7 @@ export class QueryClient {
|
|
|
301
301
|
|
|
302
302
|
prefetchQuery<
|
|
303
303
|
TQueryFnData = unknown,
|
|
304
|
-
TError =
|
|
304
|
+
TError = DefaultError,
|
|
305
305
|
TData = TQueryFnData,
|
|
306
306
|
TQueryKey extends QueryKey = QueryKey,
|
|
307
307
|
>(
|
|
@@ -312,7 +312,7 @@ export class QueryClient {
|
|
|
312
312
|
|
|
313
313
|
fetchInfiniteQuery<
|
|
314
314
|
TQueryFnData,
|
|
315
|
-
TError =
|
|
315
|
+
TError = DefaultError,
|
|
316
316
|
TData = TQueryFnData,
|
|
317
317
|
TQueryKey extends QueryKey = QueryKey,
|
|
318
318
|
TPageParam = unknown,
|
|
@@ -331,7 +331,7 @@ export class QueryClient {
|
|
|
331
331
|
|
|
332
332
|
prefetchInfiniteQuery<
|
|
333
333
|
TQueryFnData,
|
|
334
|
-
TError =
|
|
334
|
+
TError = DefaultError,
|
|
335
335
|
TData = TQueryFnData,
|
|
336
336
|
TQueryKey extends QueryKey = QueryKey,
|
|
337
337
|
TPageParam = unknown,
|
|
@@ -422,7 +422,7 @@ export class QueryClient {
|
|
|
422
422
|
|
|
423
423
|
defaultQueryOptions<
|
|
424
424
|
TQueryFnData = unknown,
|
|
425
|
-
TError =
|
|
425
|
+
TError = DefaultError,
|
|
426
426
|
TData = TQueryFnData,
|
|
427
427
|
TQueryData = TQueryFnData,
|
|
428
428
|
TQueryKey extends QueryKey = QueryKey,
|
package/src/queryObserver.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DefaultedQueryObserverOptions,
|
|
1
|
+
import type { DefaultedQueryObserverOptions, DefaultError } from './types'
|
|
2
2
|
import {
|
|
3
3
|
isServer,
|
|
4
4
|
isValidTimeout,
|
|
@@ -39,7 +39,7 @@ export interface ObserverFetchOptions extends FetchOptions {
|
|
|
39
39
|
|
|
40
40
|
export class QueryObserver<
|
|
41
41
|
TQueryFnData = unknown,
|
|
42
|
-
TError =
|
|
42
|
+
TError = DefaultError,
|
|
43
43
|
TData = TQueryFnData,
|
|
44
44
|
TQueryData = TQueryFnData,
|
|
45
45
|
TQueryKey extends QueryKey = QueryKey,
|
package/src/retryer.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { focusManager } from './focusManager'
|
|
2
2
|
import { onlineManager } from './onlineManager'
|
|
3
3
|
import { sleep } from './utils'
|
|
4
|
-
import type { CancelOptions, NetworkMode,
|
|
4
|
+
import type { CancelOptions, NetworkMode, DefaultError } from './types'
|
|
5
5
|
|
|
6
6
|
// TYPES
|
|
7
7
|
|
|
8
|
-
interface RetryerConfig<TData = unknown, TError =
|
|
8
|
+
interface RetryerConfig<TData = unknown, TError = DefaultError> {
|
|
9
9
|
fn: () => TData | Promise<TData>
|
|
10
10
|
abort?: () => void
|
|
11
11
|
onError?: (error: TError) => void
|
|
@@ -28,14 +28,14 @@ export interface Retryer<TData = unknown> {
|
|
|
28
28
|
|
|
29
29
|
export type RetryValue<TError> = boolean | number | ShouldRetryFunction<TError>
|
|
30
30
|
|
|
31
|
-
type ShouldRetryFunction<TError =
|
|
31
|
+
type ShouldRetryFunction<TError = DefaultError> = (
|
|
32
32
|
failureCount: number,
|
|
33
33
|
error: TError,
|
|
34
34
|
) => boolean
|
|
35
35
|
|
|
36
36
|
export type RetryDelayValue<TError> = number | RetryDelayFunction<TError>
|
|
37
37
|
|
|
38
|
-
type RetryDelayFunction<TError =
|
|
38
|
+
type RetryDelayFunction<TError = DefaultError> = (
|
|
39
39
|
failureCount: number,
|
|
40
40
|
error: TError,
|
|
41
41
|
) => number
|
|
@@ -63,7 +63,7 @@ export function isCancelledError(value: any): value is CancelledError {
|
|
|
63
63
|
return value instanceof CancelledError
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
export function createRetryer<TData = unknown, TError =
|
|
66
|
+
export function createRetryer<TData = unknown, TError = DefaultError>(
|
|
67
67
|
config: RetryerConfig<TData, TError>,
|
|
68
68
|
): Retryer<TData> {
|
|
69
69
|
let isRetryCancelled = false
|
|
@@ -3,11 +3,13 @@ import { queryKey, sleep, executeMutation, createQueryClient } from './utils'
|
|
|
3
3
|
import { MutationCache, MutationObserver } from '..'
|
|
4
4
|
|
|
5
5
|
describe('mutationCache', () => {
|
|
6
|
-
describe('MutationCacheConfig
|
|
7
|
-
test('should
|
|
6
|
+
describe('MutationCacheConfig error callbacks', () => {
|
|
7
|
+
test('should call onError and onSettled when a mutation errors', async () => {
|
|
8
8
|
const key = queryKey()
|
|
9
9
|
const onError = jest.fn()
|
|
10
|
-
const
|
|
10
|
+
const onSuccess = jest.fn()
|
|
11
|
+
const onSettled = jest.fn()
|
|
12
|
+
const testCache = new MutationCache({ onError, onSuccess, onSettled })
|
|
11
13
|
const testClient = createQueryClient({ mutationCache: testCache })
|
|
12
14
|
|
|
13
15
|
try {
|
|
@@ -23,12 +25,22 @@ describe('mutationCache', () => {
|
|
|
23
25
|
} catch {}
|
|
24
26
|
|
|
25
27
|
const mutation = testCache.getAll()[0]
|
|
28
|
+
expect(onError).toHaveBeenCalledTimes(1)
|
|
26
29
|
expect(onError).toHaveBeenCalledWith(
|
|
27
30
|
new Error('error'),
|
|
28
31
|
'vars',
|
|
29
32
|
'context',
|
|
30
33
|
mutation,
|
|
31
34
|
)
|
|
35
|
+
expect(onSuccess).not.toHaveBeenCalled()
|
|
36
|
+
expect(onSettled).toHaveBeenCalledTimes(1)
|
|
37
|
+
expect(onSettled).toHaveBeenCalledWith(
|
|
38
|
+
undefined,
|
|
39
|
+
new Error('error'),
|
|
40
|
+
'vars',
|
|
41
|
+
'context',
|
|
42
|
+
mutation,
|
|
43
|
+
)
|
|
32
44
|
})
|
|
33
45
|
|
|
34
46
|
test('should be awaited', async () => {
|
|
@@ -39,7 +51,12 @@ describe('mutationCache', () => {
|
|
|
39
51
|
await sleep(1)
|
|
40
52
|
states.push(2)
|
|
41
53
|
}
|
|
42
|
-
const
|
|
54
|
+
const onSettled = async () => {
|
|
55
|
+
states.push(5)
|
|
56
|
+
await sleep(1)
|
|
57
|
+
states.push(6)
|
|
58
|
+
}
|
|
59
|
+
const testCache = new MutationCache({ onError, onSettled })
|
|
43
60
|
const testClient = createQueryClient({ mutationCache: testCache })
|
|
44
61
|
|
|
45
62
|
try {
|
|
@@ -53,19 +70,26 @@ describe('mutationCache', () => {
|
|
|
53
70
|
await sleep(1)
|
|
54
71
|
states.push(4)
|
|
55
72
|
},
|
|
73
|
+
onSettled: async () => {
|
|
74
|
+
states.push(7)
|
|
75
|
+
await sleep(1)
|
|
76
|
+
states.push(8)
|
|
77
|
+
},
|
|
56
78
|
},
|
|
57
79
|
'vars',
|
|
58
80
|
)
|
|
59
81
|
} catch {}
|
|
60
82
|
|
|
61
|
-
expect(states).toEqual([1, 2, 3, 4])
|
|
83
|
+
expect(states).toEqual([1, 2, 3, 4, 5, 6, 7, 8])
|
|
62
84
|
})
|
|
63
85
|
})
|
|
64
|
-
describe('MutationCacheConfig
|
|
65
|
-
test('should
|
|
86
|
+
describe('MutationCacheConfig success callbacks', () => {
|
|
87
|
+
test('should call onSuccess and onSettled when a mutation is successful', async () => {
|
|
66
88
|
const key = queryKey()
|
|
89
|
+
const onError = jest.fn()
|
|
67
90
|
const onSuccess = jest.fn()
|
|
68
|
-
const
|
|
91
|
+
const onSettled = jest.fn()
|
|
92
|
+
const testCache = new MutationCache({ onError, onSuccess, onSettled })
|
|
69
93
|
const testClient = createQueryClient({ mutationCache: testCache })
|
|
70
94
|
|
|
71
95
|
try {
|
|
@@ -81,12 +105,22 @@ describe('mutationCache', () => {
|
|
|
81
105
|
} catch {}
|
|
82
106
|
|
|
83
107
|
const mutation = testCache.getAll()[0]
|
|
108
|
+
expect(onSuccess).toHaveBeenCalledTimes(1)
|
|
84
109
|
expect(onSuccess).toHaveBeenCalledWith(
|
|
85
110
|
{ data: 5 },
|
|
86
111
|
'vars',
|
|
87
112
|
'context',
|
|
88
113
|
mutation,
|
|
89
114
|
)
|
|
115
|
+
expect(onError).not.toHaveBeenCalled()
|
|
116
|
+
expect(onSettled).toHaveBeenCalledTimes(1)
|
|
117
|
+
expect(onSettled).toHaveBeenCalledWith(
|
|
118
|
+
{ data: 5 },
|
|
119
|
+
null,
|
|
120
|
+
'vars',
|
|
121
|
+
'context',
|
|
122
|
+
mutation,
|
|
123
|
+
)
|
|
90
124
|
})
|
|
91
125
|
test('should be awaited', async () => {
|
|
92
126
|
const key = queryKey()
|
|
@@ -96,7 +130,12 @@ describe('mutationCache', () => {
|
|
|
96
130
|
await sleep(1)
|
|
97
131
|
states.push(2)
|
|
98
132
|
}
|
|
99
|
-
const
|
|
133
|
+
const onSettled = async () => {
|
|
134
|
+
states.push(5)
|
|
135
|
+
await sleep(1)
|
|
136
|
+
states.push(6)
|
|
137
|
+
}
|
|
138
|
+
const testCache = new MutationCache({ onSuccess, onSettled })
|
|
100
139
|
const testClient = createQueryClient({ mutationCache: testCache })
|
|
101
140
|
|
|
102
141
|
await executeMutation(
|
|
@@ -109,11 +148,16 @@ describe('mutationCache', () => {
|
|
|
109
148
|
await sleep(1)
|
|
110
149
|
states.push(4)
|
|
111
150
|
},
|
|
151
|
+
onSettled: async () => {
|
|
152
|
+
states.push(7)
|
|
153
|
+
await sleep(1)
|
|
154
|
+
states.push(8)
|
|
155
|
+
},
|
|
112
156
|
},
|
|
113
157
|
'vars',
|
|
114
158
|
)
|
|
115
159
|
|
|
116
|
-
expect(states).toEqual([1, 2, 3, 4])
|
|
160
|
+
expect(states).toEqual([1, 2, 3, 4, 5, 6, 7, 8])
|
|
117
161
|
})
|
|
118
162
|
})
|
|
119
163
|
describe('MutationCacheConfig.onMutate', () => {
|
|
@@ -2,6 +2,7 @@ import type { QueryClient } from '..'
|
|
|
2
2
|
import { createQueryClient, executeMutation, queryKey, sleep } from './utils'
|
|
3
3
|
import type { MutationState } from '../mutation'
|
|
4
4
|
import { MutationObserver } from '../mutationObserver'
|
|
5
|
+
import { waitFor } from '@testing-library/react'
|
|
5
6
|
|
|
6
7
|
describe('mutations', () => {
|
|
7
8
|
let queryClient: QueryClient
|
|
@@ -377,4 +378,34 @@ describe('mutations', () => {
|
|
|
377
378
|
expect(onSuccess).not.toHaveBeenCalled()
|
|
378
379
|
expect(onSettled).not.toHaveBeenCalled()
|
|
379
380
|
})
|
|
381
|
+
|
|
382
|
+
test('mutation callbacks should see updated options', async () => {
|
|
383
|
+
const onSuccess = jest.fn()
|
|
384
|
+
|
|
385
|
+
const mutation = new MutationObserver(queryClient, {
|
|
386
|
+
mutationFn: async () => {
|
|
387
|
+
sleep(100)
|
|
388
|
+
return 'update'
|
|
389
|
+
},
|
|
390
|
+
onSuccess: () => {
|
|
391
|
+
onSuccess(1)
|
|
392
|
+
},
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
void mutation.mutate()
|
|
396
|
+
|
|
397
|
+
mutation.setOptions({
|
|
398
|
+
mutationFn: async () => {
|
|
399
|
+
sleep(100)
|
|
400
|
+
return 'update'
|
|
401
|
+
},
|
|
402
|
+
onSuccess: () => {
|
|
403
|
+
onSuccess(2)
|
|
404
|
+
},
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
await waitFor(() => expect(onSuccess).toHaveBeenCalledTimes(1))
|
|
408
|
+
|
|
409
|
+
expect(onSuccess).toHaveBeenCalledWith(2)
|
|
410
|
+
})
|
|
380
411
|
})
|