Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/query-db-collection-gctime-forward.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/query-db-collection': patch
---

Forward `gcTime` from `queryCollectionOptions` to the underlying TanStack Query observer. The `gcTime` option was previously documented in the config shape but silently dropped before reaching the observer, leaving consumers stuck on the `queryClient` default. Closes #1546.
9 changes: 9 additions & 0 deletions packages/query-db-collection/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ export interface QueryCollectionConfig<
TQueryData,
TQueryKey
>[`staleTime`]
gcTime?: QueryObserverOptions<
TQueryData,
TError,
Array<T>,
TQueryData,
TQueryKey
>[`gcTime`]
persistedGcTime?: number

/**
Expand Down Expand Up @@ -578,6 +585,7 @@ export function queryCollectionOptions(
retry,
retryDelay,
staleTime,
gcTime,
persistedGcTime,
getKey,
onInsert,
Expand Down Expand Up @@ -1163,6 +1171,7 @@ export function queryCollectionOptions(
...(retry !== undefined && { retry }),
...(retryDelay !== undefined && { retryDelay }),
...(staleTime !== undefined && { staleTime }),
...(gcTime !== undefined && { gcTime }),
}

const localObserver = new QueryObserver<
Expand Down
101 changes: 101 additions & 0 deletions packages/query-db-collection/tests/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3594,6 +3594,107 @@ describe(`QueryCollection`, () => {
customQueryClient.clear()
})

it(`should forward gcTime from queryCollectionOptions to the underlying query`, async () => {
const customQueryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 60000,
},
},
})

const queryKey = [`gcTimeForwardTest`]
const items: Array<TestItem> = [{ id: `1`, name: `Item 1` }]
const queryFn = vi.fn().mockResolvedValue(items)

const config: QueryCollectionConfig<TestItem> = {
id: `gcTimeForwardTest`,
queryClient: customQueryClient,
queryKey,
queryFn,
getKey,
startSync: true,
gcTime: 100000,
}

const options = queryCollectionOptions(config)
const collection = createCollection(options)

await vi.waitFor(() => {
expect(collection.status).toBe(`ready`)
})

const query = customQueryClient.getQueryCache().find({ queryKey })
expect((query?.options as any).gcTime).toBe(100000)

customQueryClient.clear()
})

it(`should fall back to QueryClient default gcTime when omitted`, async () => {
const customQueryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 45000,
},
},
})

const queryKey = [`gcTimeFallbackTest`]
const items: Array<TestItem> = [{ id: `1`, name: `Item 1` }]
const queryFn = vi.fn().mockResolvedValue(items)

const config: QueryCollectionConfig<TestItem> = {
id: `gcTimeFallbackTest`,
queryClient: customQueryClient,
queryKey,
queryFn,
getKey,
startSync: true,
}

const options = queryCollectionOptions(config)
const collection = createCollection(options)

await vi.waitFor(() => {
expect(collection.status).toBe(`ready`)
})

const query = customQueryClient.getQueryCache().find({ queryKey })
expect((query?.options as any).gcTime).toBe(45000)

customQueryClient.clear()
})

it(`should accept Infinity as gcTime to disable garbage collection`, async () => {
const customQueryClient = new QueryClient()

const queryKey = [`gcTimeInfinityTest`]
const items: Array<TestItem> = [{ id: `1`, name: `Item 1` }]
const queryFn = vi.fn().mockResolvedValue(items)

const config: QueryCollectionConfig<TestItem> = {
id: `gcTimeInfinityTest`,
queryClient: customQueryClient,
queryKey,
queryFn,
getKey,
startSync: true,
gcTime: Infinity,
}

const options = queryCollectionOptions(config)
const collection = createCollection(options)

await vi.waitFor(() => {
expect(collection.status).toBe(`ready`)
})

const query = customQueryClient.getQueryCache().find({ queryKey })
expect((query?.options as any).gcTime).toBe(Infinity)

customQueryClient.clear()
})

it(`should use retry from QueryClient defaultOptions when not overridden`, async () => {
let callCount = 0
// Create a QueryClient with custom retry defaultOption
Expand Down