-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
init query rename and delegation #9835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
init query rename and delegation #9835
Conversation
🦋 Changeset detectedLatest commit: bf15113 The changes in this PR will be included in the next version bump. This PR includes changesets to release 19 packages
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 |
WalkthroughAdds new imperative execute methods Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Caller as Caller
participant QClient as QueryClient
participant Executor as Execute Core
participant Cache as Cache / Network
participant Selector as Select (optional)
Caller->>QClient: query(opts) / infiniteQuery(opts)
QClient->>Executor: delegate(QueryExecuteOptions / InfiniteQueryExecuteOptions)
Executor->>Cache: fetch raw TQueryData or pages
Cache-->>Executor: raw TQueryData or pages
alt select provided
Executor->>Selector: apply select(raw data/pages)
Selector-->>Executor: transformed TData or pages
end
Executor-->>QClient: Promise<TData or InfiniteData>
QClient-->>Caller: resolved data
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 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 |
|
View your CI Pipeline Execution ↗ for commit bf15113
☁️ Nx Cloud last updated this comment at |
sorry the idea was not to rename those, but to add new methods and deprecate the old ones. Otherwise, this would be a breaking change. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #9835 +/- ##
===========================================
+ Coverage 45.89% 59.97% +14.07%
===========================================
Files 200 129 -71
Lines 8437 5671 -2766
Branches 1940 1544 -396
===========================================
- Hits 3872 3401 -471
+ Misses 4116 1964 -2152
+ Partials 449 306 -143 🚀 New features to boost your workflow:
|
b3a20d4 to
46d274c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.changeset/wise-suns-ask.md(1 hunks)packages/query-core/src/__tests__/queryClient.test-d.tsx(2 hunks)packages/query-core/src/__tests__/queryClient.test.tsx(9 hunks)packages/query-core/src/queryClient.ts(6 hunks)packages/vue-query/src/queryClient.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsx
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.
Applied to files:
.changeset/wise-suns-ask.md
🧬 Code graph analysis (4)
packages/query-core/src/__tests__/queryClient.test-d.tsx (3)
packages/query-core/src/types.ts (1)
InfiniteData(204-207)packages/query-core/src/queryClient.ts (1)
infiniteQuery(395-417)packages/vue-query/src/queryClient.ts (1)
infiniteQuery(328-346)
packages/query-core/src/__tests__/queryClient.test.tsx (2)
packages/query-core/src/utils.ts (2)
noop(82-82)sleep(363-367)packages/query-core/src/types.ts (1)
QueryFunction(96-100)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)FetchQueryOptions(491-507)FetchInfiniteQueryOptions(548-565)InfiniteData(204-207)packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
packages/query-core/src/queryClient.ts (2)
packages/query-core/src/utils.ts (1)
noop(82-82)packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)FetchQueryOptions(491-507)FetchInfiniteQueryOptions(548-565)InfiniteData(204-207)
🪛 LanguageTool
.changeset/wise-suns-ask.md
[grammar] ~6-~6: Ensure spelling is correct
Context: ...tanstack/vue-query': minor --- renamed imperitive methods
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (8)
packages/query-core/src/queryClient.ts (5)
140-159: LGTM! ensureQueryData correctly delegates to the new query method.The internal delegation to
querywithstaleTime: 'static'maintains the expected behavior while utilizing the new method.
336-365: Verify alignment with maintainer expectations regarding API migration strategy.Per TkDodo's comment, the original intent was to "add new methods and deprecate the old ones to avoid a breaking change, not to remove/rename them outright." While this implementation maintains backward compatibility by keeping
fetchQueryas a wrapper, please confirm that makingquerythe primary implementation (rather than keepingfetchQueryas primary and addingqueryas an alias) aligns with the team's migration strategy.
384-393: LGTM! prefetchQuery correctly delegates to the new query method.The delegation pattern with
.then(noop).catch(noop)properly maintains the fire-and-forget prefetch behavior.
395-417: LGTM! infiniteQuery implementation is clean and consistent.The method correctly sets the
infiniteQueryBehaviorand delegates to thequerymethod. The type assertion on line 416 is necessary due to the behavior transformation.
436-452: LGTM! prefetchInfiniteQuery correctly delegates to the new infiniteQuery method.The delegation pattern maintains the fire-and-forget prefetch behavior.
packages/query-core/src/__tests__/queryClient.test-d.tsx (1)
313-328: LGTM! Type assertions for new methods are comprehensive and correct.The type checks for
queryandinfiniteQuerymethods properly cover both fully typed and untyped scenarios, maintaining consistency with the existing test structure.Also applies to: 462-477
packages/query-core/src/__tests__/queryClient.test.tsx (1)
11-11: LGTM! Comprehensive test coverage for the new query methods.The test additions are excellent:
- Properly imports
nooputility for prefetch patterns- Marks old test suites with
@deprecatedcomments for clarity- Provides thorough coverage of new
queryandinfiniteQuerymethods including:
- Static staleTime behavior
- Prefetching scenarios
- Type safety validation
- Edge cases (cache hits, invalidation, GC, etc.)
- Maintains parallel structure with legacy tests while validating new functionality
Also applies to: 453-453, 529-620, 622-622, 683-720, 753-753, 928-1100, 1102-1102, 1147-1189, 1191-1191, 1281-1374, 1376-1376, 1426-1477
packages/vue-query/src/queryClient.ts (1)
256-346: LGTM! Vue Query extensions for new methods are well-implemented.The
queryandinfiniteQuerymethods properly:
- Provide overloads for both plain and
MaybeRefDeepoptions- Use
cloneDeepUnrefto handle Vue's reactive refs correctly- Delegate to the parent QueryClient implementation
- Follow the established pattern used by other methods in this class
|
From #9135:
|
c18dfc0 to
7670b40
Compare
| initialPageParam: 1, | ||
| }) | ||
|
|
||
| const data = await new QueryClient().infiniteQuery(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Known type failures here.
as far as I know a select pass into a useInfiniteQuery can transform the data: InfiniteData into whatever (e.g. an Array<>) and that will end up being the data returned from the infinite query*. infiniteQuery should do the same I think, but we've got a big type mismatch here at the moment.
*I suspect this is not the best idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type errors from my local VSCode:
Types of property 'select' are incompatible.
Type '((data: InfiniteData<string, number>) => string[]) | undefined' is not assignable to type '((data: InfiniteData<string, number>) => string) | undefined'.
Type '(data: InfiniteData<string, number>) => string[]' is not assignable to type '(data: InfiniteData<string, number>) => string'.
Type 'string[]' is not assignable to type 'string'.ts(2345)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it works for useInfiniteQuery, it should also work for client.infiniteQuery()
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.changeset/famous-owls-battle.md(1 hunks)packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)packages/query-core/src/__tests__/queryClient.test.tsx(9 hunks)packages/query-core/src/queryClient.ts(8 hunks)packages/query-core/src/types.ts(3 hunks)packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx(3 hunks)packages/react-query/src/__tests__/queryOptions.test-d.tsx(2 hunks)packages/vue-query/src/queryClient.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/react-query/src/tests/queryOptions.test-d.tsx
- packages/react-query/src/tests/infiniteQueryOptions.test-d.tsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsx
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.
Applied to files:
.changeset/famous-owls-battle.md
🧬 Code graph analysis (4)
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
packages/query-core/src/queryClient.ts (1)
infiniteQuery(409-431)packages/query-core/src/types.ts (2)
InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)
packages/query-core/src/queryClient.ts (4)
packages/query-core/src/utils.ts (2)
noop(82-82)resolveStaleTime(101-113)packages/query-core/src/types.ts (7)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)FetchQueryOptions(511-527)InfiniteQueryExecuteOptions(568-586)FetchInfiniteQueryOptions(588-605)InfiniteData(204-207)packages/query-core/src/query.ts (1)
isStale(296-306)packages/vue-query/src/queryClient.ts (1)
query(294-314)
packages/query-core/src/__tests__/queryClient.test.tsx (2)
packages/query-core/src/utils.ts (2)
noop(82-82)sleep(363-367)packages/query-core/src/types.ts (1)
QueryFunction(96-100)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteQueryExecuteOptions(568-586)InfiniteData(204-207)packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
🪛 Biome (2.1.2)
packages/query-core/src/__tests__/queryClient.test-d.tsx
[error] 342-342: Const declarations must have an initialized value.
This variable needs to be initialized.
(parse)
[error] 342-342: Shouldn't redeclare 'infiniteQueryOptions'. Consider to delete it or rename it.
'infiniteQueryOptions' is defined here:
(lint/suspicious/noRedeclare)
[error] 441-441: This variable is used before its declaration.
The variable is declared here:
(lint/correctness/noInvalidUseBeforeDeclaration)
[error] 443-443: Shouldn't redeclare 'infiniteQuery'. Consider to delete it or rename it.
'infiniteQuery' is defined here:
(lint/suspicious/noRedeclare)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (7)
packages/query-core/src/__tests__/queryClient.test-d.tsx (7)
161-172: LGTM!The test correctly verifies that
fetchQuerydoes not accept theselectoption, maintaining backward compatibility as intended in the PR design.
174-227: LGTM!The tests correctly verify:
selectoption is not allowed onfetchInfiniteQuery(backward compatibility)pagesparameter is properly typedgetNextPageParamis required whenpagesis specified
229-239: LGTM!The test correctly verifies that the new
querymethod accepts theselectoption, which is the key differentiator from thefetchQuerycompatibility wrapper.
242-257: Verify whetherselectshould be allowed oninfiniteQuery.This test asserts that
selectis not allowed oninfiniteQuery, but:
- Lines 336-339 show
InfiniteQueryExecuteOptionsbeing used with aselectoption successfully- Unlike the
fetchInfiniteQuerytest (line 183), there's no@ts-expect-errorannotation on theselectproperty (line 249)Based on the implementation where
infiniteQuerydelegates toquery(which supports select), it appearsselectshould be allowed. Please clarify the intended behavior and add the@ts-expect-errorannotation if select is truly not supported, or update the test description if it is supported.
428-429: LGTM!The type check correctly verifies that
queryreturns the expectedTDatatype.
578-579: LGTM!The type check correctly verifies that
queryreturnsunknownwhen called with untyped options.
583-593: LGTM!The type checks correctly verify the return types for
fetchInfiniteQueryandinfiniteQuerywith untyped options, both returningInfiniteData<unknown, unknown>.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.changeset/famous-owls-battle.md(1 hunks)packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .changeset/famous-owls-battle.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsx
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (3)
packages/query-core/src/queryClient.ts (2)
QueryClient(63-692)infiniteQuery(409-431)packages/vue-query/src/queryClient.ts (2)
QueryClient(39-589)infiniteQuery(348-366)packages/query-core/src/types.ts (2)
InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Preview
- GitHub Check: Test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.049Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsx
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsx
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
packages/query-core/src/queryClient.ts (1)
infiniteQuery(409-431)packages/query-core/src/types.ts (2)
InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
🔇 Additional comments (5)
packages/query-core/src/__tests__/queryClient.test-d.tsx (5)
13-13: LGTM!The addition of
InfiniteQueryExecuteOptionsto the imports aligns with the new public API surface introduced in this PR.
161-172: LGTM!This test correctly validates that the legacy
fetchQuerymethod does not support theselectoption, with proper use of@ts-expect-errorto enforce the type constraint.
174-227: LGTM!The tests for
fetchInfiniteQuerycorrectly validate the legacy behavior, including:
- Properly rejecting
selectoption with@ts-expect-error- Validating the
pagesoption with correct type expectations- Enforcing required parameter constraints
229-239: LGTM!This test correctly validates that the new
querymethod supports theselectoption for data transformation, properly demonstrating the enhanced functionality compared to the legacyfetchQuery.
328-336: LGTM!The integration of the new
queryandinfiniteQuerymethods into the fully-typed and untyped test sections is correct:
- Proper usage of
InfiniteQueryExecuteOptions<TData, TError>type- Correct type expectations for return values
- Good coverage of both typed and untyped variants
Also applies to: 422-423, 434-435, 569-570, 581-584
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
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/__tests__/queryClient.test-d.tsx (1)
205-214: Fix misleading test title.The test uses
assertTypewithout@ts-expect-error, meaning it's verifying that passinggetNextPageParamwithoutpagesis allowed (per theInfiniteQueryPagesunion's{ pages?: never }branch). The title incorrectly says "should not allow".Apply this diff:
- it('should not allow passing getNextPageParam without pages', () => { + it('should allow passing getNextPageParam without pages', () => {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)packages/query-core/src/types.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.049Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/types.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/types.ts
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
packages/query-core/src/queryClient.ts (1)
infiniteQuery(409-431)packages/query-core/src/types.ts (2)
InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
🔇 Additional comments (7)
packages/query-core/src/types.ts (3)
491-509: LGTM: QueryExecuteOptions introduces select support correctly.The new
QueryExecuteOptionsinterface properly introduces theselecttransformation flow via theTQueryDatageneric. The data flows asTQueryFnData(raw) →TQueryData(intermediate) →TData(final via select). ThestaleTimecorrectly usesTQueryDatasince staleness should be determined from the query's stored data, not the transformed result.
511-528: LGTM: FetchQueryOptions maintains backward compatibility.The refactor to make
FetchQueryOptionsan alias that omitsselectfromQueryExecuteOptionsis correct. PassingTDataas both the 3rd and 4th generics (TData, TData) ensures no transformation layer exists whenselectis omitted, maintaining the original behavior offetchQuery.
568-586: LGTM: InfiniteQueryExecuteOptions properly extends execute options.The type correctly:
- Omits
initialPageParamfromQueryExecuteOptions(which hasinitialPageParam?: never)- Re-adds it via
InitialPageParam<TPageParam>with the proper type- Uses
InfiniteData<TQueryFnData, TPageParam>as the intermediate data shape- Includes
InfiniteQueryPagesdiscriminated union to enforce the pages/getNextPageParam constraintpackages/query-core/src/__tests__/queryClient.test-d.tsx (4)
161-172: LGTM: Correctly verifies fetchQuery rejects select.The test properly uses
@ts-expect-errorto confirm that the legacyfetchQuerymethod does not support theselectoption, maintaining backward compatibility.Based on learnings.
229-239: LGTM: Correctly verifies query accepts select.The test confirms that the new
querymethod supports theselectoption for data transformation, usingassertType(without@ts-expect-error) to validate this is allowed.Based on learnings.
241-257: LGTM: Correctly verifies infiniteQuery accepts select.The test confirms that the new
infiniteQuerymethod supports theselectoption for transforming infinite query data, usingassertType(without@ts-expect-error) to validate this is allowed.Based on learnings.
328-336: LGTM: infiniteQueryOptions properly typed.The variable correctly uses
InfiniteQueryExecuteOptions<TData, TError>with defaults for remaining generics. ThegetNextPageParamcallback properly receiveslastPagetyped asTData.
| const cachedData = query.state.data | ||
|
|
||
| if (cachedData === undefined) { | ||
| return this.fetchQuery(options) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get why this was removed (because staleTime: 'static' achieves the same thing), however, background refetching with revalidateIfStale was never triggered if we had no data in the cache, and right now, it’s the first thing that happens.
I guess it’s mostly fine because query.fetch will dedupe promises, but there is the edge-case where users pass cancelRefetch which would lead to to the first fetch being cancelled.
Not sure what a good way out here would be, except maybe not re-implement ensureQueryData with this.query rather than keep the current implementation ?
also since query now supports select, these functions also do transformation in case you’ve passed excess properties!
I think what we should do is leave ensureQueryData, fetchQuery and prefetchQuery alone for now and NOT have them call .query or .infiniteQuery under the hood.
| return basePromise.then((data) => select(data)) | ||
| } | ||
|
|
||
| return basePromise.then((data) => data as unknown as TData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure why this is necessary :/
| initialPageParam: 1, | ||
| }) | ||
|
|
||
| const data = await new QueryClient().infiniteQuery(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it works for useInfiniteQuery, it should also work for client.infiniteQuery()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/query-core/src/queryClient.ts (1)
428-450: Implementation delegates correctly, but consider type-safe alternatives to the cast.The method properly sets
infiniteQueryBehaviorbefore delegating toquery. Theas anycast on line 449 bypasses type safety—consider whether tighter generic constraints or a helper could eliminate it.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/query-core/src/queryClient.ts(5 hunks)packages/query-core/src/types.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/query-core/src/types.tspackages/query-core/src/queryClient.ts
🧬 Code graph analysis (1)
packages/query-core/src/queryClient.ts (3)
packages/query-core/src/types.ts (6)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteQueryExecuteOptions(568-586)FetchInfiniteQueryOptions(588-605)InfiniteData(204-207)packages/vue-query/src/queryClient.ts (1)
query(294-314)packages/query-core/src/utils.ts (1)
resolveStaleTime(101-113)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (4)
packages/query-core/src/types.ts (2)
491-509: LGTM! Well-designed interface for query execution options.The interface correctly separates
TQueryDatafromTDatato enable optionalselecttransformation, explicitly preventsinitialPageParamfor single queries, and provides clear documentation forstaleTimebehavior.
561-586: LGTM! Clean type composition for infinite query execution.The discriminated union for
InfiniteQueryPagesand the composition strategy forInfiniteQueryExecuteOptions(omitting theneverfield then adding the required version) correctly enforces that infinite queries must provideinitialPageParam.packages/query-core/src/queryClient.ts (2)
343-384: LGTM! Core query execution logic is sound.The method correctly handles stale-time checking, optional data fetching, and select transformation. The double cast
as unknown as TDataon line 383 is a TypeScript workaround when no select is provided (TData defaults to TQueryData), though it's safe in practice.
452-468: Fix: Missingoptions.behaviorsetup before delegation tofetchQuery.The
fetchInfiniteQuerymethod must setoptions.behaviorbefore delegating tofetchQuery, matching the pattern used ininfiniteQuery(lines 443-448) andensureInfiniteQueryData(lines 503-508). Without this, infinite query pagination will not work correctly.fetchInfiniteQuery< TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown, >( options: FetchInfiniteQueryOptions< TQueryFnData, TError, TData, TQueryKey, TPageParam >, ): Promise<InfiniteData<TData, TPageParam>> { + options.behavior = infiniteQueryBehavior< + TQueryFnData, + TError, + TData, + TPageParam + >(options.pages) return this.fetchQuery(options as any) }⛔ Skipped due to learnings
Learnt from: DogPawHat Repo: TanStack/query PR: 9835 File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256 Timestamp: 2025-11-02T22:52:33.071Z Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
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)
428-450: Fix the type error and avoidas anyassertion.Two issues need to be addressed:
Pipeline failure (Line 443): The type error indicates that
QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, readonly unknown[]>is not assignable toQueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>. This suggests a mismatch in the query key type constraint.Line 449: The
as anytype assertion bypasses type safety and hides potential type errors. This indicates that the types don't align properly betweenInfiniteQueryExecuteOptionsandQueryExecuteOptions.The type system should properly model the relationship between these option types without requiring unsafe casts. Please investigate:
- Whether the
QueryExecuteOptionstype needs to be adjusted to properly accept infinite query options- Whether the generic constraints need to be refined to make the types compatible
- Alternative approaches that maintain type safety
#!/bin/bash # Check how behavior property is typed and used ast-grep --pattern $'behavior: QueryBehavior<$$$>'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/query-core/src/queryClient.ts(5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/query-core/src/queryClient.ts
🧬 Code graph analysis (1)
packages/query-core/src/queryClient.ts (3)
packages/query-core/src/types.ts (6)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteQueryExecuteOptions(568-586)FetchInfiniteQueryOptions(588-605)InfiniteData(204-207)packages/vue-query/src/queryClient.ts (1)
query(294-314)packages/query-core/src/utils.ts (1)
resolveStaleTime(101-113)
🪛 GitHub Actions: PR
packages/query-core/src/queryClient.ts
[error] 443-443: Type 'QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, readonly unknown[]>' is not assignable to type 'QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>'.
🔇 Additional comments (2)
packages/query-core/src/queryClient.ts (2)
28-28: LGTM!The new type imports support the
queryandinfiniteQuerymethod signatures correctly.Also applies to: 37-37
373-383: Verify data handling assumptions in the query method implementation.The technical concerns in the review are valid: when
isStaleis false,query.state.datacould beundefined(initialized withoutinitialData), and this would be passed to theselectfunction without a guard. The type signatureselect?: (data: TQueryData) => TDataexpects defined data, but the cast on line 375 (as TQueryData) doesn't guarantee it at runtime.However, test cases across the codebase show
selectalways receives properly typed, defined data—no scenario in tests passesundefinedto the selector. This suggests either:
- The scenario is prevented by caller contracts (e.g., always providing
initialDataor ensuring fetch completes first)- The stale-time logic prevents
isStale=falsewhen data is undefined- This is an edge case not covered by tests
Confirm whether adding a guard (e.g.,
if (!queryData) return queryData as TData) is necessary, or if the current design intentionally relies on caller responsibility to provide valid initial state.
| fetchInfiniteQuery< | ||
| TQueryFnData, | ||
| TError = DefaultError, | ||
| TData = TQueryFnData, | ||
| TQueryKey extends QueryKey = QueryKey, | ||
| TPageParam = unknown, | ||
| >( | ||
| options: FetchInfiniteQueryOptions< | ||
| TQueryFnData, | ||
| TError, | ||
| TData, | ||
| TQueryKey, | ||
| TPageParam | ||
| >, | ||
| ): Promise<InfiniteData<TData, TPageParam>> { | ||
| return this.fetchQuery(options as any) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Avoid as any type assertion.
Line 467 uses as any when delegating to fetchQuery, which bypasses type safety. While this maintains the existing delegation pattern (based on past review comments indicating fetchInfiniteQuery should call fetchQuery), the type assertion suggests that FetchInfiniteQueryOptions and FetchQueryOptions aren't properly aligned.
Consider:
- Ensuring
FetchInfiniteQueryOptionsproperly extends or is compatible withFetchQueryOptionsso no cast is needed - Adding an internal helper that both methods can safely delegate to without type assertions
- If the cast is unavoidable due to the type structure, document why it's safe with a comment
#!/bin/bash
# Check the relationship between FetchInfiniteQueryOptions and FetchQueryOptions
ast-grep --pattern $'export type FetchInfiniteQueryOptions<$$$> = $$$'🤖 Prompt for AI Agents
In packages/query-core/src/queryClient.ts around lines 452 to 468, the
fetchInfiniteQuery implementation uses "as any" to call fetchQuery which
bypasses type safety; fix by ensuring FetchInfiniteQueryOptions is compatible
with FetchQueryOptions (update its declaration to extend or intersect the
FetchQueryOptions generic shape), or extract a private internal typed helper
that both fetchQuery and fetchInfiniteQuery call (with appropriate generic
bounds) so no cast is needed; if a cast is truly unavoidable due to type
constraints, replace "as any" with a narrower, justified cast and add a brief
comment explaining why the cast is safe.
1338e8e to
8c46d9e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/query-core/src/queryClient.ts (1)
428-452: Restore infiniteQueryBehavior wiring for fetchInfiniteQuery and reduceas anysurfaceCurrently, only
infiniteQueryandensureInfiniteQueryDataattachinfiniteQueryBehavior, whilefetchInfiniteQuerynow delegates straight tofetchQuerywithout settingoptions.behavior:fetchInfiniteQuery(...) { return this.fetchQuery(options as any) }In the published build,
fetchInfiniteQuerysetsoptions.behavior = infiniteQueryBehavior(options.pages)before callingfetchQuery, which is what gives it proper infinite paging semantics (usingpages,pageParams, andgetNextPageParam). (impactic.de) Dropping that here likely breaks existingfetchInfiniteQuerybehavior and will make tests like “should return infinite query data”/“should prefetch multiple pages” incorrect at runtime.I’d strongly suggest restoring the behavior setup, e.g.:
fetchInfiniteQuery< TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown, >( options: FetchInfiniteQueryOptions< TQueryFnData, TError, TData, TQueryKey, TPageParam >, ): Promise<InfiniteData<TData, TPageParam>> { options.behavior = infiniteQueryBehavior< TQueryFnData, TError, TData, TPageParam >(options.pages) return this.fetchQuery(options as any) }On top of that, the three
as anycasts (this.query(options as any),this.fetchQuery(options as any),this.ensureQueryData(options as any)) are understandable given the generic differences between execute/fetch option types, but they do punch a hole through type safety. If feasible, consider a small internal helper or tightening the generic relationships betweenQueryExecuteOptions,InfiniteQueryExecuteOptions,FetchQueryOptions, andFetchInfiniteQueryOptionsso these calls can be expressed withoutany(or at least with a narrower cast and a brief comment on why it’s safe).Also applies to: 470-486, 488-511
🧹 Nitpick comments (1)
packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (1)
53-66: Type tests correctly encode select behavior for infinite pathsThe new tests nicely capture the intended distinctions:
useInfiniteQuery,useSuspenseInfiniteQuery, andQueryClient.infiniteQueryall seeselectand return the transformedArray<string>type.fetchInfiniteQuerystill yieldsInfiniteData<string, number>even when given options that includeselect, matching the legacy “no select” behavior for fetch APIs.Only tiny nit: the “known issue” comment in the suspense test still mentions
useInfiniteQuery, but that’s cosmetic.Also applies to: 79-92, 93-117, 130-142
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.changeset/famous-owls-battle.md(1 hunks)packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)packages/query-core/src/__tests__/queryClient.test.tsx(9 hunks)packages/query-core/src/queryClient.ts(5 hunks)packages/query-core/src/types.ts(3 hunks)packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx(3 hunks)packages/react-query/src/__tests__/queryOptions.test-d.tsx(2 hunks)packages/vue-query/src/queryClient.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .changeset/famous-owls-battle.md
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Applied to files:
packages/react-query/src/__tests__/queryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/queryClient.tspackages/vue-query/src/queryClient.ts
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/react-query/src/__tests__/queryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/queryClient.tspackages/vue-query/src/queryClient.tspackages/query-core/src/types.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/react-query/src/__tests__/queryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsxpackages/query-core/src/queryClient.ts
🧬 Code graph analysis (3)
packages/query-core/src/__tests__/queryClient.test-d.tsx (1)
packages/query-core/src/types.ts (2)
InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)
packages/query-core/src/queryClient.ts (2)
packages/query-core/src/types.ts (6)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteQueryExecuteOptions(568-586)FetchInfiniteQueryOptions(588-605)InfiniteData(204-207)packages/query-core/src/utils.ts (1)
resolveStaleTime(112-124)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteQueryExecuteOptions(568-586)InfiniteData(204-207)packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (8)
packages/query-core/src/types.ts (1)
491-509: New execute option types align well with observer options and infinite semantics
QueryExecuteOptionsandInfiniteQueryExecuteOptionsare wired correctly: usingTQueryDataforstaleTimeandselectmatches howdefaultQueryOptionsandresolveStaleTimeoperate, andInfiniteQueryPagescleanly enforces thepages/getNextPageParampairing while being reused by both execute and fetch infinite options. This should givequery/infiniteQuerythe right type-level behavior without impacting existingFetch*callers.Also applies to: 561-587, 588-605
packages/react-query/src/__tests__/queryOptions.test-d.tsx (1)
58-66: query vs fetchQuery select behavior is well coveredThe added tests clearly distinguish the new
queryAPI (including select transformations) from the legacyfetchQuery(which returns the rawnumbereven when given options that containselect). This matches the intended separation between the new and old imperative entry points.Also applies to: 76-95
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
161-172: Type tests cleanly separate select support between legacy and new APIsThe new blocks for
fetchQuery,fetchInfiniteQuery,query, andinfiniteQuerycorrectly encode the contract:
fetchQuery/fetchInfiniteQueryrejectselectat the option level via@ts-expect-error.query/infiniteQueryacceptselectand assert the transformed data types.This gives solid type-level coverage for the migration story from the old fetch* APIs to the new imperative methods.
Also applies to: 175-192, 229-257
193-203: Infinite execute/fetch options generics are exercised thoroughlyThe updated tests around passing
pages, using{ count: number }pages, and the “fully typed usage” blocks validate that:
FetchInfiniteQueryOptionsandInfiniteQueryExecuteOptionsexposelastPageasTDataingetNextPageParam.infiniteQueryandfetchInfiniteQueryboth resolve toInfiniteData<TData, TPageParam>(orInfiniteData<unknown, unknown>in the untyped case).This gives good confidence that the new infinite-execute types integrate correctly with
QueryClient’s generics.Also applies to: 259-269, 328-337, 422-435, 569-585
packages/query-core/src/__tests__/queryClient.test.tsx (2)
529-620: Static staleTime behavior for query/infiniteQuery is well specifiedThe new “with static staleTime” suites for both
queryandinfiniteQueryclearly pin down the behavior:
- Cached data (including falsy values) is returned without re-fetching when staleTime is
'static'.- Missing queries invoke
queryFnonce.- Providing
initialDatashort-circuits network calls.- A second call with
staleTime: 0drives an explicit background revalidation, as verified vianoopand cache assertions.This is a strong regression suite for the new imperative surface.
Also applies to: 683-720
928-1106: Runtime tests give good confidence in new query/infiniteQuery entry pointsThe added
query/infiniteQuerysuites (including “used for prefetching”) thoroughly mirror the legacyfetchQuery/prefetch*behavior:
- No-retry-by-default semantics, gcTime handling, and static staleTime cache hits are preserved.
- Infinite flows still produce the expected
InfiniteDatashapes, including multi-page prefetch and early termination viagetNextPageParam.- Prefetch-style usages (
.catch(noop)) ensure that usingquery/infiniteQuerypurely for seeding the cache continues to work.Overall, the tests look well aligned with the intended migration path from the deprecated fetch* methods to the new APIs.
Also applies to: 1153-1195, 1287-1380, 1432-1483
packages/vue-query/src/queryClient.ts (1)
19-37: Vue QueryClient query/infiniteQuery wrappers are consistent and type-safeThe new
queryandinfiniteQueryoverloads:
- Reuse the core
QueryExecuteOptions/InfiniteQueryExecuteOptionsgenerics correctly.- Preserve the Vue adapter’s
MaybeRefDeep+cloneDeepUnrefpattern so refs and getter-basedqueryKeys are handled before delegating.- Return the expected
Promise<TData>/Promise<InfiniteData<TData, TPageParam>>types, matching the core client.This keeps the Vue surface in lockstep with the new imperative APIs.
Also applies to: 258-366
packages/query-core/src/queryClient.ts (1)
343-384: query implementation correctly layers select on top of legacy fetch semanticsThe new
querymethod:
- Runs through
defaultQueryOptions, preserves the “no retry by default” behavior fromfetchQuery, and usesresolveStaleTimewithQueryExecuteOptions.staleTimetyped onTQueryData.- Fetches when
isStaleByTimeis true, otherwise returnsquery.state.datafrom cache.- Applies
selectonce, purely at the imperative layer, without mutating the stored query data.This matches the intended contract for the new imperative API and is well covered by the added runtime and type tests.
There was a problem hiding this 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
♻️ Duplicate comments (1)
packages/query-core/src/queryClient.ts (1)
428-454: Type assertion bypasses type safety.Line 453 uses
as anywhen delegating tothis.query, which bypasses TypeScript's type checking. While this mirrors the existing pattern infetchInfiniteQuery(Line 477), the cast suggests thatInfiniteQueryExecuteOptionsandQueryExecuteOptionsaren't properly aligned.Consider refactoring to eliminate the cast by:
- Ensuring type compatibility between the two option types
- Extracting a shared internal helper that both methods can call with appropriate generic bounds
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/query-core/src/queryClient.ts(4 hunks)packages/query-core/src/types.ts(3 hunks)packages/vue-query/src/queryClient.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/query-core/src/queryClient.tspackages/query-core/src/types.tspackages/vue-query/src/queryClient.ts
📚 Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Applied to files:
packages/query-core/src/queryClient.tspackages/vue-query/src/queryClient.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/queryClient.ts
🧬 Code graph analysis (1)
packages/query-core/src/queryClient.ts (4)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)packages/query-core/src/query.ts (1)
isStale(296-306)packages/query-core/src/utils.ts (1)
resolveStaleTime(112-124)packages/query-core/src/infiniteQueryBehavior.ts (1)
infiniteQueryBehavior(11-133)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Preview
- GitHub Check: Test
🔇 Additional comments (2)
packages/query-core/src/queryClient.ts (1)
343-384: LGTM! The query method logic is sound.The implementation correctly:
- Defaults retry to
false(matchingfetchQuerybehavior)- Checks staleness via
resolveStaleTime- Fetches when stale or returns cached data
- Applies
selecttransformation when providedThe double cast at Line 383 (
as unknown as TData) is safe given thatTDatadefaults toTQueryDatawhenselectis not provided, though it's overly defensive.Based on learnings, the new
querymethod correctly supports theselectoption for data transformation.packages/query-core/src/types.ts (1)
491-509: LGTM! Type definitions are well-structured.The new type definitions are correctly designed:
QueryExecuteOptions(491-509): Properly extendsQueryOptionswith requiredqueryKey, addsselectfor data transformation, and includesstaleTimefor staleness controlInfiniteQueryPages(561-566): Clean discriminated union that allows optional pages specification or requiresgetNextPageParamwhen pages are specifiedInfiniteQueryExecuteOptions(568-586): Well-composed type combiningQueryExecuteOptions,InitialPageParam, andInfiniteQueryPagesFetchInfiniteQueryOptions(605): Updated to reuseInfiniteQueryPages, improving consistencyBased on learnings, the new types correctly support the
selectoption for data transformation inqueryandinfiniteQuerymethods.Also applies to: 561-586, 605-605
| query< | ||
| TQueryFnData, | ||
| TError = DefaultError, | ||
| TData = TQueryFnData, | ||
| TQueryData = TQueryFnData, | ||
| TQueryKey extends QueryKey = QueryKey, | ||
| TPageParam = never, | ||
| >( | ||
| options: MaybeRefDeep< | ||
| QueryExecuteOptions< | ||
| TQueryFnData, | ||
| TError, | ||
| TData, | ||
| TQueryData, | ||
| TQueryKey, | ||
| TPageParam | ||
| > | ||
| >, | ||
| ): Promise<TData> | ||
| query< | ||
| TQueryFnData, | ||
| TError = DefaultError, | ||
| TData = TQueryFnData, | ||
| TQueryData = TQueryFnData, | ||
| TQueryKey extends QueryKey = QueryKey, | ||
| TPageParam = never, | ||
| >( | ||
| options: MaybeRefDeep< | ||
| QueryExecuteOptions< | ||
| TQueryFnData, | ||
| TError, | ||
| TData, | ||
| TQueryData, | ||
| TQueryKey, | ||
| TPageParam | ||
| > | ||
| >, | ||
| ): Promise<TData> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicate overload.
The second and third overloads for the query method (Lines 275-293 and 294-312) are identical—they have the same generic parameters, option type, and return type. TypeScript does not allow duplicate overload signatures.
Remove one of the duplicate overloads:
): Promise<TData>
query<
TQueryFnData,
TError = DefaultError,
TData = TQueryFnData,
TQueryData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
TPageParam = never,
>(
options: MaybeRefDeep<
QueryExecuteOptions<
TQueryFnData,
TError,
TData,
TQueryData,
TQueryKey,
TPageParam
>
>,
): Promise<TData>
- query<
- TQueryFnData,
- TError = DefaultError,
- TData = TQueryFnData,
- TQueryData = TQueryFnData,
- TQueryKey extends QueryKey = QueryKey,
- TPageParam = never,
- >(
- options: MaybeRefDeep<
- QueryExecuteOptions<
- TQueryFnData,
- TError,
- TData,
- TQueryData,
- TQueryKey,
- TPageParam
- >
- >,
- ): Promise<TData> {
+ query<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = never>(options: MaybeRefDeep<QueryExecuteOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey, TPageParam>>): Promise<TData> {
return super.query(cloneDeepUnref(options))
}🤖 Prompt for AI Agents
packages/vue-query/src/queryClient.ts around lines 275 to 312: there are
duplicate overload signatures for the query method (the overloads covering lines
275-293 and 294-312 are identical), which causes a TypeScript duplicate overload
error; remove one of the identical overload declarations so only a single
overload (followed by the implementation) remains, ensuring generics, parameter
types, and return type are preserved exactly in the kept signature.
| infiniteQuery< | ||
| TQueryFnData, | ||
| TError = DefaultError, | ||
| TData = InfiniteData<TQueryFnData>, | ||
| TQueryKey extends QueryKey = QueryKey, | ||
| TPageParam = unknown, | ||
| >( | ||
| options: MaybeRefDeep< | ||
| InfiniteQueryExecuteOptions< | ||
| TQueryFnData, | ||
| TError, | ||
| TData, | ||
| TQueryKey, | ||
| TPageParam | ||
| > | ||
| >, | ||
| ): Promise< | ||
| Array<TData> extends Array<InfiniteData<TQueryFnData>> | ||
| ? InfiniteData<TQueryFnData, TPageParam> | ||
| : TData | ||
| > | ||
| infiniteQuery< | ||
| TQueryFnData, | ||
| TError = DefaultError, | ||
| TData = InfiniteData<TQueryFnData>, | ||
| TQueryKey extends QueryKey = QueryKey, | ||
| TPageParam = unknown, | ||
| >( | ||
| options: MaybeRefDeep< | ||
| InfiniteQueryExecuteOptions< | ||
| TQueryFnData, | ||
| TError, | ||
| TData, | ||
| TQueryKey, | ||
| TPageParam | ||
| > | ||
| >, | ||
| ): Promise< | ||
| Array<TData> extends Array<InfiniteData<TQueryFnData>> | ||
| ? InfiniteData<TQueryFnData, TPageParam> | ||
| : TData | ||
| > { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicate overload.
The second and third overloads for the infiniteQuery method (Lines 335-355 and 356-376) are identical. This is the same duplication issue as the query method.
Remove one of the duplicate overloads:
>
infiniteQuery<
TQueryFnData,
TError = DefaultError,
TData = InfiniteData<TQueryFnData>,
TQueryKey extends QueryKey = QueryKey,
TPageParam = unknown,
>(
options: MaybeRefDeep<
InfiniteQueryExecuteOptions<
TQueryFnData,
TError,
TData,
TQueryKey,
TPageParam
>
>,
): Promise<
Array<TData> extends Array<InfiniteData<TQueryFnData>>
? InfiniteData<TQueryFnData, TPageParam>
: TData
>
- infiniteQuery<
- TQueryFnData,
- TError = DefaultError,
- TData = InfiniteData<TQueryFnData>,
- TQueryKey extends QueryKey = QueryKey,
- TPageParam = unknown,
- >(
- options: MaybeRefDeep<
- InfiniteQueryExecuteOptions<
- TQueryFnData,
- TError,
- TData,
- TQueryKey,
- TPageParam
- >
- >,
- ): Promise<
- Array<TData> extends Array<InfiniteData<TQueryFnData>>
- ? InfiniteData<TQueryFnData, TPageParam>
- : TData
- > {
+ infiniteQuery<TQueryFnData, TError = DefaultError, TData = InfiniteData<TQueryFnData>, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(options: MaybeRefDeep<InfiniteQueryExecuteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>): Promise<Array<TData> extends Array<InfiniteData<TQueryFnData>> ? InfiniteData<TQueryFnData, TPageParam> : TData> {
return super.infiniteQuery(cloneDeepUnref(options))
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| infiniteQuery< | |
| TQueryFnData, | |
| TError = DefaultError, | |
| TData = InfiniteData<TQueryFnData>, | |
| TQueryKey extends QueryKey = QueryKey, | |
| TPageParam = unknown, | |
| >( | |
| options: MaybeRefDeep< | |
| InfiniteQueryExecuteOptions< | |
| TQueryFnData, | |
| TError, | |
| TData, | |
| TQueryKey, | |
| TPageParam | |
| > | |
| >, | |
| ): Promise< | |
| Array<TData> extends Array<InfiniteData<TQueryFnData>> | |
| ? InfiniteData<TQueryFnData, TPageParam> | |
| : TData | |
| > | |
| infiniteQuery< | |
| TQueryFnData, | |
| TError = DefaultError, | |
| TData = InfiniteData<TQueryFnData>, | |
| TQueryKey extends QueryKey = QueryKey, | |
| TPageParam = unknown, | |
| >( | |
| options: MaybeRefDeep< | |
| InfiniteQueryExecuteOptions< | |
| TQueryFnData, | |
| TError, | |
| TData, | |
| TQueryKey, | |
| TPageParam | |
| > | |
| >, | |
| ): Promise< | |
| Array<TData> extends Array<InfiniteData<TQueryFnData>> | |
| ? InfiniteData<TQueryFnData, TPageParam> | |
| : TData | |
| > { | |
| infiniteQuery< | |
| TQueryFnData, | |
| TError = DefaultError, | |
| TData = InfiniteData<TQueryFnData>, | |
| TQueryKey extends QueryKey = QueryKey, | |
| TPageParam = unknown, | |
| >( | |
| options: MaybeRefDeep< | |
| InfiniteQueryExecuteOptions< | |
| TQueryFnData, | |
| TError, | |
| TData, | |
| TQueryKey, | |
| TPageParam | |
| > | |
| >, | |
| ): Promise< | |
| Array<TData> extends Array<InfiniteData<TQueryFnData>> | |
| ? InfiniteData<TQueryFnData, TPageParam> | |
| : TData | |
| > { | |
| return super.infiniteQuery(cloneDeepUnref(options)) | |
| } |
🤖 Prompt for AI Agents
In packages/vue-query/src/queryClient.ts around lines 335 to 376, there are two
identical overload declarations for the infiniteQuery method; remove one of the
duplicate overload blocks (either the second or third of the two identical
signatures) so only a single overload remains before the implementation, then
run TypeScript type-check/build and tests to confirm no signature regressions.
| TQueryFnData, | ||
| TError = DefaultError, | ||
| TData = TQueryFnData, | ||
| TData = InfiniteData<TQueryFnData>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to match the options used by react query queryOptions but not InfiniteQueryObserverOptions in query-core types.ts.
be836cd to
bf15113
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/query-core/src/queryClient.ts (1)
471-477: Sameas anypattern infetchInfiniteQuery.This follows the same pattern as
infiniteQuery. Consistent with past review feedback, the cast exists due to type structure differences.
🧹 Nitpick comments (1)
packages/query-core/src/queryClient.ts (1)
447-453: Theas anycast bypasses type checking.The
infiniteQuerymethod usesas anywhen delegating tothis.query(). This is flagged as a concern in past reviews. While necessary due to the type complexity betweenInfiniteQueryExecuteOptionsandQueryExecuteOptions, it could mask type errors.Consider adding a brief inline comment explaining why the cast is safe:
options.behavior = infiniteQueryBehavior< TQueryFnData, TError, TQueryFnData, TPageParam >(options.pages) + // Cast is safe: InfiniteQueryExecuteOptions extends QueryExecuteOptions with infinite-specific fields return this.query(options as any)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.changeset/famous-owls-battle.md(1 hunks)packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)packages/query-core/src/__tests__/queryClient.test.tsx(9 hunks)packages/query-core/src/queryClient.ts(4 hunks)packages/query-core/src/types.ts(3 hunks)packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx(3 hunks)packages/react-query/src/__tests__/queryOptions.test-d.tsx(2 hunks)packages/vue-query/src/queryClient.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- .changeset/famous-owls-battle.md
- packages/react-query/src/tests/queryOptions.test-d.tsx
- packages/react-query/src/tests/infiniteQueryOptions.test-d.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Applied to files:
packages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/queryClient.tspackages/vue-query/src/queryClient.ts
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
packages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/queryClient.tspackages/query-core/src/types.tspackages/vue-query/src/queryClient.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/queryClient.ts
🧬 Code graph analysis (4)
packages/query-core/src/__tests__/queryClient.test.tsx (1)
packages/query-core/src/utils.ts (2)
noop(93-93)sleep(374-378)
packages/query-core/src/__tests__/queryClient.test-d.tsx (1)
packages/query-core/src/types.ts (2)
InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)
packages/query-core/src/queryClient.ts (4)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)packages/query-core/src/query.ts (1)
isStale(296-306)packages/query-core/src/utils.ts (1)
resolveStaleTime(112-124)packages/query-core/src/infiniteQueryBehavior.ts (1)
infiniteQueryBehavior(11-133)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (16)
packages/query-core/src/__tests__/queryClient.test-d.tsx (5)
161-172: LGTM — Correctly verifiesselectis rejected forfetchQuery.The
@ts-expect-errormarker ensures TypeScript will flag ifselectbecomes allowed onfetchQuery, maintaining the intended API distinction between legacy and new methods.
229-239: LGTM — Type test validatesqueryacceptsselect.This correctly verifies the new
querymethod supports theselectoption for data transformation, distinguishing it from the legacyfetchQuery. Based on learnings, this aligns with the intended API design.
241-257: LGTM — Type test validatesinfiniteQueryacceptsselect.Correctly verifies that
infiniteQuerysupports theselectoption for transformingInfiniteData, aligning with the new API surface documented in learnings.
328-336: LGTM — Correctly usesInfiniteQueryExecuteOptionsfor typed scenarios.The type test properly exercises the new
InfiniteQueryExecuteOptionsinterface with explicitTDataandTErrorgenerics, validating the public API surface.
422-424: LGTM — Tests for newqueryandinfiniteQuerymethods with typed options.Type assertions correctly verify that both new methods return the expected types when used with fully-typed options.
Also applies to: 434-435
packages/query-core/src/__tests__/queryClient.test.tsx (5)
11-11: LGTM —noopis correctly imported from the public API.This validates that
noopis now part of the public API surface as intended by the PR.
529-620: Comprehensive test coverage forquerywith static staleTime.Tests correctly cover:
- Cache hit scenarios (lines 530-544, 546-560)
- Cache miss with fetch (lines 562-574)
initialDatabehavior (lines 576-590)- Manual background revalidation (lines 592-619)
The background revalidation test at line 607-613 correctly demonstrates forcing a refetch with
staleTime: 0while not awaiting the promise.
683-720: LGTM —infiniteQuerywith static staleTime tests.Correctly mirrors the
querystatic staleTime tests for infinite query scenarios, validating cache hits and fresh fetches.
928-1106: Good parity betweenqueryandfetchQuerytest suites.The new
querymethod tests properly mirror the existingfetchQuerytests, ensuring behavioral consistency. The tests cover:
- Strict query key typing
- Default retry behavior
- Cache hits
- Static staleTime with invalidation
- GC time behavior
- staleTime-based freshness checks
- Meta propagation
1287-1380: LGTM — Prefetching tests forinfiniteQuery.Tests correctly validate that
infiniteQuerycan be used for prefetching by catching errors withnoop, including multi-page prefetching and early exit whengetNextPageParamreturnsundefined.packages/query-core/src/queryClient.ts (1)
343-384: Newquerymethod implementation looks correct.The implementation properly:
- Defaults
retrytofalse(line 363-365), consistent withfetchQuery- Checks staleness before deciding to fetch (line 369-371)
- Supports
selecttransformation (lines 377-381)One minor observation: the return at line 383 uses
as unknown as TDatawhich is necessary because whenselectis not provided,TDatashould equalTQueryData, but TypeScript can't infer this.packages/vue-query/src/queryClient.ts (2)
258-314: Overload pattern is correct for Vue Query.The three-signature pattern (plain options, reactive options, implementation) follows the established Vue Query convention used throughout the file (e.g.,
ensureQueryData,fetchQuery). The implementation correctly delegates tosuper.query()after unwrapping refs.
316-378:infiniteQueryoverloads follow the same correct pattern.Consistent with the
querymethod and other Vue Query methods in this file. The complex return type conditional is correctly propagated through all overloads.packages/query-core/src/types.ts (3)
491-509: Well-structuredQueryExecuteOptionsinterface.The interface correctly:
- Extends
QueryOptionswith requiredqueryKey- Uses
initialPageParam?: neverto prevent misuse with infinite queries- Includes optional
selectfor data transformation- Uses
StaleTimeFunctionfor flexible stale time configurationThe generic parameter order (
TQueryFnData,TError,TData,TQueryData,TQueryKey,TPageParam) is consistent with existing types.
561-566: Good rename fromFetchInfiniteQueryPagestoInfiniteQueryPages.This makes the type more reusable and removes the "Fetch" prefix since it's now used by both
FetchInfiniteQueryOptionsandInfiniteQueryExecuteOptions.
568-586:InfiniteQueryExecuteOptionscorrectly composes base types.The type properly:
- Omits
initialPageParamfromQueryExecuteOptionsto re-add it as required viaInitialPageParam<TPageParam>- Includes
InfiniteQueryPagesfor pagination options- Sets appropriate defaults (
TData = InfiniteData<TQueryFnData>)
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
packages/vue-query/src/queryClient.ts (2)
258-314: Remove the duplicatequeryoverload usingMaybeRefDeep.There are two identical overload declarations for
querythat both takeoptions: MaybeRefDeep<QueryExecuteOptions<...>>; only one is needed before the implementation. Keeping both can lead to duplicate overload errors in TypeScript, while adding no extra expressiveness.You can safely drop the middle overload block:
query< TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = never, >( options: MaybeRefDeep< QueryExecuteOptions< TQueryFnData, TError, TData, TQueryData, TQueryKey, TPageParam > >, - ): Promise<TData> - query< - TQueryFnData, - TError = DefaultError, - TData = TQueryFnData, - TQueryData = TQueryFnData, - TQueryKey extends QueryKey = QueryKey, - TPageParam = never, - >( - options: MaybeRefDeep< - QueryExecuteOptions< - TQueryFnData, - TError, - TData, - TQueryData, - TQueryKey, - TPageParam - > - >, ): Promise<TData> { return super.query(cloneDeepUnref(options)) }
316-378: Remove the duplicateinfiniteQueryoverload usingMaybeRefDeep.Similarly,
infiniteQuerydeclares two identical overloads that both acceptoptions: MaybeRefDeep<InfiniteQueryExecuteOptions<...>>; only one is needed in addition to the rawInfiniteQueryExecuteOptionsoverload and the implementation. This duplication can trigger TypeScript overload errors without adding functionality.You can remove the extra overload block:
infiniteQuery< TQueryFnData, TError = DefaultError, TData = InfiniteData<TQueryFnData>, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown, >( options: MaybeRefDeep< InfiniteQueryExecuteOptions< TQueryFnData, TError, TData, TQueryKey, TPageParam > >, - ): Promise< - Array<TData> extends Array<InfiniteData<TQueryFnData>> - ? InfiniteData<TQueryFnData, TPageParam> - : TData - > - infiniteQuery< - TQueryFnData, - TError = DefaultError, - TData = InfiniteData<TQueryFnData>, - TQueryKey extends QueryKey = QueryKey, - TPageParam = unknown, - >( - options: MaybeRefDeep< - InfiniteQueryExecuteOptions< - TQueryFnData, - TError, - TData, - TQueryKey, - TPageParam - > - >, - ): Promise< - Array<TData> extends Array<InfiniteData<TQueryFnData>> - ? InfiniteData<TQueryFnData, TPageParam> - : TData - > { + ): Promise< + Array<TData> extends Array<InfiniteData<TQueryFnData>> + ? InfiniteData<TQueryFnData, TPageParam> + : TData + > { return super.infiniteQuery(cloneDeepUnref(options)) }
🧹 Nitpick comments (2)
packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (1)
79-92: Minor: Comment references wrong hook.Line 90 mentions "useInfiniteQuery" but this test is for
useSuspenseInfiniteQuery. Consider updating the comment for accuracy.- // known issue: type of pageParams is unknown when returned from useInfiniteQuery + // known issue: type of pageParams is unknown when returned from useSuspenseInfiniteQuery expectTypeOf(data).toEqualTypeOf<Array<string>>()packages/query-core/src/queryClient.ts (1)
428-454:infiniteQuerywiring looks good; consider removing theas anycast.Using
infiniteQueryBehavior(options.pages)and delegating tothis.queryunifies infinite queries with the new execute surface and reuses the same staleTime/select semantics, which is desirable. Theoptions as anycast, however, bypasses type safety betweenInfiniteQueryExecuteOptionsandQueryExecuteOptions; if possible, consider tightening the generics or extracting a small internal helper so this call site can be fully typed withoutas any.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.changeset/famous-owls-battle.md(1 hunks)packages/query-core/src/__tests__/queryClient.test-d.tsx(7 hunks)packages/query-core/src/__tests__/queryClient.test.tsx(9 hunks)packages/query-core/src/queryClient.ts(4 hunks)packages/query-core/src/types.ts(3 hunks)packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx(3 hunks)packages/react-query/src/__tests__/queryOptions.test-d.tsx(2 hunks)packages/vue-query/src/queryClient.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Applied to files:
.changeset/famous-owls-battle.mdpackages/react-query/src/__tests__/queryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/__tests__/queryClient.test.tsxpackages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsxpackages/vue-query/src/queryClient.tspackages/query-core/src/queryClient.ts
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
Applied to files:
.changeset/famous-owls-battle.mdpackages/react-query/src/__tests__/queryOptions.test-d.tsxpackages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/__tests__/queryClient.test.tsxpackages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsxpackages/vue-query/src/queryClient.tspackages/query-core/src/queryClient.tspackages/query-core/src/types.ts
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.
Applied to files:
.changeset/famous-owls-battle.md
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.
Applied to files:
packages/query-core/src/__tests__/queryClient.test-d.tsxpackages/query-core/src/__tests__/queryClient.test.tsxpackages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsxpackages/query-core/src/queryClient.ts
🧬 Code graph analysis (3)
packages/query-core/src/__tests__/queryClient.test.tsx (4)
packages/query-core/src/utils.ts (2)
noop(93-93)sleep(374-378)packages/query-core/src/types.ts (1)
QueryFunction(96-100)packages/query-core/src/query.ts (2)
promise(198-200)meta(194-196)packages/query-core/src/mutation.ts (1)
meta(124-126)
packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (5)
packages/query-core/src/queryObserver.ts (1)
options(379-385)packages/react-query/src/index.ts (3)
infiniteQueryOptions(26-26)useInfiniteQuery(55-55)useSuspenseInfiniteQuery(12-12)packages/react-query/src/infiniteQueryOptions.ts (1)
infiniteQueryOptions(147-149)packages/react-query/src/useSuspenseInfiniteQuery.ts (1)
useSuspenseInfiniteQuery(18-50)packages/query-core/src/types.ts (1)
InfiniteData(204-207)
packages/vue-query/src/queryClient.ts (4)
packages/query-core/src/types.ts (5)
DefaultError(47-51)QueryKey(53-61)QueryExecuteOptions(491-509)InfiniteData(204-207)InfiniteQueryExecuteOptions(568-586)packages/query-core/src/queryObserver.ts (1)
options(379-385)packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
🔇 Additional comments (23)
.changeset/famous-owls-battle.md (1)
1-7: Changeset looks good.The spelling is correct, and the packages are appropriately marked as minor changes. The description is brief but sufficient for the changeset format.
packages/react-query/src/__tests__/queryOptions.test-d.tsx (2)
58-66: LGTM!The test correctly validates that
queryOptionsworks with the newquerymethod, with proper type inference for the return type.
76-95: Comprehensive coverage forselectbehavior.These tests properly validate the key design difference:
queryrespects theselectoption (returningstringafter transformation), whilefetchQueryignores it (returning the originalnumber). This aligns well with the documented API distinction. Based on learnings, this is the intended behavior.packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (3)
53-66: LGTM!Test correctly validates that
useInfiniteQuerywithselecttransforms the data type toArray<string>.
93-117: Tests correctly validate the newinfiniteQuerymethod.The tests properly verify that:
- Basic usage returns
InfiniteData<string, number>with correctpageParamsinference- With
select, the return type is transformed toArray<string>This aligns with the intended behavior where
infiniteQuerysupportsselect. Based on learnings, this is the expected distinction fromfetchInfiniteQuery.
130-142: LGTM!This test correctly validates that
fetchInfiniteQueryignores theselectoption and returns the fullInfiniteData<string, number>type.packages/query-core/src/__tests__/queryClient.test.tsx (6)
11-11: LGTM!The
noopimport is appropriately used throughout the new tests to swallow promise rejections in prefetch-style patterns.
529-620: Comprehensive coverage forquerywith staticstaleTime.The tests properly validate:
- Cache hits return existing data without calling
queryFn- Falsy cached data (null) is correctly returned
- Missing data triggers fetch
initialDataprevents fetching- Manual background revalidation via a second call with
staleTime: 0The manual revalidation test (lines 592-619) is particularly valuable for documenting this use case.
683-720: LGTM!The
infiniteQuerywith staticstaleTimetests mirror the standard query tests appropriately, validating both cache hits and fetching behavior.
928-1106: Tests correctly mirrorfetchQuerybehavior.The new
querytest block comprehensively covers:
- Strict query key typing
- No retry by default
- Cache hit behavior
- Static staleTime with invalidation
- Garbage collection timing
- staleTime-based fetch decisions
- Meta propagation
This provides confidence that
querymaintains behavioral parity withfetchQuery.
1287-1380: Good pattern for prefetching withinfiniteQuery.These tests demonstrate using
infiniteQuery().catch(noop)as an alternative toprefetchInfiniteQuery. The coverage includes multi-page prefetching and early exit whengetNextPageParamreturns undefined.
1432-1483: LGTM!The
queryused for prefetching tests appropriately demonstrate the.catch(noop)pattern and verify garbage collection behavior.packages/query-core/src/__tests__/queryClient.test-d.tsx (7)
13-13: LGTM!The
InfiniteQueryExecuteOptionsimport aligns with the new public API surface introduced in this PR.
161-172: LGTM!This test correctly validates that
fetchQueryrejects theselectoption at the type level using@ts-expect-error. Based on learnings, this is the intended distinction from the newquerymethod.
175-227: LGTM!The
fetchInfiniteQuerytests correctly validate:
selectis rejected with@ts-expect-errorpagesoption works with proper return typinggetNextPageParamcan be passed withoutpagespageswithoutgetNextPageParamis rejected
229-239: LGTM!This test correctly validates that the new
querymethod accepts theselectoption, which is the key API distinction fromfetchQuery.
241-293: LGTM!The
infiniteQuerytests comprehensively validate:
selectoption is allowed (lines 242-257)pagesoption works correctly (lines 259-269)getNextPageParamwithoutpagesis allowed (lines 271-280)pageswithoutgetNextPageParamis rejected (lines 282-292)This matches the expected behavior where
infiniteQuerysupportsselectwhilefetchInfiniteQuerydoes not.
328-336: LGTM!The
infiniteQueryOptionsvariable correctly uses the newInfiniteQueryExecuteOptions<TData, TError>type to validate fully-typed usage of the infinite query API.
422-424: LGTM!The new
queryandinfiniteQuerymethod calls are properly integrated into the fully-typed usage tests, validating that the return types match expectations.Also applies to: 434-435
packages/query-core/src/queryClient.ts (2)
16-45: New execute option imports match downstream usage.Importing
InfiniteQueryExecuteOptionsandQueryExecuteOptionshere lines up with the newqueryandinfiniteQuerymethods below and keeps the execute surface types clearly separate from the legacy fetch option types.
343-384:querycorrectly implements the cache-aware execute surface withselect.This mirrors
fetchQuery’s retry/staleTime behavior while adding an optional post-fetchselecttransform against the cached/fetchedqueryData, usingresolveStaleTimeso both numeric and function-based (including'static') stale times are respected without unnecessary refetches. This matches the intended contract where the new imperativequeryAPI supportsselectwhilefetchQueryremains simpler. Based on learnings, this is the right place to exposeselect.packages/vue-query/src/queryClient.ts (1)
9-37: Vue QueryClient imports correctly mirror the core execute types.Bringing in
InfiniteQueryExecuteOptionsandQueryExecuteOptionsensures the Vue wrapper exposes the same execute signatures as the coreQueryClient, while still relying on localMaybeRefDeepfor ref-unwrapping.packages/query-core/src/types.ts (1)
491-509: Execute option types cleanly separate the execute and fetch surfaces.
QueryExecuteOptionsextendsQueryOptionswith a requiredqueryKey, aselecttransform, and astaleTimeexpressed asStaleTimeFunction, while explicitly disallowinginitialPageParam.InfiniteQueryExecuteOptionsthen layers infinite-specific concerns (InitialPageParamand the sharedInfiniteQueryPageshelper) on top, and reusingInfiniteQueryPagesinsideFetchInfiniteQueryOptionskeeps execute and fetch infinite options structurally aligned without introducingselecton the legacy fetch surface. This matches the desired contract that onlyquery/infiniteQuerysupportselect, whilefetchQuery/fetchInfiniteQuerycontinue to reject it at the type level. Based on learnings, this design looks correct.Also applies to: 561-587, 588-606
🎯 Changes
Implements #9135
fetchQueryandfetchInfiniteQuerytoqueryandinfiniteQueryfetch*aliases for the renamed methodsprefetch*methods withqueryinstead offetchQueryensureQueryDatamethods toquerywithstaletime: 'static'TODO when this is merged (I have stacked branchs for these)
✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
New Features
Chores
Tests
✏️ Tip: You can customize this high-level summary in your review settings.