Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d098f3c
fix(query-db-collection): resolve data loss on component remount
KyleAMathews Nov 20, 2025
dbb1fe7
chore: add changeset for query collection remount fix
KyleAMathews Nov 20, 2025
72059ad
fix: improve query collection GC to respect TanStack Query cache life…
KyleAMathews Nov 21, 2025
fb8bbd9
chore: format changeset file
KyleAMathews Nov 21, 2025
310a150
fix: add removeQueries to subscription cleanup to cancel in-flight qu…
KyleAMathews Nov 21, 2025
08733ab
test: add comprehensive tests for cache persistence on remount
KyleAMathews Nov 21, 2025
c2d1896
test: add assertions to removeQueries GC test
KyleAMathews Nov 21, 2025
c6c165b
Merge remote-tracking branch 'origin/main' into fix/query-collection-…
KyleAMathews Nov 21, 2025
e3a4492
feat: add reference counting and unloadSubset infrastructure for quer…
KyleAMathews Nov 21, 2025
f0d78cf
fix: implement all 3 refcount bug fixes for QueryObserver lifecycle
KyleAMathews Nov 21, 2025
6ad7848
fix: remove cancelQueries call that interferes with active subscriptions
KyleAMathews Nov 21, 2025
71eda8c
test: add coverage for unsubscribe during in-flight load
KyleAMathews Nov 21, 2025
c2794d7
docs: refine comments to match crisp reviewer summary
KyleAMathews Nov 21, 2025
cf81253
docs: update changeset and PR body to describe changes vs main
KyleAMathews Nov 21, 2025
3238df7
chore: format changeset with prettier
KyleAMathews Nov 21, 2025
efe2c4d
fix: handle unsupported operators gracefully in e2e test mock
KyleAMathews Nov 21, 2025
99e4d17
Merge remote-tracking branch 'origin/main' into fix/query-collection-…
KyleAMathews Nov 21, 2025
03dbf4b
fix: add safety check to prevent premature observer cleanup
KyleAMathews Nov 21, 2025
09cbb0b
fix: deduplicate loadedSubsets to prevent refcount drift
KyleAMathews Nov 21, 2025
24c9cd7
chore: format code with prettier
KyleAMathews Nov 21, 2025
ba5b4e4
fix: revert unnecessary deduplication and hasListeners() check
KyleAMathews Nov 21, 2025
f95a51a
docs: simplify changeset after reverting unnecessary fixes
KyleAMathews Nov 21, 2025
127530a
fix: prevent premature cleanup during invalidateQueries refetches
KyleAMathews Nov 21, 2025
2d40d6b
docs: update changeset to document safety check for mutations
KyleAMathews Nov 21, 2025
685ece5
Revert "docs: update changeset to document safety check for mutations"
KyleAMathews Nov 21, 2025
d88f215
debug: add logging to diagnose CI mutation test failures
KyleAMathews Nov 21, 2025
3433289
debug: remove safety check and add mutation logging
KyleAMathews Nov 21, 2025
c5ddd32
fix: add hasListeners check to prevent cleanup during invalidateQueries
KyleAMathews Nov 21, 2025
fd63c02
refactor: defer row cleanup to TanStack Query's 'removed' event
KyleAMathews Nov 21, 2025
2b4e5c8
refactor: separate explicit and subscription-based cleanup paths
KyleAMathews Nov 21, 2025
677d1cd
refactor: separate explicit cleanup from TanStack Query GC lifecycle
KyleAMathews Nov 21, 2025
9a47ded
remove guide
KyleAMathews Nov 21, 2025
0917f9e
fix: address code review feedback - type safety and production readiness
KyleAMathews Nov 22, 2025
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
27 changes: 27 additions & 0 deletions .changeset/fix-query-collection-remount-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"@tanstack/query-db-collection": patch
"@tanstack/db": patch
---

Fix data loss on component remount by implementing reference counting for QueryObserver lifecycle

**What changed vs main:**

Previously, when live query subscriptions unsubscribed, there was no tracking of which rows were still needed by other active queries. This caused data loss during remounts.

This PR adds reference counting infrastructure to properly manage QueryObserver lifecycle:

1. Pass same predicates to `unloadSubset` that were passed to `loadSubset`
2. Use them to compute the queryKey (via `generateQueryKeyFromOptions`)
3. Use existing machinery (`queryToRows` map) to find rows that query loaded
4. Decrement the ref count
5. GC rows where count reaches 0 (no longer referenced by any active query)

**Impact:**

- Navigation back to previously loaded pages shows cached data immediately
- No unnecessary refetches during quick remounts (< gcTime)
- Multiple live queries with identical predicates correctly share QueryObservers
- Proper row-level cleanup when last subscriber leaves
- TanStack Query's cache lifecycle (gcTime) is fully respected
- No data leakage from in-flight requests when unsubscribing
Loading
Loading