@tanstack/query-core 5.0.0-alpha.1 → 5.0.0-alpha.18

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.
Files changed (143) hide show
  1. package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js +13 -0
  2. package/build/lib/_virtual/_rollupPluginBabelHelpers.esm.js.map +1 -0
  3. package/build/lib/_virtual/_rollupPluginBabelHelpers.js +16 -0
  4. package/build/lib/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  5. package/build/lib/focusManager.esm.js +31 -15
  6. package/build/lib/focusManager.esm.js.map +1 -1
  7. package/build/lib/focusManager.js +31 -15
  8. package/build/lib/focusManager.js.map +1 -1
  9. package/build/lib/hydration.d.ts +2 -6
  10. package/build/lib/hydration.esm.js +9 -20
  11. package/build/lib/hydration.esm.js.map +1 -1
  12. package/build/lib/hydration.js +9 -20
  13. package/build/lib/hydration.js.map +1 -1
  14. package/build/lib/hydration.mjs +4 -18
  15. package/build/lib/hydration.mjs.map +1 -1
  16. package/build/lib/index.d.ts +4 -4
  17. package/build/lib/index.esm.js +1 -1
  18. package/build/lib/index.js +1 -0
  19. package/build/lib/index.js.map +1 -1
  20. package/build/lib/index.mjs +1 -1
  21. package/build/lib/infiniteQueryBehavior.d.ts +2 -2
  22. package/build/lib/infiniteQueryBehavior.esm.js +52 -48
  23. package/build/lib/infiniteQueryBehavior.esm.js.map +1 -1
  24. package/build/lib/infiniteQueryBehavior.js +52 -48
  25. package/build/lib/infiniteQueryBehavior.js.map +1 -1
  26. package/build/lib/infiniteQueryBehavior.mjs +48 -45
  27. package/build/lib/infiniteQueryBehavior.mjs.map +1 -1
  28. package/build/lib/infiniteQueryObserver.d.ts +7 -7
  29. package/build/lib/infiniteQueryObserver.esm.js +7 -8
  30. package/build/lib/infiniteQueryObserver.esm.js.map +1 -1
  31. package/build/lib/infiniteQueryObserver.js +7 -8
  32. package/build/lib/infiniteQueryObserver.js.map +1 -1
  33. package/build/lib/infiniteQueryObserver.mjs +4 -6
  34. package/build/lib/infiniteQueryObserver.mjs.map +1 -1
  35. package/build/lib/mutation.d.ts +5 -4
  36. package/build/lib/mutation.esm.js +138 -99
  37. package/build/lib/mutation.esm.js.map +1 -1
  38. package/build/lib/mutation.js +138 -99
  39. package/build/lib/mutation.js.map +1 -1
  40. package/build/lib/mutation.mjs +16 -2
  41. package/build/lib/mutation.mjs.map +1 -1
  42. package/build/lib/mutationCache.d.ts +5 -4
  43. package/build/lib/mutationCache.esm.js +34 -20
  44. package/build/lib/mutationCache.esm.js.map +1 -1
  45. package/build/lib/mutationCache.js +34 -20
  46. package/build/lib/mutationCache.js.map +1 -1
  47. package/build/lib/mutationCache.mjs +5 -4
  48. package/build/lib/mutationCache.mjs.map +1 -1
  49. package/build/lib/mutationObserver.d.ts +2 -2
  50. package/build/lib/mutationObserver.esm.js +81 -50
  51. package/build/lib/mutationObserver.esm.js.map +1 -1
  52. package/build/lib/mutationObserver.js +81 -50
  53. package/build/lib/mutationObserver.js.map +1 -1
  54. package/build/lib/mutationObserver.mjs +1 -0
  55. package/build/lib/mutationObserver.mjs.map +1 -1
  56. package/build/lib/onlineManager.esm.js +29 -14
  57. package/build/lib/onlineManager.esm.js.map +1 -1
  58. package/build/lib/onlineManager.js +29 -14
  59. package/build/lib/onlineManager.js.map +1 -1
  60. package/build/lib/queriesObserver.esm.js +94 -69
  61. package/build/lib/queriesObserver.esm.js.map +1 -1
  62. package/build/lib/queriesObserver.js +94 -69
  63. package/build/lib/queriesObserver.js.map +1 -1
  64. package/build/lib/queriesObserver.mjs +1 -5
  65. package/build/lib/queriesObserver.mjs.map +1 -1
  66. package/build/lib/query.d.ts +8 -7
  67. package/build/lib/query.esm.js +210 -159
  68. package/build/lib/query.esm.js.map +1 -1
  69. package/build/lib/query.js +210 -159
  70. package/build/lib/query.js.map +1 -1
  71. package/build/lib/query.mjs +2 -0
  72. package/build/lib/query.mjs.map +1 -1
  73. package/build/lib/queryCache.d.ts +5 -4
  74. package/build/lib/queryCache.esm.js +21 -13
  75. package/build/lib/queryCache.esm.js.map +1 -1
  76. package/build/lib/queryCache.js +21 -13
  77. package/build/lib/queryCache.js.map +1 -1
  78. package/build/lib/queryCache.mjs +5 -4
  79. package/build/lib/queryCache.mjs.map +1 -1
  80. package/build/lib/queryClient.d.ts +7 -7
  81. package/build/lib/queryClient.esm.js +107 -66
  82. package/build/lib/queryClient.esm.js.map +1 -1
  83. package/build/lib/queryClient.js +107 -66
  84. package/build/lib/queryClient.js.map +1 -1
  85. package/build/lib/queryClient.mjs +5 -4
  86. package/build/lib/queryClient.mjs.map +1 -1
  87. package/build/lib/queryObserver.d.ts +2 -2
  88. package/build/lib/queryObserver.esm.js +308 -207
  89. package/build/lib/queryObserver.esm.js.map +1 -1
  90. package/build/lib/queryObserver.js +307 -206
  91. package/build/lib/queryObserver.js.map +1 -1
  92. package/build/lib/queryObserver.mjs.map +1 -1
  93. package/build/lib/removable.esm.js +13 -6
  94. package/build/lib/removable.esm.js.map +1 -1
  95. package/build/lib/removable.js +13 -6
  96. package/build/lib/removable.js.map +1 -1
  97. package/build/lib/retryer.d.ts +5 -5
  98. package/build/lib/retryer.esm.js +15 -14
  99. package/build/lib/retryer.esm.js.map +1 -1
  100. package/build/lib/retryer.js +15 -14
  101. package/build/lib/retryer.js.map +1 -1
  102. package/build/lib/retryer.mjs.map +1 -1
  103. package/build/lib/tests/utils.d.ts +4 -5
  104. package/build/lib/types.d.ts +42 -40
  105. package/build/lib/utils.esm.js +1 -1
  106. package/build/lib/utils.esm.js.map +1 -1
  107. package/build/lib/utils.js +1 -1
  108. package/build/lib/utils.js.map +1 -1
  109. package/build/umd/index.development.js +92 -88
  110. package/build/umd/index.development.js.map +1 -1
  111. package/build/umd/index.production.js +1 -1
  112. package/build/umd/index.production.js.map +1 -1
  113. package/package.json +2 -2
  114. package/src/hydration.ts +18 -37
  115. package/src/index.ts +9 -5
  116. package/src/infiniteQueryBehavior.ts +52 -60
  117. package/src/infiniteQueryObserver.ts +17 -12
  118. package/src/mutation.ts +34 -7
  119. package/src/mutationCache.ts +15 -8
  120. package/src/mutationObserver.ts +3 -2
  121. package/src/queriesObserver.ts +3 -7
  122. package/src/query.ts +24 -9
  123. package/src/queryCache.ts +16 -10
  124. package/src/queryClient.ts +9 -11
  125. package/src/queryObserver.ts +2 -2
  126. package/src/retryer.ts +5 -5
  127. package/src/tests/focusManager.test.tsx +12 -14
  128. package/src/tests/hydration.test.tsx +22 -17
  129. package/src/tests/infiniteQueryBehavior.test.tsx +16 -9
  130. package/src/tests/infiniteQueryObserver.test.tsx +62 -1
  131. package/src/tests/mutationCache.test.tsx +61 -16
  132. package/src/tests/mutationObserver.test.tsx +3 -2
  133. package/src/tests/mutations.test.tsx +41 -9
  134. package/src/tests/notifyManager.test.tsx +7 -6
  135. package/src/tests/onlineManager.test.tsx +12 -17
  136. package/src/tests/queriesObserver.test.tsx +18 -17
  137. package/src/tests/query.test.tsx +18 -17
  138. package/src/tests/queryCache.test.tsx +28 -15
  139. package/src/tests/queryClient.test.tsx +49 -48
  140. package/src/tests/queryObserver.test.tsx +10 -9
  141. package/src/tests/utils.test.tsx +2 -1
  142. package/src/tests/utils.ts +5 -4
  143. package/src/types.ts +53 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/query-core",
3
- "version": "5.0.0-alpha.1",
3
+ "version": "5.0.0-alpha.18",
4
4
  "description": "The framework agnostic core that powers TanStack Query",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "clean": "rimraf ./build",
32
32
  "test:eslint": "eslint --ext .ts,.tsx ./src",
33
33
  "test:types": "tsc",
34
- "test:lib": "jest --config ./jest.config.ts",
34
+ "test:lib": "vitest run --coverage",
35
35
  "test:lib:dev": "pnpm run test:lib --watch",
36
36
  "build:types": "tsc --build"
37
37
  }
package/src/hydration.ts CHANGED
@@ -11,10 +11,8 @@ import type { Mutation, MutationState } from './mutation'
11
11
  // TYPES
12
12
 
13
13
  export interface DehydrateOptions {
14
- dehydrateMutations?: boolean
15
- dehydrateQueries?: boolean
16
- shouldDehydrateMutation?: ShouldDehydrateMutationFunction
17
- shouldDehydrateQuery?: ShouldDehydrateQueryFunction
14
+ shouldDehydrateMutation?: (mutation: Mutation) => boolean
15
+ shouldDehydrateQuery?: (query: Query) => boolean
18
16
  }
19
17
 
20
18
  export interface HydrateOptions {
@@ -40,10 +38,6 @@ export interface DehydratedState {
40
38
  queries: DehydratedQuery[]
41
39
  }
42
40
 
43
- export type ShouldDehydrateQueryFunction = (query: Query) => boolean
44
-
45
- export type ShouldDehydrateMutationFunction = (mutation: Mutation) => boolean
46
-
47
41
  // FUNCTIONS
48
42
 
49
43
  function dehydrateMutation(mutation: Mutation): DehydratedMutation {
@@ -77,36 +71,23 @@ export function dehydrate(
77
71
  client: QueryClient,
78
72
  options: DehydrateOptions = {},
79
73
  ): DehydratedState {
80
- const mutations: DehydratedMutation[] = []
81
- const queries: DehydratedQuery[] = []
82
-
83
- if (options.dehydrateMutations !== false) {
84
- const shouldDehydrateMutation =
85
- options.shouldDehydrateMutation || defaultShouldDehydrateMutation
86
-
87
- client
88
- .getMutationCache()
89
- .getAll()
90
- .forEach((mutation) => {
91
- if (shouldDehydrateMutation(mutation)) {
92
- mutations.push(dehydrateMutation(mutation))
93
- }
94
- })
95
- }
74
+ const filterMutation =
75
+ options.shouldDehydrateMutation ?? defaultShouldDehydrateMutation
76
+
77
+ const mutations = client
78
+ .getMutationCache()
79
+ .getAll()
80
+ .flatMap((mutation) =>
81
+ filterMutation(mutation) ? [dehydrateMutation(mutation)] : [],
82
+ )
96
83
 
97
- if (options.dehydrateQueries !== false) {
98
- const shouldDehydrateQuery =
99
- options.shouldDehydrateQuery || defaultShouldDehydrateQuery
100
-
101
- client
102
- .getQueryCache()
103
- .getAll()
104
- .forEach((query) => {
105
- if (shouldDehydrateQuery(query)) {
106
- queries.push(dehydrateQuery(query))
107
- }
108
- })
109
- }
84
+ const filterQuery =
85
+ options.shouldDehydrateQuery ?? defaultShouldDehydrateQuery
86
+
87
+ const queries = client
88
+ .getQueryCache()
89
+ .getAll()
90
+ .flatMap((query) => (filterQuery(query) ? [dehydrateQuery(query)] : []))
110
91
 
111
92
  return { mutations, queries }
112
93
  }
package/src/index.ts CHANGED
@@ -11,24 +11,28 @@ export { MutationObserver } from './mutationObserver'
11
11
  export { notifyManager } from './notifyManager'
12
12
  export { focusManager } from './focusManager'
13
13
  export { onlineManager } from './onlineManager'
14
- export { hashKey, replaceEqualDeep, isServer, keepPreviousData } from './utils'
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 {
18
24
  dehydrate,
19
25
  hydrate,
20
- defaultShouldDehydrateMutation,
21
26
  defaultShouldDehydrateQuery,
27
+ defaultShouldDehydrateMutation,
22
28
  } from './hydration'
23
29
 
24
30
  // Types
25
31
  export * from './types'
26
32
  export type { Query, QueryState } from './query'
27
- export type { Mutation } from './mutation'
33
+ export type { Mutation, MutationState } from './mutation'
28
34
  export type {
29
35
  DehydrateOptions,
30
36
  DehydratedState,
31
37
  HydrateOptions,
32
- ShouldDehydrateMutationFunction,
33
- ShouldDehydrateQueryFunction,
34
38
  } from './hydration'
@@ -14,12 +14,12 @@ export function infiniteQueryBehavior<
14
14
  >(): QueryBehavior<TQueryFnData, TError, InfiniteData<TData>> {
15
15
  return {
16
16
  onFetch: (context) => {
17
- context.fetchFn = () => {
17
+ context.fetchFn = async () => {
18
18
  const options = context.options as InfiniteQueryPageParamsOptions<TData>
19
19
  const direction = context.fetchOptions?.meta?.fetchMore?.direction
20
20
  const oldPages = context.state.data?.pages || []
21
21
  const oldPageParams = context.state.data?.pageParams || []
22
- let newPageParams = oldPageParams
22
+ const empty = { pages: [], pageParams: [] }
23
23
  let cancelled = false
24
24
 
25
25
  const addSignalProperty = (object: unknown) => {
@@ -43,35 +43,18 @@ export function infiniteQueryBehavior<
43
43
  context.options.queryFn ||
44
44
  (() => Promise.reject(new Error('Missing queryFn')))
45
45
 
46
- const buildNewPages = (
47
- pages: unknown[],
48
- param: unknown,
49
- page: unknown,
50
- previous?: boolean,
51
- ) => {
52
- const { maxPages } = context.options
53
-
54
- if (previous) {
55
- newPageParams = addToStart(newPageParams, param, maxPages)
56
- return addToStart(pages, page, maxPages)
57
- }
58
-
59
- newPageParams = addToEnd(newPageParams, param, maxPages)
60
- return addToEnd(pages, page, maxPages)
61
- }
62
-
63
46
  // Create function to fetch a page
64
- const fetchPage = (
65
- pages: unknown[],
47
+ const fetchPage = async (
48
+ data: InfiniteData<unknown>,
66
49
  param: unknown,
67
50
  previous?: boolean,
68
- ): Promise<unknown[]> => {
51
+ ): Promise<InfiniteData<unknown>> => {
69
52
  if (cancelled) {
70
53
  return Promise.reject()
71
54
  }
72
55
 
73
- if (typeof param === 'undefined' && pages.length) {
74
- return Promise.resolve(pages)
56
+ if (typeof param === 'undefined' && data.pages.length) {
57
+ return Promise.resolve(data)
75
58
  }
76
59
 
77
60
  const queryFnContext: Omit<
@@ -80,60 +63,58 @@ export function infiniteQueryBehavior<
80
63
  > = {
81
64
  queryKey: context.queryKey,
82
65
  pageParam: param,
66
+ direction: previous ? 'backward' : 'forward',
83
67
  meta: context.options.meta,
84
68
  }
85
69
 
86
70
  addSignalProperty(queryFnContext)
87
71
 
88
- const queryFnResult = queryFn(
72
+ const page = await queryFn(
89
73
  queryFnContext as QueryFunctionContext<QueryKey, unknown>,
90
74
  )
91
75
 
92
- const promise = Promise.resolve(queryFnResult).then((page) =>
93
- buildNewPages(pages, param, page, previous),
94
- )
76
+ const { maxPages } = context.options
77
+ const addTo = previous ? addToStart : addToEnd
95
78
 
96
- return promise
79
+ return {
80
+ pages: addTo(data.pages, page, maxPages),
81
+ pageParams: addTo(data.pageParams, param, maxPages),
82
+ }
97
83
  }
98
84
 
99
- let promise: Promise<unknown[]>
85
+ let result: InfiniteData<unknown>
100
86
 
101
87
  // Fetch first page?
102
88
  if (!oldPages.length) {
103
- promise = fetchPage([], options.defaultPageParam)
89
+ result = await fetchPage(empty, options.defaultPageParam)
104
90
  }
105
91
 
106
92
  // fetch next / previous page?
107
93
  else if (direction) {
108
94
  const previous = direction === 'backward'
109
- const param = previous
110
- ? getPreviousPageParam(options, oldPages)
111
- : getNextPageParam(options, oldPages)
112
- promise = fetchPage(oldPages, param, previous)
95
+ const pageParamFn = previous ? getPreviousPageParam : getNextPageParam
96
+ const oldData = {
97
+ pages: oldPages,
98
+ pageParams: oldPageParams,
99
+ }
100
+ const param = pageParamFn(options, oldData)
101
+
102
+ result = await fetchPage(oldData, param, previous)
113
103
  }
114
104
 
115
105
  // Refetch pages
116
106
  else {
117
- newPageParams = []
118
-
119
107
  // Fetch first page
120
- promise = fetchPage([], oldPageParams[0])
108
+ result = await fetchPage(empty, oldPageParams[0])
121
109
 
122
110
  // Fetch remaining pages
123
111
  for (let i = 1; i < oldPages.length; i++) {
124
- promise = promise.then((pages) => {
125
- const param = getNextPageParam(options, pages)
126
- return fetchPage(pages, param)
127
- })
112
+ const param = getNextPageParam(options, result)
113
+ result = await fetchPage(result, param)
128
114
  }
129
115
  }
130
116
 
131
- const finalPromise = promise.then((pages) => ({
132
- pages,
133
- pageParams: newPageParams,
134
- }))
135
-
136
- return finalPromise
117
+ return result
137
118
  }
138
119
  },
139
120
  }
@@ -141,36 +122,47 @@ export function infiniteQueryBehavior<
141
122
 
142
123
  function getNextPageParam(
143
124
  options: InfiniteQueryPageParamsOptions<any>,
144
- pages: unknown[],
125
+ { pages, pageParams }: InfiniteData<unknown>,
145
126
  ): unknown | undefined {
146
- return options.getNextPageParam(pages[pages.length - 1], pages)
127
+ const lastIndex = pages.length - 1
128
+ return options.getNextPageParam(
129
+ pages[lastIndex],
130
+ pages,
131
+ pageParams[lastIndex],
132
+ pageParams,
133
+ )
147
134
  }
148
135
 
149
136
  function getPreviousPageParam(
150
137
  options: InfiniteQueryPageParamsOptions<any>,
151
- pages: unknown[],
138
+ { pages, pageParams }: InfiniteData<unknown>,
152
139
  ): unknown | undefined {
153
- return options.getPreviousPageParam?.(pages[0], pages)
140
+ return options.getPreviousPageParam?.(
141
+ pages[0],
142
+ pages,
143
+ pageParams[0],
144
+ pageParams,
145
+ )
154
146
  }
155
147
 
156
148
  /**
157
149
  * Checks if there is a next page.
158
150
  */
159
151
  export function hasNextPage(
160
- options: InfiniteQueryPageParamsOptions<any>,
161
- pages?: unknown[],
152
+ options: InfiniteQueryPageParamsOptions<any, any>,
153
+ data?: InfiniteData<unknown>,
162
154
  ): boolean {
163
- if (!pages) return false
164
- return typeof getNextPageParam(options, pages) !== 'undefined'
155
+ if (!data) return false
156
+ return typeof getNextPageParam(options, data) !== 'undefined'
165
157
  }
166
158
 
167
159
  /**
168
160
  * Checks if there is a previous page.
169
161
  */
170
162
  export function hasPreviousPage(
171
- options: InfiniteQueryPageParamsOptions<any>,
172
- pages?: unknown[],
163
+ options: InfiniteQueryPageParamsOptions<any, any>,
164
+ data?: InfiniteData<unknown>,
173
165
  ): boolean {
174
- if (!pages || !options.getPreviousPageParam) return false
175
- return typeof getPreviousPageParam(options, pages) !== 'undefined'
166
+ if (!data || !options.getPreviousPageParam) return false
167
+ return typeof getPreviousPageParam(options, data) !== 'undefined'
176
168
  }
@@ -6,7 +6,7 @@ import type {
6
6
  InfiniteQueryObserverOptions,
7
7
  InfiniteQueryObserverResult,
8
8
  QueryKey,
9
- RegisteredError,
9
+ DefaultError,
10
10
  } from './types'
11
11
  import type { QueryClient } from './queryClient'
12
12
  import type { NotifyOptions, ObserverFetchOptions } from './queryObserver'
@@ -24,10 +24,11 @@ type InfiniteQueryObserverListener<TData, TError> = (
24
24
 
25
25
  export class InfiniteQueryObserver<
26
26
  TQueryFnData = unknown,
27
- TError = RegisteredError,
27
+ TError = DefaultError,
28
28
  TData = InfiniteData<TQueryFnData>,
29
29
  TQueryData = TQueryFnData,
30
30
  TQueryKey extends QueryKey = QueryKey,
31
+ TPageParam = unknown,
31
32
  > extends QueryObserver<
32
33
  TQueryFnData,
33
34
  TError,
@@ -56,7 +57,8 @@ export class InfiniteQueryObserver<
56
57
  TError,
57
58
  TData,
58
59
  TQueryData,
59
- TQueryKey
60
+ TQueryKey,
61
+ TPageParam
60
62
  >,
61
63
  ) {
62
64
  super(client, options)
@@ -74,7 +76,8 @@ export class InfiniteQueryObserver<
74
76
  TError,
75
77
  TData,
76
78
  TQueryData,
77
- TQueryKey
79
+ TQueryKey,
80
+ TPageParam
78
81
  >,
79
82
  notifyOptions?: NotifyOptions,
80
83
  ): void {
@@ -93,7 +96,8 @@ export class InfiniteQueryObserver<
93
96
  TError,
94
97
  TData,
95
98
  TQueryData,
96
- TQueryKey
99
+ TQueryKey,
100
+ TPageParam
97
101
  >,
98
102
  ): InfiniteQueryObserverResult<TData, TError> {
99
103
  options.behavior = infiniteQueryBehavior()
@@ -104,7 +108,7 @@ export class InfiniteQueryObserver<
104
108
  }
105
109
 
106
110
  fetchNextPage(
107
- options: FetchNextPageOptions = {},
111
+ options?: FetchNextPageOptions,
108
112
  ): Promise<InfiniteQueryObserverResult<TData, TError>> {
109
113
  return this.fetch({
110
114
  ...options,
@@ -114,9 +118,9 @@ export class InfiniteQueryObserver<
114
118
  })
115
119
  }
116
120
 
117
- fetchPreviousPage({ ...options }: FetchPreviousPageOptions = {}): Promise<
118
- InfiniteQueryObserverResult<TData, TError>
119
- > {
121
+ fetchPreviousPage(
122
+ options?: FetchPreviousPageOptions,
123
+ ): Promise<InfiniteQueryObserverResult<TData, TError>> {
120
124
  return this.fetch({
121
125
  ...options,
122
126
  meta: {
@@ -132,7 +136,8 @@ export class InfiniteQueryObserver<
132
136
  TError,
133
137
  TData,
134
138
  TQueryData,
135
- TQueryKey
139
+ TQueryKey,
140
+ TPageParam
136
141
  >,
137
142
  ): InfiniteQueryObserverResult<TData, TError> {
138
143
  const { state } = query
@@ -150,8 +155,8 @@ export class InfiniteQueryObserver<
150
155
  ...result,
151
156
  fetchNextPage: this.fetchNextPage,
152
157
  fetchPreviousPage: this.fetchPreviousPage,
153
- hasNextPage: hasNextPage(options, state.data?.pages),
154
- hasPreviousPage: hasPreviousPage(options, state.data?.pages),
158
+ hasNextPage: hasNextPage(options, state.data),
159
+ hasPreviousPage: hasPreviousPage(options, state.data),
155
160
  isFetchingNextPage,
156
161
  isFetchingPreviousPage,
157
162
  isRefetching:
package/src/mutation.ts CHANGED
@@ -2,7 +2,7 @@ import type {
2
2
  MutationOptions,
3
3
  MutationStatus,
4
4
  MutationMeta,
5
- RegisteredError,
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 = RegisteredError,
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 = RegisteredError,
83
+ TError = DefaultError,
84
84
  TVariables = void,
85
85
  TContext = unknown,
86
86
  > extends Removable {
87
87
  state: MutationState<TData, TError, TVariables, TContext>
88
- readonly options: MutationOptions<TData, TError, TVariables, TContext>
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.updateGcTime(this.options.gcTime)
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,
@@ -1,5 +1,5 @@
1
1
  import type { MutationObserver } from './mutationObserver'
2
- import type { NotifyEvent, MutationOptions, RegisteredError } from './types'
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: unknown,
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, 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,17 +133,17 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
126
133
 
127
134
  find<
128
135
  TData = unknown,
129
- TError = RegisteredError,
136
+ TError = DefaultError,
130
137
  TVariables = any,
131
138
  TContext = unknown,
132
139
  >(
133
140
  filters: MutationFilters,
134
141
  ): Mutation<TData, TError, TVariables, TContext> | undefined {
135
- if (typeof filters.exact === 'undefined') {
136
- filters.exact = true
137
- }
142
+ const defaultedFilters = { exact: true, ...filters }
138
143
 
139
- return this.#mutations.find((mutation) => matchMutation(filters, mutation))
144
+ return this.#mutations.find((mutation) =>
145
+ matchMutation(defaultedFilters, mutation),
146
+ )
140
147
  }
141
148
 
142
149
  findAll(filters: MutationFilters = {}): Mutation[] {
@@ -7,7 +7,7 @@ import type {
7
7
  MutateOptions,
8
8
  MutationObserverResult,
9
9
  MutationObserverOptions,
10
- RegisteredError,
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 = RegisteredError,
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 {
@@ -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.#observersMap[defaultedOptions.queryHash!]
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
  )