Skip to content

fix(query): unable to infer mutation context when onMutate has args#200

Merged
dinwwwh merged 2 commits into
mainfrom
fix/query/infer-mutation-context-problem
Mar 5, 2025
Merged

fix(query): unable to infer mutation context when onMutate has args#200
dinwwwh merged 2 commits into
mainfrom
fix/query/infer-mutation-context-problem

Conversation

@dinwwwh
Copy link
Copy Markdown
Member

@dinwwwh dinwwwh commented Mar 5, 2025

Related: https://discord.com/channels/1308966753044398161/1316404696830836816/1346472892547727414

Summary by CodeRabbit

  • New Features

    • Enhanced mutation option configuration by introducing a new overload, allowing for a more straightforward specification of mutation settings.
    • Added improved type safeguards for mutation options, increasing flexibility and reliability.
  • Refactor

    • Updated mutation callbacks to accept parameters, enabling potential future enhancements in mutation handling.
    • Simplified method signatures for mutationOptions, queryOptions, and infiniteOptions, streamlining option handling across the interface.
    • Modified error handling comments in tests for better clarity and context.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
orpc ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 5, 2025 7:27am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 5, 2025

Walkthrough

This pull request updates the handling of mutation options and test context in both the React and Vue query packages. In the test suites, the onMutate function is modified to accept a parameter, enabling future utilization of mutation variables. In the core utility files, the mutationOptions method signature is updated to use a new type alias and an additional overload is introduced. The changes enhance type safety and streamline the handling of options across the ProcedureUtils interface.

Changes

File(s) Change Summary
packages/react-query/src/procedure-utils.test-d.ts
packages/vue-query/src/procedure-utils.test-d.ts
Updated onMutate arrow function to include a parameter (v) instead of no parameters.
packages/react-query/src/procedure-utils.ts
packages/vue-query/src/procedure-utils.ts
Modified the mutationOptions method signature to replace MaybeOptionalOptions with the new MutationOptions type and added a new overload that accepts a single options parameter.
packages/react-query/src/types.ts
packages/vue-query/src/types.ts
Introduced a new type alias MutationOptions<TInput, TOutput, TError, TMutationContext> that replaces the previous UseMutationOptions structure.
packages/vue-query/src/procedure-utils.ts
packages/vue-query/src/types.ts
Updated mutationOptions method to use the new MutationOptions type and simplified parameter handling.
packages/server/src/procedure-decorated.ts Modified the callable method to cast ...rest to any when calling createProcedureClient, affecting type checking.
packages/shared/src/types.ts Updated MaybeOptionalOptions<TOptions> type to simplify the definition of optional parameters based on the structure of TOptions.
packages/vue-colada/tests/e2e.test-d.ts Reorganized comments related to TypeScript errors within the mutationOptions section for clarity.
packages/vue-query/src/procedure-utils.test.ts Changed the invocation of mutationFn to cast options to any, affecting type safety in tests.

Possibly related PRs

  • unnoq/orpc#190 – The changes in the main PR involve modifications to the mutationOptions method in the ProcedureUtils interface, which are related to the changes in this PR that also address the mutationOptions method's return type and structure.
  • unnoq/orpc#191 – Both PRs modify the onMutate function within the useMutation call, focusing on how mutation context is handled and tested.
  • unnoq/orpc#189 – The changes in the main PR, specifically the modifications to the onMutate function and the mutationOptions method, are directly related to updates in this PR, enhancing the functionality and type inference of mutation options.

Poem

I'm a rabbit in the code, hopping on through the night,
Tweaking my functions to set every parameter right.
With new types shining like carrots so bright,
Mutation flows redefined, a delight in each byte.
Hoppin' and coding, I cheer with all my might!
🥕🐰 Happy code days to all, keeping bugs out of sight!

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 5, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

📢 Thoughts on this report? Let us know!

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Mar 5, 2025

Open in Stackblitz

More templates

@orpc/client

npm i https://pkg.pr.new/@orpc/client@200

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@200

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@200

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@200

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@200

@orpc/server

npm i https://pkg.pr.new/@orpc/server@200

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@200

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@200

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@200

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@200

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@200

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@200

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@200

commit: 2ec3816

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
packages/vue-query/src/procedure-utils.ts (1)

1-67: 💡 Verification agent

🧩 Analysis chain

Consider adding tests for the fixed mutation context inference.

The PR title indicates this is fixing an issue with mutation context inference when onMutate has arguments. To ensure this fix is robust and doesn't regress in the future, consider adding specific tests that verify the type inference works correctly in this scenario.


🏁 Script executed:

#!/bin/bash
# Check if there are any tests or types for MutationOptionsRest

echo "Checking for MutationOptionsRest definition:"
rg -A 5 "MutationOptionsRest" --glob "**/*.ts" | grep -v "procedure-utils.ts"

echo "Checking for any related type tests:"
rg -A 3 -B 3 "type test" --glob "**/*.ts" | grep -E "Mutation|onMutate"

Length of output: 588


Add Comprehensive Type Tests for Mutation Context Inference

The fix for mutation context inference when onMutate has arguments looks solid, but our search indicates that there are no type tests verifying this behavior. To prevent regressions, please add tests that explicitly confirm the type inference works as expected for mutation options, especially when onMutate receives arguments. Consider testing both overload paths of mutationOptions to ensure that the inferred types are correct.

  • Test Scenarios:
    • Validate that providing arguments in onMutate correctly infers the mutation context.
    • Confirm that the overload handling in mutationOptions produces the expected types in various use cases.
🧹 Nitpick comments (1)
packages/vue-query/src/procedure-utils.ts (1)

58-64: Ensure consistent implementation across packages.

The implementation of mutationOptions is correctly kept identical between the React and Vue packages. It handles both signature overloads properly through the use of rest parameters with a default value.

I recommend adding a comment to document the purpose of this implementation pattern, given the changes made to support better type inference.

mutationOptions(...[{ context, ...rest } = {}]) {
+  // Implementation handles both overload signatures:
+  // 1. With rest parameters (for backward compatibility)
+  // 2. With direct options object (for better type inference when onMutate has args)
  return {
    mutationKey: buildKey(path, { type: 'mutation' }),
    mutationFn: input => client(input, { context: unrefDeep(context) as any }),
    ...(rest as any),
  }
},
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf03cec and b621738.

📒 Files selected for processing (6)
  • packages/react-query/src/procedure-utils.test-d.ts (1 hunks)
  • packages/react-query/src/procedure-utils.ts (2 hunks)
  • packages/react-query/src/types.ts (1 hunks)
  • packages/vue-query/src/procedure-utils.test-d.ts (1 hunks)
  • packages/vue-query/src/procedure-utils.ts (2 hunks)
  • packages/vue-query/src/types.ts (1 hunks)
🔇 Additional comments (11)
packages/vue-query/src/types.ts (1)

63-63: Good addition of type utility for handling conditional rest parameters

This new MutationOptionsRest<T> type utility elegantly handles the conditional parameter passing pattern, resolving to an empty tuple when the options object is empty, and a single-element tuple otherwise.

This is a good pattern for handling optional parameters in TypeScript function signatures, particularly for mutation options which may or may not require additional configuration.

packages/react-query/src/types.ts (1)

37-37: Good addition of type utility for handling conditional rest parameters

This new MutationOptionsRest<T> type utility elegantly handles the conditional parameter passing pattern, resolving to an empty tuple when the options object is empty, and a single-element tuple otherwise.

The utility ensures consistent typing across both React and Vue implementations, providing a solid foundation for handling mutation options in a type-safe manner.

packages/vue-query/src/procedure-utils.test-d.ts (1)

280-280: Updated onMutate to accept mutation variables parameter

The function signature now accepts a parameter that can be used to access mutation variables, aligning with the PR objective to fix inference of mutation context when onMutate has args.

This change enables proper type inference for mutation context when the onMutate callback has parameters, addressing the issue mentioned in the PR title.

packages/react-query/src/procedure-utils.test-d.ts (1)

293-293: Updated onMutate to accept mutation variables parameter

The function signature now accepts a parameter that can be used to access mutation variables, aligning with the PR objective to fix inference of mutation context when onMutate has args.

This change enables proper type inference for mutation context when the onMutate callback has parameters, addressing the issue mentioned in the PR title. The consistency between React and Vue implementations is maintained.

packages/react-query/src/procedure-utils.ts (4)

4-4: Updated import properly includes the new MutationOptionsRest type.

The import statement has been correctly updated to include the new MutationOptionsRest type that will be used in the method signatures.


20-22: Improved type inference for mutation options.

Replacing MaybeOptionalOptions with MutationOptionsRest should help fix the issue where mutation context wasn't being properly inferred when onMutate has arguments. This change maintains backward compatibility while enhancing type safety.


24-26: Added explicit signature overload for better type inference.

Adding this overload signature is a good approach that allows the API to be more flexible while providing proper type inference. This explicit signature will make it clearer to consumers how to properly type their mutation options.


54-60:

Details

✅ Verification successful

Verify implementation compatibility with the new signatures.

The implementation of mutationOptions hasn't changed, but it should work with both the updated rest parameter signature and the new direct options signature. Since TypeScript function overloads share a single implementation, the current implementation using rest parameters with default value should correctly handle both cases.


🏁 Script executed:

#!/bin/bash
# Check if there are any tests that validate the new mutation options behavior

echo "Checking for tests related to mutation options:"
rg -A 3 -B 3 "mutationOptions" --glob "**/*.test.ts" --glob "**/*.spec.ts"

echo "Checking for tests that might be testing onMutate with arguments:"
rg -A 3 -B 3 "onMutate" --glob "**/*.test.ts" --glob "**/*.spec.ts"

Length of output: 3298


Action Required: Confirming Mutation Options Signature Compatibility

The tests in multiple packages (react-query, vue-query, and vue-colada) confirm that the current implementation of mutationOptions, which uses a rest parameter with a default object, correctly supports both the legacy rest parameter signature and the new direct options signature. There were no discrepancies found in the tests verifying that passing an options object (with or without the context property) results in the expected behavior.

  • The tests validate that calling mutationOptions() without parameters and with an options object (e.g., { context: { batch: '__batch__' } }) behaves as intended.
  • The implementation using destructuring defaults in the rest parameter slot is fully compatible with TypeScript function overloads, ensuring both usage patterns are handled.

No modifications are necessary at this time.

packages/vue-query/src/procedure-utils.ts (3)

4-4: Updated import properly includes the new MutationOptionsRest type.

The import statement has been correctly updated to include the new MutationOptionsRest type that will be used in the method signatures.


22-24: Improved type inference for mutation options.

Replacing MaybeOptionalOptions with MutationOptionsRest should help fix the issue where mutation context wasn't being properly inferred when onMutate has arguments. This change maintains backward compatibility while enhancing type safety.


26-28: Added explicit signature overload for better type inference.

Adding this overload signature is a good approach that allows the API to be more flexible while providing proper type inference. This explicit signature will make it clearer to consumers how to properly type their mutation options.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (6)
packages/server/src/procedure-decorated.ts (1)

127-127: Consider a more type-safe alternative to as any.

While the type assertion works as a fix, using as any bypasses TypeScript's type checking which can hide potential type errors. Consider if there's a more type-safe way to handle this case, potentially by creating a more specific type assertion or refining the type definitions.

If a more type-safe alternative isn't practical at this time, please add a code comment explaining why the as any cast is necessary here to help future maintainers.

packages/vue-query/src/procedure-utils.test.ts (1)

64-64: Type assertion may be avoidable in test case.

The change from options.mutationFn!('__input__') to (options as any).mutationFn('__input__') works around type constraints, but may not be necessary in a test context. Consider if the test could be updated to work with the new type structure directly, rather than using a type assertion.

Since this is a test file, the type assertion has less impact on production code safety, but maintaining type safety in tests is still a good practice when possible.

packages/vue-query/src/procedure-utils.ts (4)

34-34: Consider simplifying the parameter destructuring pattern.

The current implementation uses an unusual destructuring pattern with rest parameters that could be simplified.

-queryOptions(...[options = {} as any]) {
+queryOptions(options = {} as any) {

45-45: Consider reducing the number of type assertions in this line.

The line uses multiple as any type assertions which bypass TypeScript's type checking. This could potentially hide type errors at compile time.

-return buildKey(path, { type: 'infinite', input: unrefDeep(options.input(unrefDeep(options.initialPageParam) as any) as any) })
+return buildKey(path, { type: 'infinite', input: unrefDeep(options.input(unrefDeep(options.initialPageParam))) })

If type issues persist, consider adding more specific type parameters or interfaces rather than using any.


48-48: Multiple type assertions could be improved with better typing.

Similar to the previous comment, this line also uses multiple as any type assertions. Consider refining the types to avoid these assertions.

-return client(unrefDeep(options.input(pageParam as any)) as any, { signal, context: unrefDeep(options.context) as any })
+return client(unrefDeep(options.input(pageParam)), { signal, context: unrefDeep(options.context) })

54-54: Consider simplifying the parameter destructuring pattern in mutationOptions.

Similar to the queryOptions method, the destructuring pattern with rest parameters could be simplified for clarity.

-mutationOptions(...[options = {} as any]) {
+mutationOptions(options = {} as any) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b621738 and 2ec3816.

📒 Files selected for processing (8)
  • packages/react-query/src/procedure-utils.ts (3 hunks)
  • packages/react-query/src/types.ts (1 hunks)
  • packages/server/src/procedure-decorated.ts (1 hunks)
  • packages/shared/src/types.ts (1 hunks)
  • packages/vue-colada/tests/e2e.test-d.ts (1 hunks)
  • packages/vue-query/src/procedure-utils.test.ts (1 hunks)
  • packages/vue-query/src/procedure-utils.ts (3 hunks)
  • packages/vue-query/src/types.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/vue-colada/tests/e2e.test-d.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-query/src/procedure-utils.ts
  • packages/vue-query/src/types.ts
🔇 Additional comments (8)
packages/react-query/src/types.ts (2)

27-29: Good use of type structure enhancement.

The change effectively uses the new MutationOptions type, providing a cleaner separation of concerns. This abstraction makes the code more maintainable and improves readability.


31-31: Well-designed type alias introduction.

Creating this type alias is a good abstraction that addresses the issue with mutation context inference. This change allows for better type inference when onMutate has arguments, as mentioned in the PR description.

packages/shared/src/types.ts (1)

1-3: Excellent type definition improvement.

This change to MaybeOptionalOptions is a significant improvement over the previous definition. The conditional type approach is more readable and directly expresses the intent: make options optional only when the options type is an empty record.

This change directly helps address the issue with mutation context inference mentioned in the PR title.

packages/vue-query/src/procedure-utils.ts (5)

4-4: Added new type imports to support mutation context updates.

The import statement has been updated to include MutationOptions and MutationOptionsIn types, which are essential for the mutation context inference changes in this PR.


22-24: Improved mutation options method signature to support context inference.

The mutationOptions method signature has been updated to properly support mutation context by:

  1. Accepting a generic UMutationContext parameter
  2. Using the rest parameter pattern with MaybeOptionalOptions
  3. Returning a properly typed MutationOptions that includes the mutation context

This change directly addresses the PR objective of fixing the context inference when onMutate has arguments.


36-38: Updated queryOptions implementation to use a simplified options object pattern.

The implementation now consistently accesses input and context from a single options object, which aligns with the interface changes and makes the code more maintainable.


42-42: Simplified infiniteOptions signature to use a single options parameter.

This change aligns with the pattern used in the other methods, creating consistency across the interface.


57-57: Updated mutationFn to use the context from options.

This change correctly takes the context from the options object, which is necessary for the mutation context inference fix.

Comment thread packages/vue-query/src/procedure-utils.ts
Comment thread packages/vue-query/src/procedure-utils.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant