@tanstack/query-core 4.24.9 → 4.25.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/query-core",
3
- "version": "4.24.9",
3
+ "version": "4.25.0",
4
4
  "description": "The framework agnostic core that powers TanStack Query",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
package/src/hydration.ts CHANGED
@@ -142,10 +142,17 @@ export function hydrate(
142
142
  queries.forEach((dehydratedQuery) => {
143
143
  const query = queryCache.get(dehydratedQuery.queryHash)
144
144
 
145
+ // Reset fetch status to idle in the dehydrated state to avoid
146
+ // query being stuck in fetching state upon hydration
147
+ const dehydratedQueryState = {
148
+ ...dehydratedQuery.state,
149
+ fetchStatus: 'idle' as const,
150
+ }
151
+
145
152
  // Do not hydrate if an existing query exists with newer data
146
153
  if (query) {
147
- if (query.state.dataUpdatedAt < dehydratedQuery.state.dataUpdatedAt) {
148
- query.setState(dehydratedQuery.state)
154
+ if (query.state.dataUpdatedAt < dehydratedQueryState.dataUpdatedAt) {
155
+ query.setState(dehydratedQueryState)
149
156
  }
150
157
  return
151
158
  }
@@ -158,7 +165,7 @@ export function hydrate(
158
165
  queryKey: dehydratedQuery.queryKey,
159
166
  queryHash: dehydratedQuery.queryHash,
160
167
  },
161
- dehydratedQuery.state,
168
+ dehydratedQueryState,
162
169
  )
163
170
  })
164
171
  }
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export {
16
16
  replaceEqualDeep,
17
17
  isError,
18
18
  isServer,
19
+ matchQuery,
19
20
  parseQueryArgs,
20
21
  parseFilterArgs,
21
22
  parseMutationFilterArgs,
@@ -426,4 +426,44 @@ describe('dehydration and rehydration', () => {
426
426
 
427
427
  queryClient.clear()
428
428
  })
429
+
430
+ test('should set the fetchStatus to idle in all cases when dehydrating', async () => {
431
+ const queryCache = new QueryCache()
432
+ const queryClient = createQueryClient({ queryCache })
433
+
434
+ let isInitialFetch = true
435
+ let resolvePromise: (value: unknown) => void = () => undefined
436
+
437
+ const customFetchData = () => {
438
+ const promise = new Promise((resolve) => {
439
+ resolvePromise = resolve
440
+ })
441
+ // Resolve the promise in initial fetch
442
+ // because we are awaiting the query first time
443
+ if (isInitialFetch) {
444
+ resolvePromise('string')
445
+ }
446
+ isInitialFetch = false
447
+ return promise
448
+ }
449
+
450
+ await queryClient.prefetchQuery(['string'], () => customFetchData())
451
+
452
+ queryClient.refetchQueries(['string'])
453
+
454
+ const dehydrated = dehydrate(queryClient)
455
+ resolvePromise('string')
456
+ expect(
457
+ dehydrated.queries.find((q) => q.queryHash === '["string"]')?.state
458
+ .fetchStatus,
459
+ ).toBe('fetching')
460
+ const stringified = JSON.stringify(dehydrated)
461
+
462
+ // ---
463
+ const parsed = JSON.parse(stringified)
464
+ const hydrationCache = new QueryCache()
465
+ const hydrationClient = createQueryClient({ queryCache: hydrationCache })
466
+ hydrate(hydrationClient, parsed)
467
+ expect(hydrationCache.find(['string'])?.state.fetchStatus).toBe('idle')
468
+ })
429
469
  })