feat(query-core): forward caller-provided meta into the invalidate action payload#10540
feat(query-core): forward caller-provided meta into the invalidate action payload#10540maastrich wants to merge 2 commits intoTanStack:mainfrom
Conversation
📝 WalkthroughWalkthroughinvalidateQueries can accept an optional Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant QC as QueryClient
participant Q as Query
participant Sub as Subscriber
Client->>QC: invalidateQueries(filters, { meta })
QC->>Q: invalidate(meta)
Q->>Sub: emit updated (action: { type: "invalidate", meta: meta })
Sub-->>Client: read event.action.meta
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/query-core/src/queryClient.ts (1)
297-311:⚠️ Potential issue | 🟠 MajorStrip
metabefore forwarding options torefetchQueries.
options.metais intended for the invalidate action, but the fulloptionsobject is also passed intorefetchQueries. That leaks the same object intoquery.fetch(..., fetchOptions), wherefetchOptions.metais interpreted as fetch metadata and can updatefetchMeta/ fetch events with invalidation metadata.Proposed fix
): Promise<void> { return notifyManager.batch(() => { + const { meta, ...refetchOptions } = options + this.#queryCache.findAll(filters).forEach((query) => { - query.invalidate(options.meta) + query.invalidate(meta) }) if (filters?.refetchType === 'none') { return Promise.resolve() } @@ ...filters, type: filters?.refetchType ?? filters?.type ?? 'active', }, - options, + refetchOptions, ) }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/query-core/src/queryClient.ts` around lines 297 - 311, The invalidate loop correctly uses options.meta but you must avoid forwarding that same meta into refetchQueries; when calling this.refetchQueries(...) strip out meta from the options passed (e.g., clone options then delete or omit options.meta) so invalidate receives meta but the refetch call receives options without meta; locate the call to notifyManager.batch -> this.#queryCache.findAll(...).forEach(query => query.invalidate(options.meta)) and change the refetchQueries invocation to pass a copy of options with meta removed before spreading into the second argument.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/query-core/src/queryClient.ts`:
- Around line 297-311: The invalidate loop correctly uses options.meta but you
must avoid forwarding that same meta into refetchQueries; when calling
this.refetchQueries(...) strip out meta from the options passed (e.g., clone
options then delete or omit options.meta) so invalidate receives meta but the
refetch call receives options without meta; locate the call to
notifyManager.batch -> this.#queryCache.findAll(...).forEach(query =>
query.invalidate(options.meta)) and change the refetchQueries invocation to pass
a copy of options with meta removed before spreading into the second argument.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6a2f6275-2903-4509-b84a-b2a7e73fffc8
📒 Files selected for processing (7)
.changeset/invalidate-queries-meta.mddocs/framework/react/guides/query-invalidation.mddocs/reference/QueryClient.mdpackages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/query.tspackages/query-core/src/queryClient.tspackages/query-core/src/types.ts
4819bff to
76550ee
Compare
…cache action Adds an optional `meta` field to `InvalidateOptions` that flows through to the `invalidate` action payload visible in `queryCache.subscribe`, enabling structured observability and echo-suppression without out-of-band bookkeeping. Closes TanStack#10539 (discussion) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Queries meta is specific to the invalidate action and should not leak into the refetch call that follows. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76550ee to
3cfeb2e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/query-core/src/query.ts`:
- Around line 392-396: The current invalidate method drops caller-supplied meta
when state.isInvalidated is true because it skips dispatch; change
invalidate(meta?: QueryMeta) to always emit a dispatch carrying meta so
subscribers can observe every call — either always call this.#dispatch({ type:
'invalidate', meta }) (and let reducers ignore no-op state changes) or dispatch
a distinct action (e.g., type: 'invalidateMeta') when state.isInvalidated is
already true; update any action handlers/listeners that consume type
'invalidate' to handle the no-op case or handle the new 'invalidateMeta' action
so meta is propagated to subscribers without altering state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 51a91876-d9d5-4132-9d3f-6dcda6257543
📒 Files selected for processing (7)
.changeset/invalidate-queries-meta.mddocs/framework/react/guides/query-invalidation.mddocs/reference/QueryClient.mdpackages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/query.tspackages/query-core/src/queryClient.tspackages/query-core/src/types.ts
✅ Files skipped from review due to trivial changes (3)
- .changeset/invalidate-queries-meta.md
- docs/reference/QueryClient.md
- docs/framework/react/guides/query-invalidation.md
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/query-core/src/queryClient.ts
- packages/query-core/src/types.ts
- packages/query-core/src/tests/queryClient.test.tsx
Summary
Implements the proposal from discussion #10539.
meta?: QueryMetatoInvalidateOptions(second arg ofinvalidateQueries)query.invalidate(meta)into the dispatchedInvalidateActionevent.action.metaavailable inqueryCache.subscribefor structured observability and echo-suppressionUsage
Notes
metais optional and defaults toundefined. No existing call site is affected.options.metais distinct fromfilters.meta(which filters queries by their meta).isInvalidatedguard is preserved: if a query is already invalidated, the dispatch is skipped and the meta from subsequent calls is silently dropped. This is consistent with current behavior and can be revisited separately.query-broadcast-client-experimentaldoes not broadcastinvalidateactions today, so no changes are needed there.Checklist
query.ts,queryClient.ts,types.ts)queryClient.test.tsxdocs/reference/QueryClient.md)docs/framework/react/guides/query-invalidation.md) — other framework guides mirror it viaref:minorfor@tanstack/query-core)Closes discussion: #10539
Summary by CodeRabbit
New Features
Documentation
Tests