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 will be added in follow on PR's
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

    • Imperative query APIs to run queries directly, including infinite-query execution and a static staleTime mode that returns cached results without refetching.
    • New execute options exposing enabled, select, and staleTime controls for runtime query execution.
  • Deprecations

    • Older imperative query methods marked deprecated; guidance added for prefetch-like usage.
  • Tests

    • Expanded coverage for new APIs, typing, caching/static staleTime, enabled/select behavior, and prefetch semantics.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 92e8cc8f-1e50-4a7f-b085-7bfd64806063

📥 Commits

Reviewing files that changed from the base of the PR and between 3f889bb and 59cacda.

📒 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 (4)
  • packages/query-core/src/tests/queryClient.test-d.tsx
  • packages/query-core/src/types.ts
  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/tests/queryClient.test.tsx

📝 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 describes the main change: adding simplified query methods to replace existing ones.
Description check ✅ Passed The description fully covers all required template sections with detailed explanation of changes, completed checklist items, and proper release impact marking.
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.

✏️ 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 3f889bb

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

☁️ Nx Cloud last updated this comment at 2026-05-08 15:33:12 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: 59cacda

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 from e2fa928 to 3f889bb Compare May 8, 2026 15:21
@DogPawHat DogPawHat force-pushed the simplified-query-methods/core branch 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?

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