-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
feat(vue-query): allow options getters in additional composables #9914
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
Conversation
🦋 Changeset detectedLatest commit: 4042579 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 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 |
WalkthroughThe PR extends Changes
Sequence DiagramsequenceDiagram
participant Caller
participant Composable
participant OptionsResolver
participant ReactiveChecker
participant QueryClient
rect rgb(230, 245, 250)
note over Caller,Composable: Old: Direct options object
Caller->>Composable: mutationOptions = {key: 'key1'}
Composable->>OptionsResolver: Use mutationOptions directly
OptionsResolver->>ReactiveChecker: cloneDeepUnref(mutationOptions)
end
rect rgb(245, 235, 255)
note over Caller,Composable: New: Options getter function
Caller->>Composable: mutationOptions = () => ({key: ref('key1')})
Composable->>OptionsResolver: Is function? Yes → call it
OptionsResolver->>ReactiveChecker: result = mutationOptions()
ReactiveChecker->>ReactiveChecker: cloneDeepUnref(result)
ReactiveChecker->>QueryClient: Apply resolved options
end
rect rgb(255, 240, 245)
note over Caller,Composable: Reactivity flow (ref update)
Caller->>Caller: Update ref inside getter
Caller->>Composable: Getter is re-evaluated
Composable->>OptionsResolver: Call getter again
OptionsResolver->>ReactiveChecker: New resolved options
ReactiveChecker->>QueryClient: Trigger re-fetch/state update
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ 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 4042579
☁️ Nx Cloud last updated this comment at |
|
Sizes for commit 4042579:
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9914 +/- ##
===========================================
+ Coverage 45.79% 71.91% +26.12%
===========================================
Files 200 19 -181
Lines 8421 495 -7926
Branches 1928 151 -1777
===========================================
- Hits 3856 356 -3500
+ Misses 4116 109 -4007
+ Partials 449 30 -419
🚀 New features to boost your workflow:
|
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/vue-query/src/useQueries.ts (1)
265-270: LGTM! Runtime resolution correctly handles function-based options.The implementation properly:
- Distinguishes between function-based and value-based inputs
- Executes the function within the computed context for reactivity tracking
- Maintains the existing unref flow for the resolved value
The type assertion on line 267 is unnecessary as TypeScript narrows the type from the
typeofcheck:const resolvedQueries = typeof queries === 'function' - ? (queries as () => MaybeRefDeep<UseQueriesOptionsArg<T>>)() + ? queries() : queries
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
.changeset/curvy-webs-create.md(1 hunks)packages/vue-query/src/__mocks__/useBaseQuery.ts(1 hunks)packages/vue-query/src/__tests__/useInfiniteQuery.test.ts(1 hunks)packages/vue-query/src/__tests__/useIsFetching.test.ts(3 hunks)packages/vue-query/src/__tests__/useIsMutating.test.ts(3 hunks)packages/vue-query/src/__tests__/useMutation.test.ts(1 hunks)packages/vue-query/src/__tests__/useQueries.test.ts(4 hunks)packages/vue-query/src/__tests__/useQuery.test.ts(5 hunks)packages/vue-query/src/useIsFetching.ts(2 hunks)packages/vue-query/src/useMutation.ts(3 hunks)packages/vue-query/src/useMutationState.ts(3 hunks)packages/vue-query/src/useQueries.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 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-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/vue-query/src/__mocks__/useBaseQuery.tspackages/vue-query/src/__tests__/useIsFetching.test.tspackages/vue-query/src/__tests__/useIsMutating.test.tspackages/vue-query/src/__tests__/useInfiniteQuery.test.tspackages/vue-query/src/__tests__/useQueries.test.tspackages/vue-query/src/__tests__/useMutation.test.tspackages/vue-query/src/__tests__/useQuery.test.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/vue-query/src/__mocks__/useBaseQuery.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/curvy-webs-create.md
🧬 Code graph analysis (7)
packages/vue-query/src/__tests__/useIsFetching.test.ts (1)
packages/vue-query/src/useIsFetching.ts (1)
useIsFetching(11-44)
packages/vue-query/src/__tests__/useIsMutating.test.ts (3)
packages/vue-query/src/useMutation.ts (1)
useMutation(78-160)packages/query-core/src/mutationObserver.ts (1)
mutate(128-143)packages/vue-query/src/useMutationState.ts (2)
useIsMutating(23-49)useMutationState(68-96)
packages/vue-query/src/useMutation.ts (4)
packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/react-query/src/mutationOptions.ts (1)
mutationOptions(32-41)packages/react-query/src/types.ts (1)
UseMutationOptions(192-200)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
packages/vue-query/src/useMutationState.ts (1)
packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
packages/vue-query/src/useIsFetching.ts (3)
packages/vue-query/src/types.ts (1)
MaybeRefDeep(29-37)packages/vue-query/src/queryClient.ts (1)
isFetching(49-51)packages/vue-query/src/utils.ts (1)
cloneDeepUnref(70-97)
packages/vue-query/src/__tests__/useMutation.test.ts (2)
packages/query-core/src/queriesObserver.ts (1)
result(195-210)packages/vue-query/src/useMutation.ts (1)
useMutation(78-160)
packages/vue-query/src/__tests__/useQuery.test.ts (2)
packages/query-core/src/queryObserver.ts (1)
query(704-721)packages/vue-query/src/useQuery.ts (1)
useQuery(123-137)
⏰ 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 (24)
.changeset/curvy-webs-create.md (1)
1-5: Changeset structure and content look good.The YAML frontmatter correctly specifies a
minorversion bump for@tanstack/vue-query, which is appropriate for a feature addition. The changelog entry accurately summarizes the feature being added.packages/vue-query/src/useQueries.ts (1)
243-243: LGTM! Type definition correctly extends queries parameter.The addition of the function form
(() => MaybeRefDeep<UseQueriesOptionsArg<T>>)enables dynamic configuration through option getters while preserving backward compatibility with existing forms.packages/vue-query/src/__tests__/useQueries.test.ts (4)
257-278: DeterministicfetchFnstub improves clarityUsing
const fetchFn = vi.fn(() => 'foo')gives this test a predictable, non-void return value while still only asserting on call counts. This matches surrounding tests’ style and keeps the focus on theenabledgetter behavior rather than the fetch implementation.
280-307: ConsistentfetchFnstub for key‑getter reactivity testSwitching to
vi.fn(() => 'foo')here keeps the query function deterministic and consistent with other tests, while the assertions remain solely about how often it’s invoked as the query key getters change.
309-370: AlignedfetchFnbehavior in nested key‑getter testUsing
vi.fn(() => 'foo')in this deeply nested key-getter test is a good move: it standardizes the mock behavior and keeps the test focused on reactivity across the nested structures rather than on the return type of the function.
372-433: New options‑getter reactivity test covers important combinationsThe new test exercises
queriesas a getter with a mix of refs, direct.valuereads, objects/arrays, and a nested function inqueryKey, then verifies one refetch per reactive change viafetchFncall counts. This is a strong coverage addition for the new options‑getter behavior and mirrors the earlier nested getter tests in a realistic way.packages/vue-query/src/__mocks__/useBaseQuery.ts (1)
4-9: LGTM! Clean removal of unused mock export.The simplification removes the
unrefQueryArgsexport while maintaining theuseBaseQuerymock functionality. This cleanup aligns with the broader changes in the PR.packages/vue-query/src/useIsFetching.ts (2)
9-9: Consistent type extension for option getters.The QueryFilters type now supports both direct values and functions returning values, enabling dynamic filter configuration. This aligns with the broader pattern introduced across composables in this PR.
28-32: Proper resolution of function-based filters.The implementation correctly resolves filters whether provided as a value or getter function, then applies
cloneDeepUnrefto handle refs. This pattern is consistent with similar changes inuseMutation.tsanduseMutationState.ts.packages/vue-query/src/useMutation.ts (2)
37-48: Well-structured type extension for reactive options.The union type properly supports both direct mutation options and function-based getters, maintaining type safety while enabling dynamic configuration.
101-107: Correct reactive resolution of mutation options.The computed property resolves function-based options before applying defaults and cloneDeepUnref, ensuring reactivity is preserved. This matches the established pattern across other composables in this PR.
packages/vue-query/src/useMutationState.ts (3)
24-24: Function-based filters support added.Extending the
filtersparameter to accept a function enables dynamic filter configuration, consistent with changes to other composables.
69-80: Centralized option resolution with computed property.The resolvedOptions computed property handles both direct and function-based options, applying cloneDeepUnref to filters while preserving the select function. This ensures proper reactivity and consistent behavior.
82-89: Consistent usage of resolved options.All references to options now correctly use
resolvedOptions.value, ensuring the computed resolution logic is applied throughout initialization, subscriptions, and watchers.packages/vue-query/src/__tests__/useInfiniteQuery.test.ts (1)
8-8: Good catch fixing the test suite description.The describe block now correctly identifies this as "useInfiniteQuery" instead of "useQuery", improving test organization and clarity.
packages/vue-query/src/__tests__/useIsFetching.test.ts (2)
67-81: Enhanced test with queryKey filter.Adding the queryKey to the filter improves test specificity, ensuring the isFetching count accurately reflects queries matching specific criteria.
83-100: Excellent test coverage for reactive option getters.This test validates that:
- Function-based options work correctly with
useIsFetching- Reactivity is preserved when the ref changes
- The fetching count updates appropriately
The test pattern is clean and follows TanStack testing conventions.
packages/vue-query/src/__tests__/useMutation.test.ts (1)
85-116: Comprehensive test for reactive mutation options.This test effectively validates:
- Function-based mutation options work correctly
- Reactive refs in the getter trigger updates when changed
- The mutationKey is properly passed to the mutation function
- Multiple mutations reflect the updated reactive values
The test structure is clear and follows the established patterns in the test suite.
packages/vue-query/src/__tests__/useQuery.test.ts (2)
65-96: Thorough test for reactive query option getters.This test validates the core reactive getter functionality:
- Options getter returns proper configuration based on refs
- Initial query executes with correct values
- Updating refs triggers re-fetch with new values
- Query state reflects the updated data
The test comprehensively covers the reactive behavior expected from option getters.
310-310: Improved test reliability with vi.fn().Replacing inline functions with
vi.fn()provides better test control and deterministic behavior, making these tests more maintainable and reliable.Also applies to: 338-338, 357-357, 382-382
packages/vue-query/src/__tests__/useIsMutating.test.ts (4)
2-2: Import ofrefis appropriate and used
reffromvue-demiis needed for the new reactive key tests and is correctly added alongside existingreactiveimport; no issues here.
92-111: useIsMutating options‑getter reactivity test looks correctThis test accurately exercises the new options‑getter path: it starts with a non‑matching key (count 0), switches the
refto the actual mutation key, keeps the mutation pending viasleep(10)and only advancing timers by 0 ms, and then asserts the count becomes 1. The pattern mirrors the existing filter‑reactivity test and gives solid coverage of the getter + ref combo. Based on learnings, the use of.thenfor a side‑effect‑freemutationFnis consistent with the repo’s test style.
115-121: Using fake timers in the useMutationState suite is appropriateEnabling fake timers per‑suite is necessary for
vi.advanceTimersByTimeAsyncin the new async test, and it should not affect the existing tests since they only rely on synchronous pending state (variables are set immediately on mutate). The timer reset inafterEachkeeps isolation clean.
160-183: useMutationState options‑getter reactivity test is well‑designedThis test correctly validates that
useMutationStatehandles an options getter whosefilters.mutationKeydepends on aref: it first sees no matches (empty array), then, after updating the key and advancing timers by 0 ms (keeping the mutation pending), it observes the selected variables array. This directly exercises the new getter logic and its reactivity, including theselectpath.
🎯 Changes
✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
New Features
useIsFetching,useMutation,useMutationState, anduseQueriescan accept functions that dynamically return options or filters, enabling more reactive and flexible configuration patterns.Tests
✏️ Tip: You can customize this high-level summary in your review settings.