Skip to content

Commit 0c6d25e

Browse files
committed
Handle garbage collection of the underlying tanstack queries
1 parent b5050d4 commit 0c6d25e

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
@@ -669,6 +669,48 @@ export function queryCollectionOptions(
669669
handleQueryResult(observer.getCurrentResult())
670670
})
671671

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

683726
await Promise.all(
684727
queryKeys.map(async (queryKey) => {

0 commit comments

Comments
 (0)