-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
fix: serialize queryKey
#9308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: serialize queryKey
#9308
Changes from all commits
1839e63
b02a871
76b1375
af0efb2
448de02
01c17fa
ec4b11a
99bdd0b
561ad58
569d3a6
73c4f1a
fbd2888
4cb1669
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' | ||
import assert from 'node:assert' | ||
import { sleep } from '@tanstack/query-test-utils' | ||
import { QueryClient } from '../queryClient' | ||
import { QueryCache } from '../queryCache' | ||
import superjson from 'superjson' | ||
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', () => { | ||
|
@@ -40,6 +42,7 @@ describe('dehydration and rehydration', () => { | |
await vi.waitFor(() => | ||
queryClient.prefetchQuery({ | ||
queryKey: ['null'], | ||
|
||
queryFn: () => sleep(0).then(() => null), | ||
}), | ||
) | ||
|
@@ -970,7 +973,7 @@ describe('dehydration and rehydration', () => { | |
defaultOptions: { | ||
dehydrate: { | ||
shouldDehydrateQuery: () => true, | ||
serializeData: (data) => data.toISOString(), | ||
serializeData: superjson.serialize, | ||
}, | ||
}, | ||
}) | ||
|
@@ -985,7 +988,7 @@ describe('dehydration and rehydration', () => { | |
const hydrationClient = new QueryClient({ | ||
defaultOptions: { | ||
hydrate: { | ||
deserializeData: (data) => new Date(data), | ||
deserializeData: superjson.deserialize, | ||
}, | ||
}, | ||
}) | ||
|
@@ -1006,7 +1009,7 @@ describe('dehydration and rehydration', () => { | |
defaultOptions: { | ||
dehydrate: { | ||
shouldDehydrateQuery: () => true, | ||
serializeData: (data) => data.toISOString(), | ||
serializeData: superjson.serialize, | ||
}, | ||
}, | ||
}) | ||
|
@@ -1021,7 +1024,7 @@ describe('dehydration and rehydration', () => { | |
const hydrationClient = new QueryClient({ | ||
defaultOptions: { | ||
hydrate: { | ||
deserializeData: (data) => new Date(data), | ||
deserializeData: superjson.deserialize, | ||
}, | ||
}, | ||
}) | ||
|
@@ -1041,7 +1044,7 @@ describe('dehydration and rehydration', () => { | |
const hydrationClient = new QueryClient({ | ||
defaultOptions: { | ||
hydrate: { | ||
deserializeData: (data) => new Date(data), | ||
deserializeData: superjson.deserialize, | ||
}, | ||
}, | ||
}) | ||
|
@@ -1059,7 +1062,7 @@ describe('dehydration and rehydration', () => { | |
defaultOptions: { | ||
dehydrate: { | ||
shouldDehydrateQuery: () => true, | ||
serializeData: (data) => data.toISOString(), | ||
serializeData: superjson.serialize, | ||
}, | ||
}, | ||
}) | ||
|
@@ -1177,16 +1180,12 @@ 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 --- | ||
const serverQueryClient = new QueryClient({ | ||
defaultOptions: { | ||
dehydrate: { | ||
shouldDehydrateQuery: () => true, | ||
serializeData: serializeDataMock, | ||
}, | ||
}, | ||
}) | ||
|
@@ -1205,13 +1204,7 @@ describe('dehydration and rehydration', () => { | |
|
||
// --- client --- | ||
|
||
const clientQueryClient = new QueryClient({ | ||
defaultOptions: { | ||
hydrate: { | ||
deserializeData: deserializeDataMock, | ||
}, | ||
}, | ||
}) | ||
const clientQueryClient = new QueryClient() | ||
|
||
hydrate(clientQueryClient, dehydrated) | ||
|
||
|
@@ -1220,12 +1213,6 @@ describe('dehydration and rehydration', () => { | |
expect(clientQueryClient.getQueryData(query.queryKey)).toBe(0), | ||
) | ||
|
||
expect(serializeDataMock).toHaveBeenCalledTimes(1) | ||
expect(serializeDataMock).toHaveBeenCalledWith(0) | ||
|
||
expect(deserializeDataMock).toHaveBeenCalledTimes(1) | ||
expect(deserializeDataMock).toHaveBeenCalledWith(0) | ||
|
||
// --- server --- | ||
Comment on lines
-1223
to
-1228
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed these as the test isn't about whether if serialization is about and the amount of times the mock gets called doubled so it gets a bit weird and unintuitive anyway |
||
countRef.current++ | ||
serverQueryClient.clear() | ||
|
@@ -1242,12 +1229,6 @@ describe('dehydration and rehydration', () => { | |
expect(clientQueryClient.getQueryData(query.queryKey)).toBe(1), | ||
) | ||
|
||
expect(serializeDataMock).toHaveBeenCalledTimes(2) | ||
expect(serializeDataMock).toHaveBeenCalledWith(1) | ||
|
||
expect(deserializeDataMock).toHaveBeenCalledTimes(2) | ||
expect(deserializeDataMock).toHaveBeenCalledWith(1) | ||
|
||
clientQueryClient.clear() | ||
serverQueryClient.clear() | ||
}) | ||
|
@@ -1402,4 +1383,50 @@ describe('dehydration and rehydration', () => { | |
clientQueryClient.clear() | ||
serverQueryClient.clear() | ||
}) | ||
|
||
test('should serialize and deserialize query keys', () => { | ||
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() | ||
|
||
// 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(queryKey, { | ||
foo: 'bar', | ||
}) | ||
|
||
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.queryKey).toEqual(queryKey) | ||
expect(clientEntry.queryKey).toEqual(serverEntry.queryKey) | ||
expect(clientEntry.queryHash).toEqual(serverEntry.queryHash) | ||
|
||
expect(clientEntry).toMatchObject(serverEntry) | ||
}) | ||
}) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this come from
vitest
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's please hold off merging this until I'm back from vacation. Not sure if this is the right fix