Skip to content

feat(query-core): add simplified query methods#10658

Open
DogPawHat wants to merge 1 commit intoTanStack:mainfrom
DogPawHat:simplified-query-methods/core
Open

feat(query-core): add simplified query methods#10658
DogPawHat wants to merge 1 commit intoTanStack:mainfrom
DogPawHat:simplified-query-methods/core

Conversation

@DogPawHat
Copy link
Copy Markdown
Contributor

@DogPawHat DogPawHat commented May 8, 2026

🎯 Changes

implements #9135

  • adds query and infiniteQuery methods as replacements for fetchQuery/fetchInfiniteQuery
  • new methods respect select, enabled and queryFn === skipToken
  • throws errors if enabled === false or queryFn === skipToken and no cached data is able to be returned.
  • updates tests for QueryClient
    • existing scenarios for fetchQuery fetch tests plus the new scenarios introduced (enabled, select, skipToken, static staleTime)
  • adds tests for the queryOptions adaptors
  • added deprecation tags to old methods (fetchQuery, prefetchQuery, ensureQueryData)

Docs and Adaptor packages releases are added in follow up PR's stacked on top of this one:

Framework adaptors:

Documentation:

Old PR and history here #9835
Reopening the new PR to clean up commit history

✅ Checklist

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

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features

    • Added imperative query APIs to run queries directly (including infinite-query execution), a static staleTime mode returning cached results without refetch, and execute-time controls for enabled, select, and staleTime.
  • Deprecations

    • Several older imperative query helpers are now deprecated; guidance added for safe prefetch-like usage.
  • Tests

    • Expanded type and runtime tests covering new APIs, typing, select/skip behavior, caching/static-staleTime, and prefetch semantics.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds imperative query() and infiniteQuery() methods to QueryClient, narrows execute-time option types (enabled, select, staleTime), marks older imperative fetch/ensure/prefetch APIs as deprecated, and updates type and runtime tests for the new behavior and typings.

Changes

Query Execute Methods and Type Refactor

Layer / File(s) Summary
Query Execute Option Types
packages/query-core/src/types.ts
New QueryExecuteOptions interface limits supported options to enabled, select, and staleTime. New InfiniteQueryExecuteOptions composes these with required InitialPageParam and an internal InfiniteQueryPages type modeling page-data shapes.
Query and InfiniteQuery Methods
packages/query-core/src/queryClient.ts
New query() method applies defaults, resolves enabled state, checks staleness, fetches if needed, and applies optional select. infiniteQuery() sets _type = 'infinite' and delegates to query().
Deprecation Annotations
packages/query-core/src/queryClient.ts
ensureQueryData, fetchQuery, prefetchQuery, infiniteQuery, fetchInfiniteQuery, and prefetchInfiniteQuery receive JSDoc @deprecated markers directing migration to query()/infiniteQuery() and notes about .catch(noop) where applicable.
Type Deprecation Markers
packages/query-core/src/types.ts
QueryExecuteOptions, EnsureQueryDataOptions, EnsureInfiniteQueryDataOptions, and InfiniteQueryExecuteOptions are marked @deprecated. FetchInfiniteQueryOptions refactored to reuse new InfiniteQueryPages type.
TypeScript Type Coverage
packages/query-core/src/__tests__/queryClient.test-d.tsx
Type-tests validate query() and infiniteQuery() compile-time behavior: skipToken handling, select option narrowing, fetchQuery disallowing select, and fetchInfiniteQuery constraints on page parameters.
Runtime Test Coverage
packages/query-core/src/__tests__/queryClient.test.tsx
Functional tests cover static staleTime caching, falsy cached data, missing cache, initialData bypass, background revalidation, select application, skipToken interaction, garbage collection, and prefetch-like usage with .catch(noop).
Release Metadata
.changeset/true-cameras-wash.md
Changeset declares minor version bump for @tanstack/query-core and documents new methods and deprecations.

Sequence Diagram(s)

sequenceDiagram
  participant Client as QueryClient
  participant Cache as QueryCache
  participant Fn as queryFn
  participant Test as TestRunner
  Test->>Client: call query()/infiniteQuery()
  Client->>Cache: read cached entry
  alt cache present & not stale
    Cache-->>Client: return cached data
  else cache missing or stale
    Client->>Fn: invoke queryFn
    Fn-->>Client: return fetched data
    Client->>Cache: store fetched data
  end
  Client-->>Test: return Promise with (selected) data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 New queries hop in, brisk and smart,
query() and infiniteQuery() play their part.
Old fetches bow with deprecation flair—
types tightened, tests dance in the air.
Cache checked, select applied, off they dart.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding simplified query methods as a new feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description comprehensively covers all required template sections and provides detailed context about the changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 8, 2026

View your CI Pipeline Execution ↗ for commit 5d51700

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1s View ↗
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 40s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-10 20:58:15 UTC

@DogPawHat DogPawHat marked this pull request as ready for review May 8, 2026 13:46
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 8, 2026

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@10658

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@10658

@tanstack/lit-query

npm i https://pkg.pr.new/@tanstack/lit-query@10658

@tanstack/preact-query

npm i https://pkg.pr.new/@tanstack/preact-query@10658

@tanstack/preact-query-devtools

npm i https://pkg.pr.new/@tanstack/preact-query-devtools@10658

@tanstack/preact-query-persist-client

npm i https://pkg.pr.new/@tanstack/preact-query-persist-client@10658

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@10658

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@10658

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@10658

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@10658

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@10658

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@10658

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@10658

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@10658

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@10658

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@10658

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@10658

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@10658

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@10658

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@10658

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@10658

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@10658

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@10658

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@10658

commit: 5d51700

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/true-cameras-wash.md:
- Line 5: Fix the spelling mistake in the changeset text by replacing the
misspelled token "impertive" with the correct word "imperative" in the changeset
entry that reads "add query and infiniteQuery methods, deprecate old impertive
methods" so release notes and docs show the correct wording.

In `@packages/query-core/src/queryClient.ts`:
- Around line 370-380: The code currently calls this.#queryCache.build(...)
before checking enabled, which creates an empty query entry on "skip" requests;
to fix, evaluate isEnabled by calling
resolveQueryBoolean(defaultedOptions.enabled, /* without building */) first and
if it's false check the cache lookup (e.g.
this.#queryCache.get(defaultedOptions.queryHash)?.state.data) for existing data
— only call this.#queryCache.build(this, defaultedOptions) when enabled or when
cached data exists; if not enabled and no cached data, reject with the existing
error message. Use the symbols resolveQueryBoolean, defaultedOptions.enabled,
this.#queryCache.get / this.#queryCache.build, query.state.data, and
defaultedOptions.queryHash to locate and implement the change.
- Around line 346-362: The generic parameter order for the query() method was
changed so that TQueryData is inserted before TQueryKey, which shifts TQueryKey
from the 4th position and breaks callers that supply explicit generics; restore
backwards compatibility by reordering the type parameters on query<TQueryFnData,
TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey =
QueryKey, TQueryData = TQueryFnData, TPageParam = never> (matching how
fetchQuery previously exposed TQueryKey as the 4th type param) and ensure the
QueryExecuteOptions type usage aligns with that order so existing
explicit-generic call sites do not need an extra type argument.
- Around line 448-469: The third generic TData in infiniteQuery currently
conflicts with fetchInfiniteQuery because TData is used for different meanings
(page data vs selected result), causing unsafe migrations; update
infiniteQuery's signature to introduce a distinct generic for the
select/returned result (e.g. add TSelect = TData or rename the existing generics
so that TData remains the page data type/TQueryFnData output) and keep the
return type built from InfiniteData<TQueryFnData, TPageParam> (or conditional
based on the new TSelect) so callers like infiniteQuery<TQueryFnData, TError,
TData, TQueryKey, TPageParam> still resolve to InfiniteData<TQueryFnData,
TPageParam>; change the type parameter list and the conditional return type in
the infiniteQuery method and update any references to TData inside
InfiniteQueryExecuteOptions to the appropriate new generic (reference symbols:
infiniteQuery, fetchInfiniteQuery, TData, TQueryFnData, InfiniteData,
InfiniteQueryExecuteOptions, TPageParam).
🪄 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: 47b6c09c-48bc-4907-a213-997c33f872bf

📥 Commits

Reviewing files that changed from the base of the PR and between 4082894 and 3fd9db4.

📒 Files selected for processing (5)
  • .changeset/true-cameras-wash.md
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/types.ts

Comment thread .changeset/true-cameras-wash.md Outdated
Comment thread packages/query-core/src/queryClient.ts
Comment thread packages/query-core/src/queryClient.ts
Comment thread packages/query-core/src/queryClient.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/query-core/src/queryClient.ts`:
- Around line 435-436: Update the deprecation JSDoc for the deprecated method to
give a copy-pasteable no-op catch example: replace `.catch(noop)` with a literal
no-op callback like `.catch(() => {})` in the deprecation text that references
using `queryClient.query(options)` (update both occurrences around
`queryClient.query` at the commented locations).
- Around line 142-144: The deprecation comment for
ensureQueryData/ensureInfiniteQueryData must note that queryClient.query({ ...,
staleTime: 'static' }) only implements the "return cached data or fetch"
behavior and does NOT preserve the background refresh that
ensureQueryData/ensureInfiniteQueryData perform when revalidateIfStale is true;
update the deprecation wording to: recommend migrating to queryClient.query({
..., staleTime: 'static' }) for simple cached-or-fetch semantics, and if callers
rely on the background revalidation, instruct them to follow the query call with
an explicit background revalidation (e.g. queryClient.fetchQuery or
queryClient.fetchInfiniteQuery) or an equivalent explicit revalidate step
instead of assuming revalidateIfStale is preserved. Include references to
ensureQueryData, ensureInfiniteQueryData, queryClient.query, revalidateIfStale,
fetchQuery and fetchInfiniteQuery in the note.
🪄 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: 0af20707-a09c-4d31-a931-fba6a2b59452

📥 Commits

Reviewing files that changed from the base of the PR and between 3fd9db4 and e2fa928.

📒 Files selected for processing (5)
  • .changeset/true-cameras-wash.md
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/types.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/true-cameras-wash.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/query-core/src/types.ts
  • packages/query-core/src/tests/queryClient.test-d.tsx
  • packages/query-core/src/tests/queryClient.test.tsx

Comment thread packages/query-core/src/queryClient.ts
Comment thread packages/query-core/src/queryClient.ts
@DogPawHat DogPawHat force-pushed the simplified-query-methods/core branch 2 times, most recently from 3f889bb to 59cacda Compare May 8, 2026 15:27
>,
): Promise<TData> {
const defaultedOptions = this.defaultQueryOptions(options)
const disabledErrorMessage = `Query is disabled and no cached data is available for key: '${defaultedOptions.queryHash}'`
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TkDodo Per your comment here #9835 (comment)

Would the working of this error work?

@DogPawHat DogPawHat force-pushed the simplified-query-methods/core branch from 59cacda to 0a9f91e Compare May 8, 2026 16:48
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
packages/query-core/src/queryClient.ts (2)

346-361: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore TQueryKey as the 4th generic on query().

Line 350 still inserts TQueryData ahead of TQueryKey, so a straight rename from fetchQuery<A, B, C, D> to query<A, B, C, D> binds D to query data instead of the key type. For a replacement API, that’s a breaking migration for explicit-generic call sites. A small dts regression around query<..., StrictQueryKey> would be useful here too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/query-core/src/queryClient.ts` around lines 346 - 361, The generic
parameter order on query(...) is incorrect: restore TQueryKey as the 4th generic
parameter so explicit-generic call sites keep the same bindings (i.e. change the
generic list on function query<TQueryFnData, TError = DefaultError, TData =
TQueryFnData, TQueryKey extends QueryKey = QueryKey, TQueryData = TQueryFnData,
TPageParam = never>), adjust the default for TQueryData accordingly, and update
any usages/types that reference QueryExecuteOptions<TQueryFnData, TError, TData,
TQueryData, TQueryKey, TPageParam> (or vice versa) to match the corrected order;
also add/adjust a small .d.ts regression test demonstrating query<...,
StrictQueryKey> still binds the 4th generic to the key type.

457-475: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Keep the 3rd generic’s meaning aligned with fetchInfiniteQuery().

fetchInfiniteQuery<Foo, Error, Bar, Key, number> returns Promise<InfiniteData<Bar, number>>, but the current infiniteQuery<Foo, Error, Bar, Key, number> signature resolves to Promise<Bar>. That makes the advertised rename unsafe for explicit-generic callers. Please split “page data” from “selected result” with a separate generic instead of reusing TData for both roles.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/query-core/src/queryClient.ts` around lines 457 - 475, The
infiniteQuery signature reuses TData for both "page data" and "selected result",
causing Promise<Bar> instead of Promise<InfiniteData<Bar, number>); change
infiniteQuery's generics to mirror fetchInfiniteQuery by introducing a new
generic (e.g. TSelected or TOutput) distinct from the page-data generic (keep
TQueryFnData and TPageParam) and use that new generic for the method's resolved
Promise type while keeping the page-data generic for InfiniteData<TQueryFnData,
TPageParam>; update the function return type and any related type mappings in
infiniteQuery accordingly so explicit-generic callers get
Promise<InfiniteData<Bar, number>> like fetchInfiniteQuery.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/query-core/src/queryClient.ts`:
- Around line 346-361: The generic parameter order on query(...) is incorrect:
restore TQueryKey as the 4th generic parameter so explicit-generic call sites
keep the same bindings (i.e. change the generic list on function
query<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey
extends QueryKey = QueryKey, TQueryData = TQueryFnData, TPageParam = never>),
adjust the default for TQueryData accordingly, and update any usages/types that
reference QueryExecuteOptions<TQueryFnData, TError, TData, TQueryData,
TQueryKey, TPageParam> (or vice versa) to match the corrected order; also
add/adjust a small .d.ts regression test demonstrating query<...,
StrictQueryKey> still binds the 4th generic to the key type.
- Around line 457-475: The infiniteQuery signature reuses TData for both "page
data" and "selected result", causing Promise<Bar> instead of
Promise<InfiniteData<Bar, number>); change infiniteQuery's generics to mirror
fetchInfiniteQuery by introducing a new generic (e.g. TSelected or TOutput)
distinct from the page-data generic (keep TQueryFnData and TPageParam) and use
that new generic for the method's resolved Promise type while keeping the
page-data generic for InfiniteData<TQueryFnData, TPageParam>; update the
function return type and any related type mappings in infiniteQuery accordingly
so explicit-generic callers get Promise<InfiniteData<Bar, number>> like
fetchInfiniteQuery.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 517f0021-cf70-4ffc-b4fa-40fc1c877f32

📥 Commits

Reviewing files that changed from the base of the PR and between 59cacda and 0a9f91e.

📒 Files selected for processing (5)
  • .changeset/true-cameras-wash.md
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/types.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/true-cameras-wash.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/query-core/src/types.ts
  • packages/query-core/src/tests/queryClient.test.tsx
  • packages/query-core/src/tests/queryClient.test-d.tsx

@DogPawHat DogPawHat force-pushed the simplified-query-methods/core branch 2 times, most recently from 4006613 to 07a10f3 Compare May 9, 2026 22:40
@DogPawHat DogPawHat force-pushed the simplified-query-methods/core branch from 07a10f3 to 5d51700 Compare May 10, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant