Skip to content

perf(plugin-react-query): dispatch operations to one matching generator family - #728

Closed
stijnvanhulle wants to merge 3 commits into
mainfrom
claude/github-issue-3816-42yfz9
Closed

perf(plugin-react-query): dispatch operations to one matching generator family#728
stijnvanhulle wants to merge 3 commits into
mainfrom
claude/github-issue-3816-42yfz9

Conversation

@stijnvanhulle

Copy link
Copy Markdown
Contributor

🎯 Changes

Every operation used to run through all five plugin-react-query operation generators (query, suspenseQuery, infiniteQuery, suspenseInfiniteQuery, mutation), each independently re-classifying the node and bailing out early when it didn't match. So a mutation like addPet hit all five generators and four did nothing.

This adds a new operationGenerator that classifies each operation as query or mutation once (via the existing classifyOperation), then calls only the generators for the matching family:

  • mutation → mutationGenerator
  • query → queryGenerator, suspenseQueryGenerator, infiniteQueryGenerator, suspenseInfiniteQueryGenerator (each still gated by its own suspense/infinite/hooks options, as before)

plugin.ts now registers this single dispatcher instead of the five generators directly, so the core AST walk invokes one operation generator per node instead of five. The individual generator files, their exports, and their existing unit tests are untouched.

Generated output is unchanged: tests/3.0.x/pluginReactQuery.test.ts's snapshot suite (11 configs covering suspense, infinite, custom query/mutation methods, groups, includes/excludes, etc.) passes without modification.

Fixes kubb-labs/kubb#3816.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is for the docs (no release).

Generated by Claude Code

…or family

Classifies each operation as query or mutation once via a new operationGenerator,
then calls only the matching hook generators, instead of registering all five
(query, suspenseQuery, infiniteQuery, suspenseInfiniteQuery, mutation) as
separate core generators that each run for every operation with four
returning early.

Fixes kubb-labs/kubb#3816. Generated output is unchanged (snapshot parity
verified via tests/3.0.x/pluginReactQuery.test.ts).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf
@codesandbox

codesandbox Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@changeset-bot

changeset-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1b86e09

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@kubb/plugin-react-query Patch
tests-3.0.x Patch
e2e Patch

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

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 18, 2026
@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Size Change: +2.09 kB (+0.71%)

Total Size: 296 kB

📦 View Changed
Filename Size Change
packages/plugin-react-query/dist/index.cjs 18 kB +1.05 kB (+6.18%) 🔍
packages/plugin-react-query/dist/index.js 17.5 kB +1.04 kB (+6.31%) 🔍
ℹ️ View Unchanged
Filename Size
packages/plugin-axios/dist/index.cjs 14.2 kB
packages/plugin-axios/dist/index.js 13.7 kB
packages/plugin-axios/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-cypress/dist/index.cjs 5.06 kB
packages/plugin-cypress/dist/index.js 4.99 kB
packages/plugin-cypress/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-faker/dist/index.cjs 13.6 kB
packages/plugin-faker/dist/index.js 13.5 kB
packages/plugin-faker/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-fetch/dist/index.cjs 14.2 kB
packages/plugin-fetch/dist/index.js 13.7 kB
packages/plugin-fetch/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-mcp/dist/index.cjs 9.43 kB
packages/plugin-mcp/dist/index.js 8.95 kB
packages/plugin-mcp/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-msw/dist/index.cjs 5.33 kB
packages/plugin-msw/dist/index.js 5.24 kB
packages/plugin-msw/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-react-query/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-redoc/dist/index.cjs 2.21 kB
packages/plugin-redoc/dist/index.js 1.75 kB
packages/plugin-redoc/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-swr/dist/index.cjs 11.3 kB
packages/plugin-swr/dist/index.js 10.8 kB
packages/plugin-swr/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-ts/dist/index.cjs 23.4 kB
packages/plugin-ts/dist/index.js 22.7 kB
packages/plugin-ts/dist/rolldown-runtime-CNktS9qV.js 291 B
packages/plugin-vue-query/dist/index.cjs 14.1 kB
packages/plugin-vue-query/dist/index.js 13.6 kB
packages/plugin-vue-query/dist/rolldown-runtime-C0LytTxp.js 168 B
packages/plugin-zod/dist/index.cjs 18.3 kB
packages/plugin-zod/dist/index.js 18.1 kB
packages/plugin-zod/dist/rolldown-runtime-C0LytTxp.js 168 B

compressed-size-action

@pkg-pr-new

pkg-pr-new Bot commented Jul 18, 2026

Copy link
Copy Markdown
More templates

@kubb/plugin-axios

npm i https://pkg.pr.new/@kubb/plugin-axios@728

@kubb/plugin-cypress

npm i https://pkg.pr.new/@kubb/plugin-cypress@728

@kubb/plugin-faker

npm i https://pkg.pr.new/@kubb/plugin-faker@728

@kubb/plugin-fetch

npm i https://pkg.pr.new/@kubb/plugin-fetch@728

@kubb/plugin-mcp

npm i https://pkg.pr.new/@kubb/plugin-mcp@728

@kubb/plugin-msw

npm i https://pkg.pr.new/@kubb/plugin-msw@728

@kubb/plugin-react-query

npm i https://pkg.pr.new/@kubb/plugin-react-query@728

@kubb/plugin-redoc

npm i https://pkg.pr.new/@kubb/plugin-redoc@728

@kubb/plugin-swr

npm i https://pkg.pr.new/@kubb/plugin-swr@728

@kubb/plugin-ts

npm i https://pkg.pr.new/@kubb/plugin-ts@728

@kubb/plugin-vue-query

npm i https://pkg.pr.new/@kubb/plugin-vue-query@728

@kubb/plugin-zod

npm i https://pkg.pr.new/@kubb/plugin-zod@728

commit: 1b86e09

claude added 2 commits July 18, 2026 12:07
Fold the query/mutation classification and dispatch directly into
plugin.ts instead of a separate generator file, so this PR doesn't add
net-new files on top of the five existing generators. Each matching
generator's JSX result is rendered and upserted directly (no `renderer`
needed on the dispatcher), so plugin.ts stays plain TypeScript like every
other plugin's entry file.

Coverage now relies on the existing per-generator unit tests plus the
tests/3.0.x/pluginReactQuery.test.ts snapshot suite, which still passes
unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf
…/tanstack-query

Move the query/mutation classify-and-dispatch generator into
@internals/tanstack-query as createOperationDispatcher, next to the
classifyOperation it's built on, instead of duplicating it inline in
plugin-react-query's plugin.ts. Other TanStack-family plugins (vue-query,
swr) have the same query/mutation config shape and can reuse it later.

plugin.ts now just builds the query and mutation generator lists and
passes them to the shared factory.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf
stijnvanhulle added a commit to kubb-labs/kubb that referenced this pull request Jul 18, 2026
#3828)

* feat(core): add a match predicate to Generator

Add an optional match(node, ctx) => boolean to Generator, checked by
KubbDriver#runGenerators before calling schema/operation. A generator
whose match resolves false is skipped for that node entirely, with no
extra context work and no render call. Omitting match keeps today's
behavior of always running, so this is purely additive.

renderGeneratorSchema/renderGeneratorOperation in mocks.ts honor match
too, so a generator's own unit tests exercise the same skip behavior as
real dispatch.

This replaces the need for a plugin to hand-roll its own dispatcher when
several of its generators only apply to a subset of nodes each, as
plugin-react-query's createOperationDispatcher does today in
kubb-labs/plugins#728.

Fixes #3826.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf

* refactor(ast,core): rename Macro's when gate to match, and clean up await checks

Macro.when hasn't shipped yet (still part of the pending, unreleased
macro-ast-transform-layer changeset), so rename it to match for
consistency with the new Generator.match predicate added in the previous
commit — same concept, same name, across both abstractions.

Also extract the await out of the compound if conditions in
KubbDriver#runGenerators and the mocks.ts test helpers into a plain
matches variable first, for readability.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf

* docs: tighten the match predicate changeset

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf

---------

Co-authored-by: Claude <noreply@anthropic.com>
stijnvanhulle added a commit that referenced this pull request Jul 18, 2026
…d of the dispatcher (#730)

* refactor(plugin-react-query): use the new core match predicate instead of the dispatcher

Give each of the five hook generators a match predicate instead of
classifying and bailing out inside operation(). This is what
createOperationDispatcher (added in #728 to fix kubb-labs/kubb#3816)
was working around: @kubb/core's Generator now supports match natively,
so the core driver skips a non-matching generator before calling it and
plugin.ts goes back to registering the five generators directly.

Generated output is unchanged (verified against
tests/3.0.x/pluginReactQuery.test.ts's 11-config snapshot suite, run
locally against a kubb build linked from ../kubb via pnpm-workspace.yaml's
commented-out overrides).

Requires kubb-labs/kubb#3828 to merge and release before this is
mergeable: without match support in the driver, these generators would
run unconditionally for every operation, since the old classify-and-bail
guards were moved into match. Do not merge until the kubb catalog
version here is bumped past that release.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf

* docs: tighten the match predicate changeset

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf

* chore: bump kubb catalog to 5.0.0-beta.104 and simplify match predicates

The published beta.104 carries the match predicate support this branch
depends on. Simplify each generator's match to narrow SchemaNode |
OperationNode via a single cast plus isHttpOperationNode instead of a
node.kind string check, and drop the queryParam regex normalization in
favor of a plain includes() check against both the plain and optional key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LnAWjXX2zoWWScgn7NsLaf

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

react-query runs five operation generators for every operation

2 participants