Skip to content

Commit 00b98c8

Browse files
committed
Handle garbage collection of the underlying tanstack queries
1 parent 7b14c8b commit 00b98c8

File tree

1 file changed

+43
-0
lines changed
  • packages/query-db-collection/src

1 file changed

+43
-0
lines changed

packages/query-db-collection/src/query.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,48 @@ export function queryCollectionOptions(
665665
handleQueryResult(observer.getCurrentResult())
666666
})
667667

668+
// Subscribe to the query client's cache to handle queries that are GCed by tanstack query
669+
const unsubscribeQueryCache = queryClient
670+
.getQueryCache()
671+
.subscribe((event) => {
672+
const hashedKey = event.query.queryHash
673+
if (event.type === `removed`) {
674+
cleanupQuery(hashedKey)
675+
}
676+
})
677+
678+
function cleanupQuery(hashedQueryKey: string) {
679+
// Unsubscribe from the query's observer
680+
unsubscribes.get(hashedQueryKey)?.()
681+
682+
// Get all the rows that are in the result of this query
683+
const rowKeys = queryToRows.get(hashedQueryKey) ?? new Set()
684+
685+
// Remove the query from these rows
686+
rowKeys.forEach((rowKey) => {
687+
const queries = rowToQueries.get(rowKey) // set of queries that reference this row
688+
if (queries && queries.size > 0) {
689+
queries.delete(hashedQueryKey)
690+
if (queries.size === 0) {
691+
// Reference count dropped to 0, we can GC the row
692+
rowToQueries.delete(rowKey)
693+
694+
if (collection.has(rowKey)) {
695+
begin()
696+
write({ type: `delete`, value: collection.get(rowKey) })
697+
commit()
698+
}
699+
}
700+
}
701+
})
702+
703+
// Remove the query from the internal state
704+
unsubscribes.delete(hashedQueryKey)
705+
observers.delete(hashedQueryKey)
706+
queryToRows.delete(hashedQueryKey)
707+
hashToQueryKey.delete(hashedQueryKey)
708+
}
709+
668710
const cleanup = async () => {
669711
unsubscribeFromCollectionEvents()
670712
unsubscribeFromQueries()
@@ -675,6 +717,7 @@ export function queryCollectionOptions(
675717
queryToRows.clear()
676718
rowToQueries.clear()
677719
observers.clear()
720+
unsubscribeQueryCache()
678721

679722
await Promise.all(
680723
queryKeys.map(async (queryKey) => {

0 commit comments

Comments
 (0)