Skip to content

Commit 489ed26

Browse files
authored
Reproduce early cache eviction with unit test (#908)
1 parent c8a2c16 commit 489ed26

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

packages/query-db-collection/tests/query.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4291,6 +4291,87 @@ describe(`QueryCollection`, () => {
42914291
await query2.cleanup()
42924292
customQueryClient.clear()
42934293
})
4294+
4295+
it(`should not immediately remove query data from cache when live query is GCed (respects gcTime)`, async () => {
4296+
// Create a QueryClient with a longer cacheTime to test that data should persist
4297+
const testQueryClient = new QueryClient({
4298+
defaultOptions: {
4299+
queries: {
4300+
staleTime: 0,
4301+
gcTime: 300,
4302+
retry: false,
4303+
},
4304+
},
4305+
})
4306+
4307+
const queryKey = [`premature-gc-test`]
4308+
const items: Array<TestItem> = [
4309+
{ id: `1`, name: `Item 1` },
4310+
{ id: `2`, name: `Item 2` },
4311+
]
4312+
4313+
const queryFn = vi.fn().mockResolvedValue(items)
4314+
4315+
// Use on-demand mode so the query is only created when the live query needs it
4316+
// This ensures the subscription is passed when the query is created
4317+
const config: QueryCollectionConfig<TestItem> = {
4318+
id: `premature-gc-test`,
4319+
queryClient: testQueryClient,
4320+
queryKey,
4321+
queryFn,
4322+
getKey,
4323+
syncMode: `on-demand`, // Use on-demand mode so query is created with subscription
4324+
}
4325+
4326+
const options = queryCollectionOptions(config)
4327+
const collection = createCollection(options)
4328+
4329+
// Create a live query that uses the collection
4330+
// This creates a subscription that will trigger the unsubscribed event when cleaned up
4331+
const liveQuery = createLiveQueryCollection({
4332+
query: (q) =>
4333+
q
4334+
.from({ item: collection })
4335+
.select(({ item }) => ({ id: item.id, name: item.name })),
4336+
})
4337+
4338+
// Preload the live query - this will create the query with the subscription
4339+
await liveQuery.preload()
4340+
4341+
// Wait for data to load
4342+
await vi.waitFor(() => {
4343+
expect(queryFn).toHaveBeenCalledTimes(1)
4344+
expect(collection.size).toBe(2)
4345+
})
4346+
4347+
// Verify query data is in the cache
4348+
const cachedData = testQueryClient.getQueryData(
4349+
queryKey
4350+
) as Array<TestItem>
4351+
expect(cachedData).toBeDefined()
4352+
expect(cachedData).toEqual(items)
4353+
4354+
// Cleanup the live query - this triggers the unsubscribed event
4355+
await liveQuery.cleanup()
4356+
4357+
// Wait 100ms, the gcTime is set to 300ms, so data should remain in the cache
4358+
await new Promise((resolve) => setTimeout(resolve, 100))
4359+
4360+
// Data should remain in cache until gcTime elapses
4361+
const cachedDataAfterCleanup = testQueryClient.getQueryData(queryKey)
4362+
expect(cachedDataAfterCleanup).toBeDefined()
4363+
expect(cachedDataAfterCleanup).toEqual(items)
4364+
4365+
// Wait an additional 250ms to be sure the gcTime elapsed
4366+
await new Promise((resolve) => setTimeout(resolve, 250))
4367+
4368+
// Data should be removed from cache after gcTime elapses
4369+
const cachedDataAfterCacheTime = testQueryClient.getQueryData(queryKey)
4370+
expect(cachedDataAfterCacheTime).toBeUndefined()
4371+
4372+
// Cleanup
4373+
testQueryClient.clear()
4374+
})
42944375
})
42954376

42964377
describe(`Static queryKey with on-demand mode`, () => {

0 commit comments

Comments
 (0)