fix(solid-query): follow queryClient changes in useMutation 🤖🤖🤖 - #11545
dijedontahiri wants to merge 9 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: TanStack/query/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
ChangesMutation client switching
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant QueryClientAccessor
participant useMutation
participant MutationObserver
QueryClientAccessor->>useMutation: provide current QueryClient
useMutation->>MutationObserver: create observer
QueryClientAccessor->>useMutation: provide changed QueryClient
useMutation->>MutationObserver: retain pending observer and unsubscribe
useMutation->>MutationObserver: create observer for changed client
MutationObserver->>useMutation: update mutation result
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Preserve per-call callback execution for in-flight mutations when switching clients.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
What changed in this PR
Updates Solid Query’s useMutation to follow reactive QueryClient changes by replacing its mutation observer.
Changes:
- Recreates and subscribes to an observer for the current client.
- Adds client-switching regression tests.
- Adds a patch changeset.
| File | Summary |
|---|---|
packages/solid-query/src/useMutation.ts |
Observer lifecycle updated; critical unresolved issue: switching clients can suppress callbacks for in-flight mutations (1 vote). |
packages/solid-query/src/__tests__/useMutation.queryClient.test.tsx |
Tests client-specific mutation behavior. |
.changeset/solid-mutation-client-switch.md |
Records the patch release. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| on( | ||
| client, | ||
| (nextClient) => { | ||
| unsubscribe() |
There was a problem hiding this comment.
Confirmed and fixed on the current head 0606ea9da15f4f8fbc761ffb0aca6593729d6b48.
The final implementation retains a state-isolated subscription to an outgoing observer only while its mutation is pending. That keeps the per-call callback lifecycle alive without allowing the old observer to update the new client's exposed state; the retained subscription is released when the old mutation settles or when the component unmounts.
I added two focused regressions around this review case. In immutable-head validation, the original PR candidate 36990befc39232df24b016b204d393f6d412487d passes the basic client-switch test but fails should preserve per-call callbacks for an in-flight mutation after switching clients; the final head passes that test plus the unmount cleanup control. The full Solid unit/type/lint/build/publication checks and root test:pr also pass on the exact final head: https://github.com/dijedontahiri/query/actions/runs/35428513719
Automated-agent reply under the PR's 🤖🤖🤖 route.

🎯 Changes
Fixes #11544.
useMutationresolves a reactive customqueryClientaccessor, but itsMutationObserverwas constructed once from the initial client. Switching the accessor therefore left subsequentmutate()calls on the previous client's defaults/cache and kept the exposed result tied to the old observer.This change swaps to a fresh
MutationObserverwhen the resolved client changes, resets the exposed state to that observer, and makesmutate()always use the current observer.The review also exposed an important callback-lifecycle edge case: simply unsubscribing the old observer while one of its mutations is pending suppresses that mutation's per-call callbacks, because
MutationObserveronly delivers them while it still has listeners. The final implementation therefore retains a state-isolated subscription to an outgoing pending observer until it settles, and releases that subscription either on settlement or component cleanup. Results from the retained observer are never written into the new client's state.Regression coverage now verifies all three behaviors:
Validation
Exact final candidate:
0606ea9da15f4f8fbc761ffb0aca6593729d6b48Exact base:
d346e85f0144eb9b991e6e1665b22f4574de9751Hosted immutable-head validation: https://github.com/dijedontahiri/query/actions/runs/35428513719
The validation checked out the exact final candidate SHA and verified meaningful negative controls before running the final tree:
useMutation.ts+ the final regression file: the queryClient-switch regression fails while the unrelated unmount control passes;36990befc39232df24b016b204d393f6d412487d+ the final regression file: the basic client-switch regression passes, but the new in-flight per-call callback regression fails while the unmount control passes;Final-tree checks all passed:
pnpm nx run @tanstack/solid-query:test:lib --skip-nx-cachepnpm nx run @tanstack/solid-query:test:types --skip-nx-cacheacross the repository's configured TypeScript matrixpnpm nx run @tanstack/solid-query:test:eslint --skip-nx-cachepnpm nx run @tanstack/solid-query:build --skip-nx-cachepnpm nx run @tanstack/solid-query:test:build --skip-nx-cachepnpm run generate-docswith no generated diffpnpm run test:pr --base=d346e85f0144eb9b991e6e1665b22f4574de9751 --head=0606ea9da15f4f8fbc761ffb0aca6593729d6b48 --skip-nx-cache --parallel=2git diff --check, exact-head verification, and exact three-file contribution-scope audit.A patch changeset for
@tanstack/solid-queryis included.Automated-agent disclosure: this PR was prepared, tested, updated, and submitted through TanStack Query's documented
🤖🤖🤖automated-agent opt-in route. It does not claim independent human review.✅ Checklist
pnpm run test:prflow and the focused/package checks listed above.🚀 Release Impact