@tanstack/query-core 5.100.0 → 5.100.2

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 (50) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.cts +5 -7
  2. package/build/legacy/_tsup-dts-rollup.d.ts +5 -7
  3. package/build/legacy/hydration.cjs +32 -6
  4. package/build/legacy/hydration.cjs.map +1 -1
  5. package/build/legacy/hydration.js +32 -6
  6. package/build/legacy/hydration.js.map +1 -1
  7. package/build/legacy/infiniteQueryObserver.cjs +3 -5
  8. package/build/legacy/infiniteQueryObserver.cjs.map +1 -1
  9. package/build/legacy/infiniteQueryObserver.js +4 -10
  10. package/build/legacy/infiniteQueryObserver.js.map +1 -1
  11. package/build/legacy/query.cjs +26 -14
  12. package/build/legacy/query.cjs.map +1 -1
  13. package/build/legacy/query.d.cts +0 -1
  14. package/build/legacy/query.d.ts +0 -1
  15. package/build/legacy/query.js +26 -14
  16. package/build/legacy/query.js.map +1 -1
  17. package/build/legacy/queryClient.cjs +2 -3
  18. package/build/legacy/queryClient.cjs.map +1 -1
  19. package/build/legacy/queryClient.js +2 -3
  20. package/build/legacy/queryClient.js.map +1 -1
  21. package/build/legacy/types.cjs.map +1 -1
  22. package/build/legacy/types.js.map +1 -1
  23. package/build/modern/_tsup-dts-rollup.d.cts +5 -7
  24. package/build/modern/_tsup-dts-rollup.d.ts +5 -7
  25. package/build/modern/hydration.cjs +32 -6
  26. package/build/modern/hydration.cjs.map +1 -1
  27. package/build/modern/hydration.js +32 -6
  28. package/build/modern/hydration.js.map +1 -1
  29. package/build/modern/infiniteQueryObserver.cjs +3 -5
  30. package/build/modern/infiniteQueryObserver.cjs.map +1 -1
  31. package/build/modern/infiniteQueryObserver.js +4 -10
  32. package/build/modern/infiniteQueryObserver.js.map +1 -1
  33. package/build/modern/query.cjs +14 -3
  34. package/build/modern/query.cjs.map +1 -1
  35. package/build/modern/query.d.cts +0 -1
  36. package/build/modern/query.d.ts +0 -1
  37. package/build/modern/query.js +14 -3
  38. package/build/modern/query.js.map +1 -1
  39. package/build/modern/queryClient.cjs +2 -3
  40. package/build/modern/queryClient.cjs.map +1 -1
  41. package/build/modern/queryClient.js +2 -3
  42. package/build/modern/queryClient.js.map +1 -1
  43. package/build/modern/types.cjs.map +1 -1
  44. package/build/modern/types.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/hydration.ts +35 -6
  47. package/src/infiniteQueryObserver.ts +4 -10
  48. package/src/query.ts +19 -11
  49. package/src/queryClient.ts +2 -13
  50. package/src/types.ts +2 -5
package/src/hydration.ts CHANGED
@@ -48,6 +48,7 @@ interface DehydratedQuery {
48
48
  state: QueryState
49
49
  promise?: Promise<unknown>
50
50
  meta?: QueryMeta
51
+ queryType?: 'infinite'
51
52
  // This is only optional because older versions of Query might have dehydrated
52
53
  // without it which we need to handle for backwards compatibility.
53
54
  // This should be changed to required in the future.
@@ -117,6 +118,7 @@ function dehydrateQuery(
117
118
  promise: dehydratePromise(),
118
119
  }),
119
120
  ...(query.meta && { meta: query.meta }),
121
+ ...(query.queryType && { queryType: query.queryType }),
120
122
  }
121
123
  }
122
124
 
@@ -209,7 +211,15 @@ export function hydrate(
209
211
  })
210
212
 
211
213
  queries.forEach(
212
- ({ queryKey, state, queryHash, meta, promise, dehydratedAt }) => {
214
+ ({
215
+ queryKey,
216
+ state,
217
+ queryHash,
218
+ meta,
219
+ promise,
220
+ dehydratedAt,
221
+ queryType,
222
+ }) => {
213
223
  const syncData = promise ? tryResolveSync(promise) : undefined
214
224
  const rawData = state.data === undefined ? syncData?.data : state.data
215
225
  const data = rawData === undefined ? rawData : deserializeData(rawData)
@@ -230,12 +240,24 @@ export function hydrate(
230
240
  state.dataUpdatedAt > query.state.dataUpdatedAt ||
231
241
  hasNewerSyncData
232
242
  ) {
233
- // omit fetchStatus from dehydrated state
234
- // so that query stays in its current fetchStatus
243
+ // Omit fetchStatus from dehydrated state so that query stays in its current fetchStatus
235
244
  const { fetchStatus: _ignored, ...serializedState } = state
236
245
  query.setState({
237
246
  ...serializedState,
238
247
  data,
248
+ // If the query was pending at the moment of dehydration, but resolved to have data
249
+ // before hydration, we can assume the query should be hydrated as successful.
250
+ //
251
+ // Since you can opt into dehydrating failed queries, and those can have data from
252
+ // previous successful fetches, we make sure we only do this for pending queries.
253
+ ...(state.status === 'pending' &&
254
+ data !== undefined && {
255
+ status: 'success' as const,
256
+ // Preserve existing fetchStatus if the existing query is actively fetching.
257
+ ...(!existingQueryIsFetching && {
258
+ fetchStatus: 'idle' as const,
259
+ }),
260
+ }),
239
261
  })
240
262
  }
241
263
  } else {
@@ -248,6 +270,7 @@ export function hydrate(
248
270
  queryKey,
249
271
  queryHash,
250
272
  meta,
273
+ _type: queryType,
251
274
  },
252
275
  // Reset fetch status to idle to avoid
253
276
  // query being stuck in fetching state upon hydration
@@ -255,13 +278,21 @@ export function hydrate(
255
278
  ...state,
256
279
  data,
257
280
  fetchStatus: 'idle',
258
- status: data !== undefined ? 'success' : state.status,
281
+ // Like above, if the query was pending at the moment of dehydration but has data,
282
+ // we can assume it should be hydrated as successful.
283
+ status:
284
+ state.status === 'pending' && data !== undefined
285
+ ? 'success'
286
+ : state.status,
259
287
  },
260
288
  )
261
289
  }
262
290
 
263
291
  if (
264
292
  promise &&
293
+ // If the data was synchronously available, there is no need to set up
294
+ // a retryer and thus no reason to call fetch
295
+ !syncData &&
265
296
  !existingQueryIsPending &&
266
297
  !existingQueryIsFetching &&
267
298
  // Only hydrate if dehydration is newer than any existing data,
@@ -270,8 +301,6 @@ export function hydrate(
270
301
  ) {
271
302
  // This doesn't actually fetch - it just creates a retryer
272
303
  // which will re-use the passed `initialPromise`
273
- // Note that we need to call these even when data was synchronously
274
- // available, as we still need to set up the retryer
275
304
  query
276
305
  .fetch(undefined, {
277
306
  // RSC transformed promises are not thenable
@@ -1,9 +1,5 @@
1
1
  import { QueryObserver } from './queryObserver'
2
- import {
3
- hasNextPage,
4
- hasPreviousPage,
5
- infiniteQueryBehavior,
6
- } from './infiniteQueryBehavior'
2
+ import { hasNextPage, hasPreviousPage } from './infiniteQueryBehavior'
7
3
  import type { Subscribable } from './subscribable'
8
4
  import type {
9
5
  DefaultError,
@@ -93,10 +89,8 @@ export class InfiniteQueryObserver<
93
89
  TPageParam
94
90
  >,
95
91
  ): void {
96
- super.setOptions({
97
- ...options,
98
- behavior: infiniteQueryBehavior(),
99
- })
92
+ options._type = 'infinite'
93
+ super.setOptions(options)
100
94
  }
101
95
 
102
96
  getOptimisticResult(
@@ -108,7 +102,7 @@ export class InfiniteQueryObserver<
108
102
  TPageParam
109
103
  >,
110
104
  ): InfiniteQueryObserverResult<TData, TError> {
111
- options.behavior = infiniteQueryBehavior()
105
+ options._type = 'infinite'
112
106
  return super.getOptimisticResult(options) as InfiniteQueryObserverResult<
113
107
  TData,
114
108
  TError
package/src/query.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  import { notifyManager } from './notifyManager'
11
11
  import { CancelledError, canFetch, createRetryer } from './retryer'
12
12
  import { Removable } from './removable'
13
+ import { infiniteQueryBehavior } from './infiniteQueryBehavior'
13
14
  import type { QueryCache } from './queryCache'
14
15
  import type { QueryClient } from './queryClient'
15
16
  import type {
@@ -137,7 +138,6 @@ interface ContinueAction {
137
138
  interface SetStateAction<TData, TError> {
138
139
  type: 'setState'
139
140
  state: Partial<QueryState<TData, TError>>
140
- setStateOptions?: SetStateOptions
141
141
  }
142
142
 
143
143
  export type Action<TData, TError> =
@@ -150,10 +150,6 @@ export type Action<TData, TError> =
150
150
  | SetStateAction<TData, TError>
151
151
  | SuccessAction<TData>
152
152
 
153
- export interface SetStateOptions {
154
- meta?: any
155
- }
156
-
157
153
  // CLASS
158
154
 
159
155
  export class Query<
@@ -166,6 +162,7 @@ export class Query<
166
162
  queryHash: string
167
163
  options!: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
168
164
  state: QueryState<TData, TError>
165
+ #queryType?: 'infinite'
169
166
 
170
167
  #initialState: QueryState<TData, TError>
171
168
  #revertState?: QueryState<TData, TError>
@@ -195,6 +192,10 @@ export class Query<
195
192
  return this.options.meta
196
193
  }
197
194
 
195
+ get queryType() {
196
+ return this.#queryType
197
+ }
198
+
198
199
  get promise(): Promise<TData> | undefined {
199
200
  return this.#retryer?.promise
200
201
  }
@@ -204,6 +205,10 @@ export class Query<
204
205
  ): void {
205
206
  this.options = { ...this.#defaultOptions, ...options }
206
207
 
208
+ if (options?._type) {
209
+ this.#queryType = options._type
210
+ }
211
+
207
212
  this.updateGcTime(this.options.gcTime)
208
213
 
209
214
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -241,11 +246,8 @@ export class Query<
241
246
  return data
242
247
  }
243
248
 
244
- setState(
245
- state: Partial<QueryState<TData, TError>>,
246
- setStateOptions?: SetStateOptions,
247
- ): void {
248
- this.#dispatch({ type: 'setState', state, setStateOptions })
249
+ setState(state: Partial<QueryState<TData, TError>>): void {
250
+ this.#dispatch({ type: 'setState', state })
249
251
  }
250
252
 
251
253
  cancel(options?: CancelOptions): Promise<void> {
@@ -511,7 +513,13 @@ export class Query<
511
513
 
512
514
  const context = createFetchContext()
513
515
 
514
- this.options.behavior?.onFetch(context, this as unknown as Query)
516
+ const behavior =
517
+ this.#queryType === 'infinite'
518
+ ? (infiniteQueryBehavior(
519
+ (this.options as { pages?: number }).pages,
520
+ ) as QueryBehavior<TQueryFnData, TError, TData, TQueryKey>)
521
+ : this.options.behavior
522
+ behavior?.onFetch(context, this as unknown as Query)
515
523
 
516
524
  // Store state in case the current fetch needs to be reverted
517
525
  this.#revertState = this.state
@@ -12,7 +12,6 @@ import { MutationCache } from './mutationCache'
12
12
  import { focusManager } from './focusManager'
13
13
  import { onlineManager } from './onlineManager'
14
14
  import { notifyManager } from './notifyManager'
15
- import { infiniteQueryBehavior } from './infiniteQueryBehavior'
16
15
  import type {
17
16
  CancelOptions,
18
17
  DefaultError,
@@ -395,12 +394,7 @@ export class QueryClient {
395
394
  TPageParam
396
395
  >,
397
396
  ): Promise<InfiniteData<TData, TPageParam>> {
398
- options.behavior = infiniteQueryBehavior<
399
- TQueryFnData,
400
- TError,
401
- TData,
402
- TPageParam
403
- >(options.pages)
397
+ options._type = 'infinite'
404
398
  return this.fetchQuery(options as any)
405
399
  }
406
400
 
@@ -437,12 +431,7 @@ export class QueryClient {
437
431
  TPageParam
438
432
  >,
439
433
  ): Promise<InfiniteData<TData, TPageParam>> {
440
- options.behavior = infiniteQueryBehavior<
441
- TQueryFnData,
442
- TError,
443
- TData,
444
- TPageParam
445
- >(options.pages)
434
+ options._type = 'infinite'
446
435
 
447
436
  return this.ensureQueryData(options as any)
448
437
  }
package/src/types.ts CHANGED
@@ -246,11 +246,7 @@ export interface QueryOptions<
246
246
  */
247
247
  gcTime?: number
248
248
  queryFn?: QueryFunction<TQueryFnData, TQueryKey, TPageParam> | SkipToken
249
- persister?: QueryPersister<
250
- NoInfer<TQueryFnData>,
251
- NoInfer<TQueryKey>,
252
- NoInfer<TPageParam>
253
- >
249
+ persister?: QueryPersister<TQueryFnData, TQueryKey, TPageParam>
254
250
  queryHash?: string
255
251
  queryKey?: TQueryKey
256
252
  queryKeyHashFn?: QueryKeyHashFunction<TQueryKey>
@@ -266,6 +262,7 @@ export interface QueryOptions<
266
262
  | boolean
267
263
  | ((oldData: unknown | undefined, newData: unknown) => unknown)
268
264
  _defaulted?: boolean
265
+ _type?: 'infinite'
269
266
  /**
270
267
  * Additional payload to be stored on each query.
271
268
  * Use this property to pass information that can be used in other places.