-
Notifications
You must be signed in to change notification settings - Fork 150
Investigate on-demand mode suspense issue in on-demand mode #1081
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…in on-demand mode When using useLiveSuspenseQuery with on-demand sync mode, the suspense boundary would sometimes release before the query's data was actually loaded. This happened because the live query collection was marked as ready immediately when the source collection was already ready, even though the loadSubset operation for the specific query hadn't completed. This fix ensures that useLiveSuspenseQuery also suspends while isLoadingSubset is true, waiting for the initial subset load to complete before releasing the suspense boundary.
🦋 Changeset detectedLatest commit: 12e4d74 The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This test verifies that useLiveSuspenseQuery holds the suspense boundary when isLoadingSubset is true, even if the collection status is 'ready'. The test confirms: 1. WITHOUT the fix: suspense releases prematurely (test fails) 2. WITH the fix: suspense waits for isLoadingSubset to be false (test passes)
More templates
@tanstack/angular-db
@tanstack/db
@tanstack/db-ivm
@tanstack/electric-db-collection
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +129 B (+0.14%) Total Size: 89.6 kB
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 3.35 kB ℹ️ View Unchanged
|
…a is loaded In on-demand sync mode, the live query collection was being marked as 'ready' before the subset data finished loading. This caused useLiveQuery to return isReady=true with empty data, and useLiveSuspenseQuery to release suspense prematurely. The fix: 1. Added isLoadingSubset check in updateLiveQueryStatus() to prevent marking ready while subset is loading 2. Added listener for loadingSubset:change events to trigger ready check when subset loading completes 3. Added test case that verifies the correct timing behavior
…race condition The loadingSubset:change listener was registered after subscribeToAllCollections(), which could cause a race condition where the event fires before the listener is registered. This resulted in the live query never becoming ready. Also adds await in electric test to account for async subset loading.
Register the status:change listener BEFORE checking the current subscription status to avoid missing status transitions. Previously, if loadSubset completed very quickly, the status could change from 'loadingSubset' to 'ready' between checking the status and registering the listener, causing the tracked promise to never resolve and the live query to never become ready.
|
Out of curiosity, I tried the latest from here and unfortunately the problem persists. So I had Claude add a bunch of debug logs to spots that might be relevant, then reloaded our app, and fed the logs back into claude for diagnosis. Here are the resulting findings from Claude in case helpful (including the debug logs from the actual reproduction): Debug Analysis:
|
…ery's The previous fix incorrectly checked isLoadingSubset on the live query collection itself, but the loadSubset/trackLoadPromise mechanism runs on SOURCE collections during on-demand sync, so the live query's isLoadingSubset was always false. This fix: - Adds anySourceCollectionLoadingSubset() to check if any source collection has isLoadingSubset=true - Listens for loadingSubset:change events on source collections instead of the live query collection
…rce collections Reverts the change to check source collections' isLoadingSubset, which was causing test timeouts in query-db-collection tests. The live query collection's isLoadingSubset is correctly updated by CollectionSubscriber.trackLoadPromise() which tracks loading on the live query collection itself. Also updates changeset to accurately describe the fix.
|
That changes since my last comment fixed it! There are several adjustments in this PR, unsure which one(s) are the actual fixes, but something in the last couple of commits finally resolved it. Might want to figure out a test that fails before the last couple of commits, and succeeds with the changes from the last couple of commits. |
…r snapshot trigger The subscription's status:change listener was being registered AFTER the snapshot was triggered (via requestSnapshot/requestLimitedSnapshot). This meant that if the loadSubset promise resolved quickly (or synchronously), the status transition from 'loadingSubset' to 'ready' could be missed entirely. Changes: - Refactored subscribeToChanges() to split subscription creation from snapshot triggering - subscribeToMatchingChanges() and subscribeToOrderedChanges() now return both the subscription AND a triggerSnapshot function - The status listener is registered AFTER getting the subscription but BEFORE calling triggerSnapshot() - Added deferSnapshot option to subscribeChanges() to prevent automatic snapshot request - For non-ordered queries, continue using trackLoadSubsetPromise: false to maintain compatibility with query-db-collection's destroyed observer handling - Updated test for source collection isLoadingSubset independence - Added regression test for the race condition fix

When using useLiveSuspenseQuery with on-demand sync mode, the suspense boundary would sometimes release before the query's data was actually loaded. This happened because the live query collection was marked as ready immediately when the source collection was already ready, even though the loadSubset operation for the specific query hadn't completed.
This fix ensures that useLiveSuspenseQuery also suspends while isLoadingSubset is true, waiting for the initial subset load to complete before releasing the suspense boundary.
🎯 Changes
✅ Checklist
pnpm test:pr.🚀 Release Impact