From 1839e6335205bf2e857b77973bd2904abf81c4b9 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 13:49:25 +0200 Subject: [PATCH 01/11] add test --- .../src/__tests__/hydration.test.tsx | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index 5582e9da16..1581bbaaf2 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -5,6 +5,8 @@ import { QueryCache } from '../queryCache' import { dehydrate, hydrate } from '../hydration' import { MutationCache } from '../mutationCache' import { executeMutation, mockOnlineManagerIsOnline } from './utils' +import superjson from 'superjson' +import assert from 'assert' describe('dehydration and rehydration', () => { beforeEach(() => { @@ -40,6 +42,7 @@ describe('dehydration and rehydration', () => { await vi.waitFor(() => queryClient.prefetchQuery({ queryKey: ['null'], + queryFn: () => sleep(0).then(() => null), }), ) @@ -1402,4 +1405,53 @@ describe('dehydration and rehydration', () => { clientQueryClient.clear() serverQueryClient.clear() }) + + // https://github.com/TanStack/query/issues/6802 + test('should serialize and deserialize query keys', async () => { + const createQueryClient = () => + new QueryClient({ + defaultOptions: { + dehydrate: { + serializeData: superjson.serialize, + }, + hydrate: { + deserializeData: superjson.deserialize, + }, + }, + }) + + const getFirstEntry = (client: QueryClient) => { + const [entry] = client.getQueryCache().getAll() + assert(entry, 'cache should not be empty') + return entry + } + + const serverClient = createQueryClient() + + const date = new Date('2024-01-01T00:00:00.000Z') + + serverClient.setQueryData(['date', date], { + date, + }) + + const serverEntry = getFirstEntry(serverClient) + + // use JSON.parse(JSON.stringify()) to mock a http roundtrip + const dehydrated = JSON.parse(JSON.stringify(dehydrate(serverClient))) + + const frontendClient = createQueryClient() + + hydrate(frontendClient, dehydrated) + + const clientEntry = getFirstEntry(frontendClient) + + + + expect(clientEntry).toMatchObject(serverEntry) + + + expect(clientEntry.queryKey).toEqual(serverEntry.queryKey) + expect(clientEntry.queryHash).toEqual(serverEntry.queryHash) + + }) }) From b02a871c2588425a08729859e6b3ddfcaf98dda4 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 13:51:15 +0200 Subject: [PATCH 02/11] meep --- packages/query-core/package.json | 3 ++- packages/query-core/src/__tests__/hydration.test.tsx | 5 ----- packages/query-core/src/hydration.ts | 9 ++++++--- pnpm-lock.yaml | 4 ++++ 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/query-core/package.json b/packages/query-core/package.json index 0a588ee9ac..30d9ccf7e7 100644 --- a/packages/query-core/package.json +++ b/packages/query-core/package.json @@ -60,6 +60,7 @@ ], "devDependencies": { "@tanstack/query-test-utils": "workspace:*", - "npm-run-all2": "^5.0.0" + "npm-run-all2": "^5.0.0", + "superjson": "^2.2.1" } } diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index 1581bbaaf2..f97c3f02a0 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -1406,7 +1406,6 @@ describe('dehydration and rehydration', () => { serverQueryClient.clear() }) - // https://github.com/TanStack/query/issues/6802 test('should serialize and deserialize query keys', async () => { const createQueryClient = () => new QueryClient({ @@ -1444,14 +1443,10 @@ describe('dehydration and rehydration', () => { hydrate(frontendClient, dehydrated) const clientEntry = getFirstEntry(frontendClient) - - expect(clientEntry).toMatchObject(serverEntry) - expect(clientEntry.queryKey).toEqual(serverEntry.queryKey) expect(clientEntry.queryHash).toEqual(serverEntry.queryHash) - }) }) diff --git a/packages/query-core/src/hydration.ts b/packages/query-core/src/hydration.ts index 1361036d86..2bba1bd9a7 100644 --- a/packages/query-core/src/hydration.ts +++ b/packages/query-core/src/hydration.ts @@ -86,7 +86,7 @@ function dehydrateQuery( data: serializeData(query.state.data), }), }, - queryKey: query.queryKey, + queryKey: serializeData(query.queryKey), queryHash: query.queryHash, ...(query.state.status === 'pending' && { promise: query.promise?.then(serializeData).catch((error) => { @@ -196,10 +196,13 @@ export function hydrate( }) queries.forEach( - ({ queryKey, state, queryHash, meta, promise, dehydratedAt }) => { + (nextQuery) => { + const { state, queryHash, meta, promise, dehydratedAt } = nextQuery + const syncData = promise ? tryResolveSync(promise) : undefined const rawData = state.data === undefined ? syncData?.data : state.data const data = rawData === undefined ? rawData : deserializeData(rawData) + const newQueryKey = deserializeData(nextQuery.queryKey) let query = queryCache.get(queryHash) const existingQueryIsPending = query?.state.status === 'pending' @@ -232,7 +235,7 @@ export function hydrate( { ...client.getDefaultOptions().hydrate?.queries, ...options?.defaultOptions?.queries, - queryKey, + queryKey: newQueryKey, queryHash, meta, }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 839f124ba0..0f6a497ed5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2452,6 +2452,9 @@ importers: npm-run-all2: specifier: ^5.0.0 version: 5.0.2 + superjson: + specifier: ^2.2.1 + version: 2.2.1 packages/query-devtools: devDependencies: @@ -7831,6 +7834,7 @@ packages: '@vercel/edge@1.2.1': resolution: {integrity: sha512-1++yncEyIAi68D3UEOlytYb1IUcIulMWdoSzX2h9LuSeeyR7JtaIgR8DcTQ6+DmYOQn+5MCh6LY+UmK6QBByNA==} + deprecated: This package is deprecated. You should to use `@vercel/functions` instead. '@vercel/nft@0.29.2': resolution: {integrity: sha512-A/Si4mrTkQqJ6EXJKv5EYCDQ3NL6nJXxG8VGXePsaiQigsomHYQC9xSpX8qGk7AEZk4b1ssbYIqJ0ISQQ7bfcA==} From 76b1375d04ad96062d2e4f085e407765cd155f01 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 13:56:29 +0200 Subject: [PATCH 03/11] tweak --- packages/query-core/src/hydration.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/query-core/src/hydration.ts b/packages/query-core/src/hydration.ts index 2bba1bd9a7..d81565f8d2 100644 --- a/packages/query-core/src/hydration.ts +++ b/packages/query-core/src/hydration.ts @@ -202,7 +202,7 @@ export function hydrate( const syncData = promise ? tryResolveSync(promise) : undefined const rawData = state.data === undefined ? syncData?.data : state.data const data = rawData === undefined ? rawData : deserializeData(rawData) - const newQueryKey = deserializeData(nextQuery.queryKey) + const queryKey = deserializeData(nextQuery.queryKey) let query = queryCache.get(queryHash) const existingQueryIsPending = query?.state.status === 'pending' @@ -235,7 +235,7 @@ export function hydrate( { ...client.getDefaultOptions().hydrate?.queries, ...options?.defaultOptions?.queries, - queryKey: newQueryKey, + queryKey: queryKey, queryHash, meta, }, From af0efb275d52824dc1fa611a1b6ad87c753d862f Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 13:57:25 +0200 Subject: [PATCH 04/11] tweak --- packages/query-core/src/hydration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/query-core/src/hydration.ts b/packages/query-core/src/hydration.ts index d81565f8d2..e881d6c8c1 100644 --- a/packages/query-core/src/hydration.ts +++ b/packages/query-core/src/hydration.ts @@ -235,7 +235,7 @@ export function hydrate( { ...client.getDefaultOptions().hydrate?.queries, ...options?.defaultOptions?.queries, - queryKey: queryKey, + queryKey, queryHash, meta, }, From 448de0264ede5cd16a145940481bc78e3f558c7c Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:58:50 +0000 Subject: [PATCH 05/11] ci: apply automated fixes --- packages/query-core/src/hydration.ts | 133 +++++++++++++-------------- 1 file changed, 64 insertions(+), 69 deletions(-) diff --git a/packages/query-core/src/hydration.ts b/packages/query-core/src/hydration.ts index e881d6c8c1..2ad2d22e1f 100644 --- a/packages/query-core/src/hydration.ts +++ b/packages/query-core/src/hydration.ts @@ -195,78 +195,73 @@ export function hydrate( ) }) - queries.forEach( - (nextQuery) => { - const { state, queryHash, meta, promise, dehydratedAt } = nextQuery - - const syncData = promise ? tryResolveSync(promise) : undefined - const rawData = state.data === undefined ? syncData?.data : state.data - const data = rawData === undefined ? rawData : deserializeData(rawData) - const queryKey = deserializeData(nextQuery.queryKey) + queries.forEach((nextQuery) => { + const { state, queryHash, meta, promise, dehydratedAt } = nextQuery - let query = queryCache.get(queryHash) - const existingQueryIsPending = query?.state.status === 'pending' - const existingQueryIsFetching = query?.state.fetchStatus === 'fetching' + const syncData = promise ? tryResolveSync(promise) : undefined + const rawData = state.data === undefined ? syncData?.data : state.data + const data = rawData === undefined ? rawData : deserializeData(rawData) + const queryKey = deserializeData(nextQuery.queryKey) - // Do not hydrate if an existing query exists with newer data - if (query) { - const hasNewerSyncData = - syncData && - // We only need this undefined check to handle older dehydration - // payloads that might not have dehydratedAt - dehydratedAt !== undefined && - dehydratedAt > query.state.dataUpdatedAt - if ( - state.dataUpdatedAt > query.state.dataUpdatedAt || - hasNewerSyncData - ) { - // omit fetchStatus from dehydrated state - // so that query stays in its current fetchStatus - const { fetchStatus: _ignored, ...serializedState } = state - query.setState({ - ...serializedState, - data, - }) - } - } else { - // Restore query - query = queryCache.build( - client, - { - ...client.getDefaultOptions().hydrate?.queries, - ...options?.defaultOptions?.queries, - queryKey, - queryHash, - meta, - }, - // Reset fetch status to idle to avoid - // query being stuck in fetching state upon hydration - { - ...state, - data, - fetchStatus: 'idle', - status: data !== undefined ? 'success' : state.status, - }, - ) - } + let query = queryCache.get(queryHash) + const existingQueryIsPending = query?.state.status === 'pending' + const existingQueryIsFetching = query?.state.fetchStatus === 'fetching' - if ( - promise && - !existingQueryIsPending && - !existingQueryIsFetching && - // Only hydrate if dehydration is newer than any existing data, - // this is always true for new queries - (dehydratedAt === undefined || dehydratedAt > query.state.dataUpdatedAt) - ) { - // This doesn't actually fetch - it just creates a retryer - // which will re-use the passed `initialPromise` - // Note that we need to call these even when data was synchronously - // available, as we still need to set up the retryer - void query.fetch(undefined, { - // RSC transformed promises are not thenable - initialPromise: Promise.resolve(promise).then(deserializeData), + // Do not hydrate if an existing query exists with newer data + if (query) { + const hasNewerSyncData = + syncData && + // We only need this undefined check to handle older dehydration + // payloads that might not have dehydratedAt + dehydratedAt !== undefined && + dehydratedAt > query.state.dataUpdatedAt + if (state.dataUpdatedAt > query.state.dataUpdatedAt || hasNewerSyncData) { + // omit fetchStatus from dehydrated state + // so that query stays in its current fetchStatus + const { fetchStatus: _ignored, ...serializedState } = state + query.setState({ + ...serializedState, + data, }) } - }, - ) + } else { + // Restore query + query = queryCache.build( + client, + { + ...client.getDefaultOptions().hydrate?.queries, + ...options?.defaultOptions?.queries, + queryKey, + queryHash, + meta, + }, + // Reset fetch status to idle to avoid + // query being stuck in fetching state upon hydration + { + ...state, + data, + fetchStatus: 'idle', + status: data !== undefined ? 'success' : state.status, + }, + ) + } + + if ( + promise && + !existingQueryIsPending && + !existingQueryIsFetching && + // Only hydrate if dehydration is newer than any existing data, + // this is always true for new queries + (dehydratedAt === undefined || dehydratedAt > query.state.dataUpdatedAt) + ) { + // This doesn't actually fetch - it just creates a retryer + // which will re-use the passed `initialPromise` + // Note that we need to call these even when data was synchronously + // available, as we still need to set up the retryer + void query.fetch(undefined, { + // RSC transformed promises are not thenable + initialPromise: Promise.resolve(promise).then(deserializeData), + }) + } + }) } From 01c17fa6bec97a59139a6ddaac362c42ce5f3737 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 13:58:47 +0200 Subject: [PATCH 06/11] fmt --- packages/query-core/src/__tests__/hydration.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index f97c3f02a0..77727ae1e0 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -1444,9 +1444,9 @@ describe('dehydration and rehydration', () => { const clientEntry = getFirstEntry(frontendClient) - expect(clientEntry).toMatchObject(serverEntry) - expect(clientEntry.queryKey).toEqual(serverEntry.queryKey) expect(clientEntry.queryHash).toEqual(serverEntry.queryHash) + + expect(clientEntry).toMatchObject(serverEntry) }) }) From ec4b11a81d1885f5bc83d4a59e1e7b4866bb9fe0 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 14:25:28 +0200 Subject: [PATCH 07/11] lint --- packages/query-core/src/__tests__/hydration.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index 77727ae1e0..3d2b12854e 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -1,12 +1,12 @@ +import assert from 'node:assert' import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { sleep } from '@tanstack/query-test-utils' +import superjson from 'superjson' import { QueryClient } from '../queryClient' import { QueryCache } from '../queryCache' import { dehydrate, hydrate } from '../hydration' import { MutationCache } from '../mutationCache' import { executeMutation, mockOnlineManagerIsOnline } from './utils' -import superjson from 'superjson' -import assert from 'assert' describe('dehydration and rehydration', () => { beforeEach(() => { @@ -1406,7 +1406,7 @@ describe('dehydration and rehydration', () => { serverQueryClient.clear() }) - test('should serialize and deserialize query keys', async () => { + test('should serialize and deserialize query keys', () => { const createQueryClient = () => new QueryClient({ defaultOptions: { From 99bdd0bdda98e36c0717a48e38da4980b54577fd Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 14:32:04 +0200 Subject: [PATCH 08/11] mkay --- .../src/__tests__/hydration.test.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index 3d2b12854e..ccc77bc9eb 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -973,7 +973,7 @@ describe('dehydration and rehydration', () => { defaultOptions: { dehydrate: { shouldDehydrateQuery: () => true, - serializeData: (data) => data.toISOString(), + serializeData: superjson.serialize, }, }, }) @@ -988,7 +988,7 @@ describe('dehydration and rehydration', () => { const hydrationClient = new QueryClient({ defaultOptions: { hydrate: { - deserializeData: (data) => new Date(data), + deserializeData: superjson.deserialize, }, }, }) @@ -1009,7 +1009,7 @@ describe('dehydration and rehydration', () => { defaultOptions: { dehydrate: { shouldDehydrateQuery: () => true, - serializeData: (data) => data.toISOString(), + serializeData: superjson.serialize, }, }, }) @@ -1024,7 +1024,7 @@ describe('dehydration and rehydration', () => { const hydrationClient = new QueryClient({ defaultOptions: { hydrate: { - deserializeData: (data) => new Date(data), + deserializeData: superjson.deserialize, }, }, }) @@ -1044,7 +1044,7 @@ describe('dehydration and rehydration', () => { const hydrationClient = new QueryClient({ defaultOptions: { hydrate: { - deserializeData: (data) => new Date(data), + deserializeData: superjson.deserialize, }, }, }) @@ -1062,7 +1062,7 @@ describe('dehydration and rehydration', () => { defaultOptions: { dehydrate: { shouldDehydrateQuery: () => true, - serializeData: (data) => data.toISOString(), + serializeData: superjson.serialize, }, }, }) @@ -1223,10 +1223,10 @@ describe('dehydration and rehydration', () => { expect(clientQueryClient.getQueryData(query.queryKey)).toBe(0), ) - expect(serializeDataMock).toHaveBeenCalledTimes(1) + expect(serializeDataMock).toHaveBeenCalledTimes(2) // once for data, once for queryKey expect(serializeDataMock).toHaveBeenCalledWith(0) - expect(deserializeDataMock).toHaveBeenCalledTimes(1) + expect(deserializeDataMock).toHaveBeenCalledTimes(2) // once for data, once for queryKey expect(deserializeDataMock).toHaveBeenCalledWith(0) // --- server --- @@ -1245,10 +1245,10 @@ describe('dehydration and rehydration', () => { expect(clientQueryClient.getQueryData(query.queryKey)).toBe(1), ) - expect(serializeDataMock).toHaveBeenCalledTimes(2) + expect(serializeDataMock).toHaveBeenCalledTimes(4) // twice for data, twice for queryKey expect(serializeDataMock).toHaveBeenCalledWith(1) - expect(deserializeDataMock).toHaveBeenCalledTimes(2) + expect(deserializeDataMock).toHaveBeenCalledTimes(4) // twice for data, twice for queryKey expect(deserializeDataMock).toHaveBeenCalledWith(1) clientQueryClient.clear() From 561ad589487bfa8bbf77e00eb6f4f9196b4a2d91 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Tue, 24 Jun 2025 14:33:34 +0200 Subject: [PATCH 09/11] rm --- .../src/__tests__/hydration.test.tsx | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index ccc77bc9eb..fee4d89629 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -1180,8 +1180,6 @@ describe('dehydration and rehydration', () => { }) test('should overwrite data when a new promise is streamed in', async () => { - const serializeDataMock = vi.fn((data: any) => data) - const deserializeDataMock = vi.fn((data: any) => data) const countRef = { current: 0 } // --- server --- @@ -1189,7 +1187,6 @@ describe('dehydration and rehydration', () => { defaultOptions: { dehydrate: { shouldDehydrateQuery: () => true, - serializeData: serializeDataMock, }, }, }) @@ -1208,13 +1205,7 @@ describe('dehydration and rehydration', () => { // --- client --- - const clientQueryClient = new QueryClient({ - defaultOptions: { - hydrate: { - deserializeData: deserializeDataMock, - }, - }, - }) + const clientQueryClient = new QueryClient() hydrate(clientQueryClient, dehydrated) @@ -1223,12 +1214,6 @@ describe('dehydration and rehydration', () => { expect(clientQueryClient.getQueryData(query.queryKey)).toBe(0), ) - expect(serializeDataMock).toHaveBeenCalledTimes(2) // once for data, once for queryKey - expect(serializeDataMock).toHaveBeenCalledWith(0) - - expect(deserializeDataMock).toHaveBeenCalledTimes(2) // once for data, once for queryKey - expect(deserializeDataMock).toHaveBeenCalledWith(0) - // --- server --- countRef.current++ serverQueryClient.clear() @@ -1245,11 +1230,6 @@ describe('dehydration and rehydration', () => { expect(clientQueryClient.getQueryData(query.queryKey)).toBe(1), ) - expect(serializeDataMock).toHaveBeenCalledTimes(4) // twice for data, twice for queryKey - expect(serializeDataMock).toHaveBeenCalledWith(1) - - expect(deserializeDataMock).toHaveBeenCalledTimes(4) // twice for data, twice for queryKey - expect(deserializeDataMock).toHaveBeenCalledWith(1) clientQueryClient.clear() serverQueryClient.clear() From 569d3a6020984553ce8a776b10b905cbf8156117 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:34:49 +0000 Subject: [PATCH 10/11] ci: apply automated fixes --- packages/query-core/src/__tests__/hydration.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index fee4d89629..7cb1d3ff9d 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -1180,7 +1180,6 @@ describe('dehydration and rehydration', () => { }) test('should overwrite data when a new promise is streamed in', async () => { - const countRef = { current: 0 } // --- server --- const serverQueryClient = new QueryClient({ @@ -1230,7 +1229,6 @@ describe('dehydration and rehydration', () => { expect(clientQueryClient.getQueryData(query.queryKey)).toBe(1), ) - clientQueryClient.clear() serverQueryClient.clear() }) From 73c4f1ad5f26b6f3a4f42222e0909e5d6b7601f9 Mon Sep 17 00:00:00 2001 From: Alexander Johansson Date: Wed, 25 Jun 2025 12:32:00 +0200 Subject: [PATCH 11/11] explicit --- .../query-core/src/__tests__/hydration.test.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index 7cb1d3ff9d..02f0683970 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -1,11 +1,11 @@ import assert from 'node:assert' -import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { sleep } from '@tanstack/query-test-utils' import superjson from 'superjson' -import { QueryClient } from '../queryClient' -import { QueryCache } from '../queryCache' +import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { dehydrate, hydrate } from '../hydration' import { MutationCache } from '../mutationCache' +import { QueryCache } from '../queryCache' +import { QueryClient } from '../queryClient' import { executeMutation, mockOnlineManagerIsOnline } from './utils' describe('dehydration and rehydration', () => { @@ -1405,10 +1405,11 @@ describe('dehydration and rehydration', () => { const serverClient = createQueryClient() - const date = new Date('2024-01-01T00:00:00.000Z') + // Make a query key that isn't plain javascript object + const queryKey = ['date', new Date('2024-01-01T00:00:00.000Z')] as const - serverClient.setQueryData(['date', date], { - date, + serverClient.setQueryData(queryKey, { + foo: 'bar', }) const serverEntry = getFirstEntry(serverClient) @@ -1422,6 +1423,7 @@ describe('dehydration and rehydration', () => { const clientEntry = getFirstEntry(frontendClient) + expect(clientEntry.queryKey).toEqual(queryKey) expect(clientEntry.queryKey).toEqual(serverEntry.queryKey) expect(clientEntry.queryHash).toEqual(serverEntry.queryHash)