Repository navigation
Stabilize fresh React Suspense requests - #16
Merged
Merged
Conversation
Own fresh render requests within each query instance and retain them across retries and sibling consumers. Keep imperative fresh queries independent and document request lifetimes and invalidation. BREAKING CHANGE: Hand-written implementations of Query must now implement resource(). Implement the documented retain/release request lifecycle or obtain instances from createQuery(); createQuery callers need no API migration. This instance-owned lifecycle is required because React discards initial hook state when rendering suspends.
Preserve request ownership and background observer error handling while synchronizing fresh resource cache writes. Add integration coverage for obsolete request rejection and fresh refresh failure/recovery.
ConsoleTVs
marked this pull request as ready for review
October 24, 2026 12:30
Keep queued mutation commits and fetch supersession while synchronizing fresh resource promises. Preserve opt-in broadcast ownership and both migration guides; cover mutation, hydration, abort and provider integration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Query.resource/QueryResource.createQuerycallers need no migration; hand-writtenQueryimplementations must add the resource retain/release protocol. The implementation commit has a BREAKING CHANGE footer.ad27cc6(v2.0.0), preserving Fix request ownership across overlapping fetches #12 request ownership, Preserve rendered data on background refetch errors #14 background-error handling, Preserve mutation ordering against older fetches #15 mutation queues/superseded-fetch tracking, and Make React cross-tab query broadcasts explicitly opt-in #13 opt-in caller-owned broadcast channels. Successful queued mutations and hydration synchronize resource promises throughcacheItem; both README migration sections remain intact.Evidence
npx vitest run src/react/hooks/useQueryFresh.test.tsx -t 'shares per-hook').After: 113 tests pass across 15 files, including 24 tests added relative to current main's 89 tests. Regression coverage includes retries, siblings, rerenders, StrictMode, key/instance changes, remounts, errors, and explicit refreshes.
npm test,npm run lint,npm run format:check,git diff --check, and sensitive-path checks pass. The final follow-up commit changes documentation only and passes lint/format checks.npm run buildexits 0 and emits bundles, but reports the existing SolidQueryProvider.tsx:80TS2786 diagnostic. Reproduced on unchanged current-main baselinead27cc6; baseline passes 89 tests and prints the same negative-timeout warning category.npx tsc --build --pretty falseremains blocked by baseline React/Solid JSX pollution: 75 diagnostics on current main, 76 here (the additional use-site is the new test rendering the existing QueryProvider). Isolated React/core typechecking has zero diagnostics across 36 root files, including all new tests.npm cireported 16 dependency vulnerabilities. This PR does not change dependencies relative to main.Merge Danger
Door: two-way
Fresh React reads now share a request lifetime instead of restarting on every render. Uncommitted/rejected selections remain until invalidation or instance collection. Committed consumers retain their successful value through failed refreshes; initial render errors and explicit action rejections retain their existing behavior.
Hand-written
Queryadapters require migration to implementresource;createQuerycallers need no API migration. The breaking-change footer can trigger another major release after main's v2.0.0. Main integration conflicts are resolved; await review/CI before merging.Hydration updates cache/resource state immediately. The existing async refetch transition can defer the visible update while a request remains pending; this was independently reproduced on unchanged main and is not changed by this fix. Integration tests assert immediate cache/resource synchronization and final rendered state after observers settle.
Blast Radius: consumers
The per-instance resource API synchronizes successful writes only after ownership/supersession checks. Existing imperative
query(..., { fresh: true })still aborts/replaces pending requests. Providers neither create nor close channels. No force push, rebase, reset, or PR merge was performed.