Skip to content

Conversation

@Nick-Lucas
Copy link
Contributor

@Nick-Lucas Nick-Lucas commented Oct 17, 2025

Closes #4989

🎯 Changes

Supports queryKeyPrefix on TRPCProvider with the Tanstack Query Client, allowing all cached queries in a react tree to be prefixed, for instance with a user ID. This allows easier implementation of user/session switching while keeping data cached for switching back and forth

import { createTRPCContextWithFeatureFlags } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';

// First enable the feature, we need a new function for this for typescript reasons, but it's a drop-in change
export const { TRPCProvider, useTRPC, useTRPCClient } =
  createTRPCContextWithFeatureFlags({
    enableKeyPrefix: true,
  })<AppRouter>();

export function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <TRPCProvider
        trpcClient={trpcClient}
        queryClient={queryClient}

        // Optional: provide a prefix for all query/mutation keys
        queryKeyPrefix={userId}

        // Also can be an array
        queryKeyPrefix={[userId, orgId]}
      >
        {/* Your app here */}
      </TRPCProvider>
    </QueryClientProvider>
  );
}

Nuances:

  • In order to use a prefix, the feature flag much be enabled when creating the context
  • If a runtime prefix is not provided then the element won't be in the key - I believe this is correct behaviour else invalidateQueries([[]]) would invalidate [["somePrefix"]] as well
  • If a runtime prefix is provided then query keys will include the prefix element

✅ Checklist

  • I have followed the steps listed in the Contributing guide.
  • If necessary, I have added documentation related to the changes made.
  • I have added or updated the tests related to the changes made.

Summary by CodeRabbit

  • New Features

    • Optional keyPrefix support for TRPC providers to namespace query/mutation keys and avoid cache collisions across instances
  • Improvements

    • Prefix-aware key handling throughout client APIs for consistent key generation and usage
    • TypeScript typings extended to propagate keyPrefix feature flags across public APIs
  • Documentation

    • Added "Query Key Prefixing" setup, examples, and guidance for multi-provider isolation
  • Tests

    • Added tests validating multiple TRPC providers and prefixed/unprefixed key behavior

@vercel
Copy link

vercel bot commented Oct 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
next-prisma-starter Ready Ready Preview Oct 25, 2025 3:04pm
og-image Ready Ready Preview Comment Oct 25, 2025 3:04pm
www Ready Ready Preview Comment Oct 25, 2025 3:04pm

@railway-app
Copy link

railway-app bot commented Oct 17, 2025

🚅 Deployed to the trpc-pr-6976 environment in trpc-sse-and-websockets

Service Status Web Updated (UTC)
next-prisma-websockets-starter ◻️ Removed (View Logs) Oct 25, 2025 at 3:05 pm
next-sse-chat ◻️ Removed (View Logs) Web Oct 25, 2025 at 3:05 pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds feature-flagged, prefix-aware query/mutation key support across tanstack-react-query: new FeatureFlags and KeyPrefixOptions types, prefixed/unprefixed key variants, keyPrefix plumbing through Context/Provider and options proxy, prefix-aware key-generation utils, updated option typings, tests, and docs.

Changes

Cohort / File(s) Summary
Type System Foundation
packages/tanstack-react-query/src/internals/types.ts
Introduce FeatureFlags, DefaultFeatureFlags, KeyPrefixOptions; replace monolithic key types with prefixed/unprefixed TRPCQueryKey/TRPCMutationKey variants; add featureFlags to ResolverDef.
Key Utilities
packages/tanstack-react-query/src/internals/utils.ts
Add isPrefixedQueryKey and readQueryKey; refactor getQueryKeyInternal/getMutationKeyInternal to accept opt objects including prefix; make key builders prefix-aware and update exports/types.
Context & Provider
packages/tanstack-react-query/src/internals/Context.tsx
Make context/provider generic over TFeatureFlags; accept/forward keyPrefix prop; memoize provider value with keyPrefix; create options proxy with prefix; set displayName.
Options Proxy
packages/tanstack-react-query/src/internals/createOptionsProxy.ts
Parameterize TRPCOptionsProxy/DecoratedRouterRecord with TFeatureFlags; thread keyPrefix into all key-generation calls via getQueryKeyInternal/getMutationKeyInternal.
Query & Infinite Query Options
packages/tanstack-react-query/src/internals/queryOptions.ts, packages/tanstack-react-query/src/internals/infiniteQueryOptions.ts
Add TFeatureFlags generics (default DefaultFeatureFlags); switch queryKey types to TRPCQueryKey<TFeatureFlags['keyPrefix']> and propagate through public overloads and trpc*Options functions.
Mutation Options
packages/tanstack-react-query/src/internals/mutationOptions.ts
Add TFeatureFlags generics; include KeyPrefixOptions; compute mutation keys with getMutationKeyInternal({ path, prefix: opts.keyPrefix }); use prefixed mutation keys for mutate calls and public types.
Subscription Options
packages/tanstack-react-query/src/internals/subscriptionOptions.ts
Add TFeatureFlags generics; make queryKey use TRPCQueryKey<TFeatureFlags['keyPrefix']>; extract input via readQueryKey() for prefixed keys; update public signatures.
Tests & Helpers
packages/tanstack-react-query/test/__helpers.tsx, packages/tanstack-react-query/test/queryKeyable.test.tsx, packages/tanstack-react-query/test/utils.test.ts, packages/tanstack-react-query/test/multipleTrpcProviders.test.tsx
Extend test helpers and tests to support keyPrefix option and feature-flag generics; update tests and snapshots for prefixed/unprefixed key shapes; adapt to new getQueryKeyInternal signature and readQueryKey; add multi-provider test.
Docs
www/docs/client/tanstack-react-query/setup.mdx, www/docs/client/tanstack-react-query/usage.mdx
Add "Query Key Prefixing" docs and examples showing keyPrefix feature flag and TRPCProvider usage; minor wording tweaks.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant TRPCProvider
    participant OptionsProxy as createTRPCOptionsProxy
    participant KeyUtil as getQueryKeyInternal

    App->>TRPCProvider: Render (trpcClient, keyPrefix?)
    TRPCProvider->>TRPCProvider: memoize value (deps include keyPrefix)
    TRPCProvider->>OptionsProxy: createTRPCOptionsProxy<TRouter,TFeatureFlags>({ keyPrefix })
    OptionsProxy->>KeyUtil: getQueryKeyInternal({ path, type, prefix: keyPrefix })
    alt keyPrefix present
        KeyUtil-->>OptionsProxy: return prefixed key (["prefix", path..., args?])
    else
        KeyUtil-->>OptionsProxy: return unprefixed key ([path..., args?])
    end
    OptionsProxy-->>TRPCProvider: return prefix-aware TRPCOptionsProxy
    TRPCProvider-->>App: provide context value
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • Type propagation of TFeatureFlags across public APIs and overloads.
    • Correctness and edge cases in getQueryKeyInternal / getMutationKeyInternal and readQueryKey (empty/undefined prefix, nested arrays).
    • Context/provider memoization (dependency list includes keyPrefix) to avoid unnecessary re-renders.
    • Test updates and new multi-provider test coverage and snapshots.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • KATT
  • juliusmarminge

Poem

🐇
I stitched a prefix on every key,
so queries hop where they should be.
Proxies, flags, and tests align,
two providers fetch without a sign.
🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning Issue #4989 requests a mechanism to override tRPC-generated query keys to allow different inputs to map to the same client-side cache key, enabling cache synchronization patterns without relying on deprecated useQuery.onSuccess callbacks. However, the PR implements a queryKeyPrefix feature that adds a prefix to all generated keys within a provider subtree for multi-user/multi-tenant scenarios, which is a different use case than the query key override mechanism requested in the issue. The PR does not provide the static or dynamic query key override functionality described in issue #4989, making the claimed closure of that issue misleading. The PR should either clarify that it addresses a different aspect of issue #4989 than what the issue description requests, or the issue reference should be updated to reflect a different issue more aligned with the query key prefixing feature being implemented. Alternatively, query key override functionality should be added to fully satisfy the original issue requirements for allowing different inputs to share the same cache key.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "feat(tanstack-react-query): Add QueryKey and MutationKey Prefix option" is concise, specific, and clearly describes the main change being introduced. It uses conventional commit formatting with an appropriate scope and accurately summarizes the feature being added—support for prefixing query and mutation keys. The title is not vague or generic and provides clear context about what enhancement is being made to the tanstack-react-query integration.
Out of Scope Changes Check ✅ Passed
Description Check ✅ Passed The PR description follows the repository template structure with all required sections present: it references the closed issue (#4989), includes a well-organized "🎯 Changes" section with detailed explanation and code examples demonstrating the queryKeyPrefix usage, provides important nuances about the feature behavior, and includes the checklist. The description is informative and explains both the motivation and usage patterns clearly, though the checklist items remain unchecked. The description provides sufficient context for understanding the changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch prefix-query-key

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b19065 and 2d023e1.

📒 Files selected for processing (2)
  • packages/tanstack-react-query/test/multipleTrpcProviders.test.tsx (1 hunks)
  • www/docs/client/tanstack-react-query/usage.mdx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • www/docs/client/tanstack-react-query/usage.mdx
  • packages/tanstack-react-query/test/multipleTrpcProviders.test.tsx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@railway-app railway-app bot temporarily deployed to next-prisma-websockets-starter (trpc-sse-and-websockets / trpc-pr-6976) October 17, 2025 15:47 Destroyed
@railway-app railway-app bot temporarily deployed to next-sse-chat (trpc-sse-and-websockets / trpc-pr-6976) October 17, 2025 15:47 Destroyed
@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 17, 2025

Open in StackBlitz

@trpc/client

npm i https://pkg.pr.new/trpc/trpc/@trpc/client@6976

@trpc/next

npm i https://pkg.pr.new/trpc/trpc/@trpc/next@6976

@trpc/react-query

npm i https://pkg.pr.new/trpc/trpc/@trpc/react-query@6976

@trpc/server

npm i https://pkg.pr.new/trpc/trpc/@trpc/server@6976

@trpc/tanstack-react-query

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

@trpc/upgrade

npm i https://pkg.pr.new/trpc/trpc/@trpc/upgrade@6976

commit: 2d023e1

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/tanstack-react-query/src/internals/mutationOptions.ts (1)

99-99: Missing prefix in mutation key construction.

The getMutationKeyInternal call doesn't receive the queryKeyPrefix, so mutation keys will always have an empty prefix even when a prefix is configured. The function should receive a prefix parameter (similar to how getQueryKeyInternal receives { prefix: queryKeyPrefix } throughout the codebase), or the mutation key should be passed in pre-constructed.

Consider passing the prefix through trpcMutationOptions parameters:

 export function trpcMutationOptions(args: {
   mutate: typeof TRPCUntypedClient.prototype.mutation;
   queryClient: QueryClient | (() => QueryClient);
   path: readonly string[];
   opts: AnyTRPCMutationOptionsIn;
   overrides: MutationOptionsOverride | undefined;
+  prefix?: readonly string[];
 }): AnyTRPCMutationOptionsOut {

Then update line 99:

-  const mutationKey = getMutationKeyInternal(path);
+  const mutationKey = getMutationKeyInternal(path, { prefix: args.prefix });

And in createOptionsProxy.ts (lines 441-448), pass the prefix when calling trpcMutationOptions.

packages/tanstack-react-query/src/internals/createOptionsProxy.ts (1)

450-452: Mutation key missing prefix.

The mutationKey() method doesn't pass the queryKeyPrefix to getMutationKeyInternal, so mutation keys will always have an empty prefix regardless of the configured queryKeyPrefix. This is inconsistent with query keys and breaks the prefix feature for mutations.

Apply this diff:

       mutationKey: () => {
-        return getMutationKeyInternal(path);
+        return getMutationKeyInternal(path, { prefix: queryKeyPrefix });
       },

You'll also need to update getMutationKeyInternal in utils.ts to accept an options parameter with prefix, similar to getQueryKeyInternal.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd64ab3 and 98acb82.

📒 Files selected for processing (9)
  • packages/tanstack-react-query/src/internals/Context.tsx (2 hunks)
  • packages/tanstack-react-query/src/internals/createOptionsProxy.ts (6 hunks)
  • packages/tanstack-react-query/src/internals/mutationOptions.ts (1 hunks)
  • packages/tanstack-react-query/src/internals/subscriptionOptions.ts (1 hunks)
  • packages/tanstack-react-query/src/internals/types.ts (1 hunks)
  • packages/tanstack-react-query/src/internals/utils.ts (4 hunks)
  • packages/tanstack-react-query/test/__helpers.tsx (3 hunks)
  • packages/tanstack-react-query/test/queryKeyable.test.tsx (11 hunks)
  • packages/tanstack-react-query/test/utils.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

**/*.{ts,tsx}: Always use import type for type-only imports
Separate type imports from value imports
Avoid overzealous object destructuring; prefer direct property access
Object destructuring is acceptable when a variable is used 3+ times
Prefer array destructuring
Avoid sparse array destructuring
Never destructure in function parameter declarations
Avoid destructuring potentially nullish nested properties
Maximum 3 parameters per function; use options objects when more
Type parameter names must match /^(T|$)(A-Z)?[0-9]*$/
Prefix unused variables, parameters, and caught errors with _
Prefer namespace imports for validation libraries and large modules (e.g., import * as z from 'zod', import * as React from 'react')
Follow import order: test helpers, tRPC test imports, third-party, then relative
Never import from @trpc/*/src; import from the package root instead
Do not use Symbol.dispose or Symbol.asyncDispose; use makeResource()/makeAsyncResource()
Always use await using for resource cleanup
Prefer makeResource()/makeAsyncResource() over manual disposal logic
Avoid non-null assertions (!)
Use proper type guards and optional chaining instead of non-null assertions
Switch statements must be exhaustive for union types
Rely on TypeScript inference; avoid unnecessary explicit return/output types
Use explicit types at public API boundaries, for complex generic constraints, or when inference is insufficient/ambiguous
Use the satisfies operator to retain inference while enforcing shapes
Use as const for literal type inference when appropriate
Prefer explicit typing over any
Use type assertions sparingly
Leverage TypeScript strict mode features

Files:

  • packages/tanstack-react-query/src/internals/types.ts
  • packages/tanstack-react-query/src/internals/subscriptionOptions.ts
  • packages/tanstack-react-query/src/internals/mutationOptions.ts
  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/src/internals/createOptionsProxy.ts
  • packages/tanstack-react-query/src/internals/utils.ts
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
**/*.{ts,tsx,md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Use camelCase for file names (with exceptions like TRPC/RPC/HTTP/JSON acronyms, .config.js, .d.ts, and tests)

Files:

  • packages/tanstack-react-query/src/internals/types.ts
  • packages/tanstack-react-query/src/internals/subscriptionOptions.ts
  • packages/tanstack-react-query/src/internals/mutationOptions.ts
  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/src/internals/createOptionsProxy.ts
  • packages/tanstack-react-query/src/internals/utils.ts
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

No console.log in packages; use proper logging instead

Files:

  • packages/tanstack-react-query/src/internals/types.ts
  • packages/tanstack-react-query/src/internals/subscriptionOptions.ts
  • packages/tanstack-react-query/src/internals/mutationOptions.ts
  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/src/internals/createOptionsProxy.ts
  • packages/tanstack-react-query/src/internals/utils.ts
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

**/*.tsx: Follow React Hooks rules (React Compiler compatible patterns)
Use the JSX runtime (no need to import React for JSX)
Prefer function components

Files:

  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
**/*.test.ts

📄 CodeRabbit inference engine (.cursor/rules/test-patterns.mdc)

**/*.test.ts: ALWAYS use await using ctx = testServerAndClientResource(...) in tests that need both server and client setup
NEVER use the deprecated routerToServerAndClientNew() in tests
Import testServerAndClientResource from @trpc/client/__tests__/testClientResource
Create fresh mock instances per test using a factory (e.g., getMockFetch())
Do not use global mocks that persist across tests
Configure mocks via the client callback in testServerAndClientResource options
Use ctx.client from the test resource for making tRPC calls
Access server URLs via ctx.httpUrl and ctx.wssUrl
Configure server options via the server property in testServerAndClientResource options
Configure client options via the client callback in testServerAndClientResource options
Use descriptive test names that explain the behavior under test
Focus test names on what the test validates, not just what it does
Use proper TypeScript typing for mocks
Clear mocks between tests when needed
Use factory functions for mock creation to ensure isolation

Files:

  • packages/tanstack-react-query/test/utils.test.ts
{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}}: Do not use Testing Library waitFor; use vi.waitFor instead
Tests may use non-null assertions
Tests may have unused variables
Tests may allow floating promises

Files:

  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
packages/tanstack-react-query/**/*.test.tsx

📄 CodeRabbit inference engine (.cursor/rules/tanstack-react-query-tests.mdc)

packages/tanstack-react-query/**/*.test.tsx: ALWAYS use await using ctx = testReactResource(...) to set up TanStack React Query tests
Import testReactResource from the local path ./__helpers
Do NOT import testReactResource from ./test/__helpers (wrong path)
Do NOT import legacy helpers like createAppRouter from ./__testHelpers
Use ctx.useTRPC() for TanStack React Query hooks access in components under test
Use ctx.useTRPCClient() for direct (vanilla) tRPC client access in tests
Use ctx.optionsProxyClient when testing client-side options proxy
Use ctx.optionsProxyServer when testing server-side options proxy
Render via ctx.renderApp() and rerender via ctx.rerenderApp() instead of custom providers
Import testing utilities from @testing-library/react
Import user interaction utilities from @testing-library/user-event when simulating interactions
Import React Query types from @tanstack/react-query as needed
Import TanStack React Query utilities from the package source via ../src
Import React testing utilities with import * as React from 'react';

Files:

  • packages/tanstack-react-query/test/queryKeyable.test.tsx
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPC()` for TanStack React Query hooks access in components under test
📚 Learning: 2025-09-05T15:17:32.520Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/upgrade-tests.mdc:0-0
Timestamp: 2025-09-05T15:17:32.520Z
Learning: Applies to packages/upgrade/**/*.{test,spec,trpc,snap}.tsx : Import both 'trpc/react-query' as rq (legacy) and 'trpc/tanstack-react-query' as trq (modern) when writing migration tests

Applied to files:

  • packages/tanstack-react-query/src/internals/types.ts
  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPC()` for TanStack React Query hooks access in components under test

Applied to files:

  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Wrap components with a custom App that provides trpc.Provider (legacy) and QueryClientProvider

Applied to files:

  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPCClient()` for direct (vanilla) tRPC client access in tests

Applied to files:

  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Import createTRPCReact from 'trpc/react-query' (legacy API)

Applied to files:

  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Create the tRPC React client with createTRPCReact<typeof appRouter>()

Applied to files:

  • packages/tanstack-react-query/src/internals/Context.tsx
  • packages/tanstack-react-query/test/__helpers.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.optionsProxyClient` when testing client-side options proxy

Applied to files:

  • packages/tanstack-react-query/src/internals/createOptionsProxy.ts
  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import `testReactResource` from the local path `./__helpers`

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.optionsProxyServer` when testing server-side options proxy

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Do NOT import `testReactResource` from `./test/__helpers` (wrong path)

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Do NOT import testReactResource from './__helpers' or './test/__helpers' in legacy React Query tests

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : If not using createAppRouter, you may create an inline router using testServerAndClientResource with appropriate server and client link configuration

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Manage test resources with konn(): call createAppRouter() in beforeEach and ctx?.close?.() in afterEach

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Import `testServerAndClientResource` from `trpc/client/__tests__/testClientResource`

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Use queryClient, db, and resolvers exposed by createAppRouter instead of redefining them

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Render via `ctx.renderApp()` and rerender via `ctx.rerenderApp()` instead of custom providers

Applied to files:

  • packages/tanstack-react-query/test/__helpers.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import React Query types from `tanstack/react-query` as needed

Applied to files:

  • packages/tanstack-react-query/test/utils.test.ts
  • packages/tanstack-react-query/test/queryKeyable.test.tsx
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import React testing utilities with `import * as React from 'react';`

Applied to files:

  • packages/tanstack-react-query/test/utils.test.ts
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import TanStack React Query utilities from the package source via `../src`

Applied to files:

  • packages/tanstack-react-query/test/utils.test.ts
🧬 Code graph analysis (7)
packages/tanstack-react-query/src/internals/mutationOptions.ts (1)
packages/tanstack-react-query/src/internals/utils.ts (1)
  • getClientArgs (26-46)
packages/tanstack-react-query/src/internals/Context.tsx (1)
packages/tanstack-react-query/src/internals/createOptionsProxy.ts (1)
  • createTRPCOptionsProxy (323-470)
packages/tanstack-react-query/src/internals/createOptionsProxy.ts (1)
packages/tanstack-react-query/src/internals/utils.ts (1)
  • getQueryKeyInternal (85-140)
packages/tanstack-react-query/src/internals/utils.ts (2)
packages/tanstack-react-query/src/internals/types.ts (3)
  • QueryType (81-81)
  • TRPCQueryKey (86-90)
  • TRPCMutationKey (95-98)
packages/server/src/unstable-core-do-not-import/utils.ts (1)
  • isObject (31-33)
packages/tanstack-react-query/test/__helpers.tsx (3)
packages/client/src/__tests__/testClientResource.ts (1)
  • TestServerAndClientResourceOpts (39-57)
packages/tanstack-react-query/src/internals/createOptionsProxy.ts (1)
  • createTRPCOptionsProxy (323-470)
packages/tanstack-react-query/src/internals/Context.tsx (1)
  • createTRPCContext (23-78)
packages/tanstack-react-query/test/utils.test.ts (1)
packages/tanstack-react-query/src/internals/utils.ts (1)
  • getQueryKeyInternal (85-140)
packages/tanstack-react-query/test/queryKeyable.test.tsx (1)
packages/tanstack-react-query/test/__helpers.tsx (1)
  • testReactResource (15-79)
⏰ 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). (4)
  • GitHub Check: test
  • GitHub Check: typecheck
  • GitHub Check: build
  • GitHub Check: Lint and auto-fix
🔇 Additional comments (21)
packages/tanstack-react-query/src/internals/subscriptionOptions.ts (1)

131-131: LGTM! Correctly adjusted for the new key structure.

The input location changed from queryKey[1]?.input to queryKey[2]?.input to align with the updated TRPCQueryKey structure where the prefix is now at index 0, path at index 1, and opts at index 2.

packages/tanstack-react-query/test/__helpers.tsx (3)

13-34: LGTM! Query key prefix properly threaded through test infrastructure.

The new queryKeyPrefix option is correctly propagated through testReactResource to both the options proxy and the TRPCProvider, enabling prefix testing.


38-64: LGTM! Prefix correctly propagated to render helpers.

Both renderApp and rerenderApp correctly pass opts?.queryKeyPrefix to the TRPCProvider, ensuring the prefix is available throughout the component tree.


6-7: Use import type for type-only imports.

RenderResult is used only as a type (line 52), so it should be imported with import type to comply with the coding guidelines.

Apply this diff:

 import '@testing-library/dom';
 import '@testing-library/jest-dom/vitest';
 import type { TestServerAndClientResourceOpts } from '@trpc/client/__tests__/testClientResource';
 import { testServerAndClientResource } from '@trpc/client/__tests__/testClientResource';
 import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import type { RenderResult } from '@testing-library/react';
-import { render } from '@testing-library/react';
+import { render } from '@testing-library/react';
+import type { RenderResult } from '@testing-library/react';

As per coding guidelines.

⛔ Skipped due to learnings
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import React testing utilities with `import * as React from 'react';`
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Use testing-library/react for rendering in tests
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Do NOT import `testReactResource` from `./test/__helpers` (wrong path)
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import React Query types from `tanstack/react-query` as needed
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Do NOT import testReactResource from './__helpers' or './test/__helpers' in legacy React Query tests
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Import `testServerAndClientResource` from `trpc/client/__tests__/testClientResource`
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Import getUntypedClient from 'trpc/client' when an untyped client is needed
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/upgrade-tests.mdc:0-0
Timestamp: 2025-09-05T15:17:32.520Z
Learning: Applies to packages/upgrade/**/*.{test,spec,trpc,snap}.tsx : Use testing-library/react for rendering in upgrade-package tests
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/upgrade-tests.mdc:0-0
Timestamp: 2025-09-05T15:17:32.520Z
Learning: Applies to packages/upgrade/**/*.{test,spec,trpc,snap}.tsx : Import both 'trpc/react-query' as rq (legacy) and 'trpc/tanstack-react-query' as trq (modern) when writing migration tests
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/upgrade-tests.mdc:0-0
Timestamp: 2025-09-05T15:17:32.520Z
Learning: Applies to packages/upgrade/**/*.{test,spec,trpc,snap}.tsx : Import testReactResource only from './__helpers' (when inside test files) or './test/__helpers' (from package root)
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Import testing utilities from `testing-library/react`
Learnt from: CR
PR: trpc/trpc#0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Render via `ctx.renderApp()` and rerender via `ctx.rerenderApp()` instead of custom providers
packages/tanstack-react-query/test/utils.test.ts (2)

6-22: LGTM! Correctly updated to use the new signature.

The test now calls getQueryKeyInternal with an options object { input, type } instead of positional parameters, aligning with the refactored API while maintaining the same output structure.


37-53: LGTM! Test updated for the new API.

Correctly uses the options-object signature for infinite query key construction.

packages/tanstack-react-query/src/internals/createOptionsProxy.ts (5)

285-285: LGTM! New public API option added.

The queryKeyPrefix option is correctly added to the public interface, allowing users to configure a prefix for all generated query and mutation keys.


326-333: LGTM! Prefix normalization is correct.

The code properly normalizes the queryKeyPrefix option (which can be a string or array) into a consistent array format for internal use.


367-406: LGTM! Prefix consistently propagated to query key methods.

All query-related methods (pathKey, pathFilter, queryOptions, queryKey, queryFilter) correctly pass prefix: queryKeyPrefix to getQueryKeyInternal.


409-438: LGTM! Infinite query methods correctly include prefix.

All infinite query methods (infiniteQueryOptions, infiniteQueryKey, infiniteQueryFilter) properly propagate the prefix to getQueryKeyInternal.


454-465: LGTM! Subscription options correctly include prefix.

The subscriptionOptions method properly passes prefix: queryKeyPrefix to getQueryKeyInternal.

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

86-98: LGTM! Key types updated to support prefix.

The TRPCQueryKey and TRPCMutationKey types are correctly updated to include the prefix as the first element. The use of labeled tuple elements (prefix:, path:, opts?:) improves readability and self-documentation.

Note: This is a breaking change to the public API, as existing code that destructures or accesses these key tuples by index will need updates.

packages/tanstack-react-query/src/internals/Context.tsx (2)

8-17: LGTM! Public API correctly extended.

The TRPCProvider props interface correctly includes the new optional queryKeyPrefix parameter, allowing users to configure a prefix at the provider level.


33-49: LGTM! Prefix properly propagated and memoized.

The TRPCProvider implementation correctly:

  • Accepts queryKeyPrefix in its props (line 38)
  • Passes it to createTRPCOptionsProxy (line 46)
  • Includes it in the useMemo dependency array (line 48) to recompute the proxy when the prefix changes
packages/tanstack-react-query/test/queryKeyable.test.tsx (3)

11-34: LGTM! Test helper correctly extended to support prefix.

The testContext function now accepts an optional opts parameter with queryKeyPrefix and properly forwards it to testReactResource, enabling prefix testing.


61-134: LGTM! Existing tests correctly updated for new key structure.

The snapshots now show an empty array [] as the first element (the prefix) in all query keys, which is correct for tests without a configured prefix.


336-419: LGTM! New test suite validates prefixed query keys.

The test suite correctly validates that when queryKeyPrefix: 'user-123' is configured, all generated keys include ["user-123"] as the prefix element.

Consider adding a test case for prefixed mutation keys within this suite to ensure mutations also respect the prefix (similar to the query key tests). For example:

expect(trpc.bluesky.post.create.mutationKey()).toMatchInlineSnapshot(`
  Array [
    Array [
      "user-123",
    ],
    Array [
      "bluesky",
      "post",
      "create",
    ],
  ]
`);

This would help catch the mutation key prefix bug identified in the earlier review comments.

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

34-35: LGTM! Array indices correctly adjusted for prefix.

The index updates properly account for the new key structure where prefix is now at index 0.


85-92: LGTM! Options object pattern improves signature.

Refactoring to an options object is a good choice as the parameter count grows, making the function more maintainable.


111-129: LGTM! Infinite query handling correctly includes prefix.

The logic properly removes cursor and direction from the input while maintaining the correct key structure with prefix.


131-139: LGTM! Default case properly constructs key with prefix.

The conditional inclusion of input and type fields is handled correctly, and the prefix is properly integrated into the key structure.

@Nick-Lucas Nick-Lucas requested a review from a team as a code owner October 17, 2025 15:49
@railway-app railway-app bot temporarily deployed to next-sse-chat (trpc-sse-and-websockets / trpc-pr-6976) October 17, 2025 15:49 Destroyed
@railway-app railway-app bot temporarily deployed to next-prisma-websockets-starter (trpc-sse-and-websockets / trpc-pr-6976) October 17, 2025 15:49 Destroyed
@railway-app railway-app bot temporarily deployed to next-sse-chat (trpc-sse-and-websockets / trpc-pr-6976) October 17, 2025 15:50 Destroyed
@railway-app railway-app bot temporarily deployed to next-prisma-websockets-starter (trpc-sse-and-websockets / trpc-pr-6976) October 17, 2025 15:50 Destroyed
@railway-app railway-app bot temporarily deployed to next-sse-chat (trpc-sse-and-websockets / trpc-pr-6976) October 25, 2025 14:55 Destroyed
@railway-app railway-app bot temporarily deployed to next-prisma-websockets-starter (trpc-sse-and-websockets / trpc-pr-6976) October 25, 2025 14:55 Destroyed
@railway-app railway-app bot temporarily deployed to next-sse-chat (trpc-sse-and-websockets / trpc-pr-6976) October 25, 2025 14:56 Destroyed
@railway-app railway-app bot temporarily deployed to next-prisma-websockets-starter (trpc-sse-and-websockets / trpc-pr-6976) October 25, 2025 14:56 Destroyed
cursor[bot]

This comment was marked as outdated.

@railway-app railway-app bot temporarily deployed to next-sse-chat (trpc-sse-and-websockets / trpc-pr-6976) October 25, 2025 15:00 Destroyed
@railway-app railway-app bot temporarily deployed to next-prisma-websockets-starter (trpc-sse-and-websockets / trpc-pr-6976) October 25, 2025 15:00 Destroyed
KATT
KATT approved these changes Oct 25, 2025
@github-actions
Copy link
Contributor

This pull request has been locked because we are very unlikely to see comments on closed issues. If you think, this PR is still necessary, create a new one with the same branch. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: overwrite query key on trpc.useQuery options

5 participants