Skip to content

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Dec 21, 2025

also implement perf optimizations

Summary by CodeRabbit

  • New Features

    • Added support for deeper nested re-export chains for server-side functions, enabling middleware and context to flow through multi-level exports.
  • Improvements

    • Compiler and resolution performance optimizations with parallel candidate resolution and faster lookup paths.
    • Internal API and rewrite logic streamlined for more reliable transformation.
  • Tests

    • New end-to-end and unit tests covering nested re-exports and both fast/slow resolution paths.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

Walkthrough

Adds a three-stage nested re-export chain (A → B → C) for a server-function factory with middleware and corresponding e2e test; simultaneously refactors the create-server-fn compiler to use precomputed maps, parallel candidate resolution, a MethodChain/RewriteCandidate model, and updates handler/middleware rewrite APIs to accept RewriteCandidate.

Changes

Cohort / File(s) Summary
Nested re-export modules
e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportA.ts, e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportB.ts, e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportC.ts
Added three files forming A → B → C re-export chain. nestedReexportC.ts defines nestedReexportFactory (GET) with a middleware that sets context.nested, nestedReexportB and nestedReexportA re-export downstream exports.
Factory usage & export
e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts, e2e/react-start/server-functions/src/routes/factory/index.tsx
Added nestedReexportedFactoryFn by wiring the re-exported factory through a handler returning { name, context }; exposed in the UI/test map with expected context payload.
E2E test
e2e/react-start/server-functions/tests/server-functions.spec.ts
Added test verifying nested star re-exported factory middleware runs and context contains 'nested-middleware-executed', asserting context equality as in existing tests.
Compiler: core rewrite & resolution
packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts
Reworked candidate discovery to use IdentifierToKind lookups and knownRootImports, collect call paths in a single pass, resolve candidates in parallel into a Map, aggregate a methodChain per candidate, added recursive findExportInModule to follow export * chains, and optimized expression unwrapping and callee resolution.
Compiler: types for rewriting
packages/start-plugin-core/src/create-server-fn-plugin/types.ts
Added MethodCallInfo, MethodChainPaths, MethodChainKey, METHOD_CHAIN_KEYS, and RewriteCandidate to represent collected call paths and first-arg paths for rewrite operations.
Rewrite handlers updated
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts, packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
Changed APIs to accept RewriteCandidate (with methodChain) instead of Babel NodePath, removed root traversal logic, and updated rewrite/removal logic to operate directly on candidate.methodChain entries; adjusted signatures and error reporting accordingly.
Tests: compiler path-selection
packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts, packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
Added fast/slow path tests for resolveId invocation counts (direct known imports vs. re-exported factory modules); added vitest vi usage for mocking.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test Runner / Browser
    participant UI as Factory UI Route
    participant Server as Dev Server / Route Handler
    participant Compiler as start-plugin-core Compiler
    participant FS as Module Filesystem
    participant Middleware as Middleware (nestedReexportC)

    Test->>UI: Click nestedReexportedFactoryFn button
    UI->>Server: Invoke factory endpoint
    Server->>Compiler: Ensure compiled factory (resolve imports)
    Compiler->>FS: Resolve import graph (A -> B -> C) using findExportInModule
    FS-->>Compiler: Return resolved factory symbol (from nestedReexportC)
    Compiler-->>Server: Emit compiled handler bound to factory (with middleware)
    Server->>Middleware: Execute middleware (adds context.nested)
    Middleware-->>Server: Continue to handler with augmented context
    Server-->>Test: Respond with name + context (contains nested-middleware-executed)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Areas requiring extra attention:

  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts — parallel resolution, findExportInModule, and map-based rewrite aggregation.
  • types.ts + use sites — verify MethodChainPaths fields and firstArgPath nullability handling.
  • handleCreateServerFn.ts / handleCreateMiddleware.ts — ensure replacements/removals operate correctly on candidate.methodChain and maintain correct error locations/codeFrameError usage.
  • E2E additions — confirm test selectors and expected payloads align with the new middleware behavior.

Possibly related PRs

Suggested reviewers

  • chorobin

Poem

🐰 Three hops, three files, a nested trail,
Middleware whispers a tiny tale,
Compiler maps and chases the thread,
Exports align where the code is led,
I nibble tests — all green ahead! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: trace nested server function factory re-export chain' accurately captures the main objective of the PR, which adds support for tracing nested re-export chains (A->B->C) in server function factories with corresponding compiler optimizations.
✨ 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 fix-serverfn-compiler

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b43fe8e and 335d039.

📒 Files selected for processing (5)
  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (11 hunks)
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (2 hunks)
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (5 hunks)
  • packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts (2 hunks)
  • packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
  • packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts
  • packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
  • packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts
  • packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts
🧠 Learnings (2)
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts
  • packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts
  • packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
🧬 Code graph analysis (2)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (1)
packages/start-plugin-core/src/create-server-fn-plugin/types.ts (1)
  • RewriteCandidate (39-42)
packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (3)
packages/start-plugin-core/src/create-server-fn-plugin/types.ts (2)
  • MethodChainPaths (18-24)
  • RewriteCandidate (39-42)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (1)
  • handleCreateServerFn (11-145)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (1)
  • handleCreateMiddleware (10-45)
⏰ 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 (29)
packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts (3)

3-3: LGTM!

Adding vi import to support mocking resolveId in the new tests.


218-255: LGTM! Well-structured test for the fast path optimization.

The test correctly verifies that direct imports from known libraries (@tanstack/react-start) use the O(1) knownRootImports lookup, resulting in only a single resolveId call during initialization.


257-311: LGTM! Comprehensive test for the slow path resolution.

The test properly simulates the factory pattern where createServerFn is re-exported from a local module. The use of ingestModule within loadModule accurately models how the compiler resolves re-exported bindings through the module graph.

The comment on lines 302-303 correctly explains why the factory module's import from @tanstack/react-start doesn't trigger an additional resolveId call (it uses the fast path).

packages/start-plugin-core/tests/createMiddleware-create-server-fn-plugin/createMiddleware.test.ts (3)

3-3: LGTM!

Adding vi import for mocking support.


63-100: LGTM! Consistent test coverage for middleware fast path.

The test validates that createMiddleware also benefits from the O(1) knownRootImports lookup for direct imports.


102-156: LGTM! Factory pattern test for middleware.

Appropriately mirrors the createServerFn slow path test, ensuring consistent resolution behavior across both ServerFn and Middleware kinds.

packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (3)

1-3: LGTM!

Clean import updates to support the new candidate-based API with proper typing via RewriteCandidate.


4-14: LGTM! Good documentation and simplified signature.

The JSDoc provides clear parameter descriptions, and the signature refactor to accept RewriteCandidate improves API consistency across handlers.


20-44: LGTM! Cleaner path access via methodChain.

The refactor eliminates the need for path traversal by directly accessing inputValidator and server from candidate.methodChain. The replacement logic correctly unwraps the call expression by replacing it with the callee's object.

packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (14)

45-53: LGTM! Good optimization with pre-computed map.

Pre-computing IdentifierToKind at module load time enables O(1) candidate detection in isCandidateCallExpression, avoiding repeated iteration over lookupKinds.


73-76: LGTM! Well-documented fast path map.

The comment clearly explains the purpose and data structure of knownRootImports for O(1) direct import resolution.


126-133: LGTM!

Correctly populates the fast lookup map during initialization, enabling the fast path for subsequent compile calls.


273-290: LGTM! Parallel candidate resolution improves performance.

Using Promise.all to resolve all candidates concurrently is an appropriate optimization. The subsequent filtering with toRewriteMap correctly identifies valid lookup kinds.


300-310: LGTM! Efficient path collection.

Pre-collecting all CallExpression paths into a map enables O(1) lookup during method chain construction, avoiding repeated traversals.


319-361: LGTM! Correct method chain construction.

The downward walk through the call chain correctly populates methodChain with path references. The while (true) loop is properly bounded by the break conditions when encountering non-member-expressions or non-call-expressions.


363-368: Verify path count matches expectations.

The size comparison ensures all candidates were resolved to paths. This is a good sanity check.

Consider adding more context to the error message to help debugging:

-    if (pathsToRewrite.length !== toRewriteMap.size) {
+    if (pathsToRewrite.length !== toRewriteMap.size) {
       throw new Error(
-        `Internal error: could not find all paths to rewrite. please file an issue`,
+        `Internal error: could not find all paths to rewrite (found ${pathsToRewrite.length}/${toRewriteMap.size}). please file an issue`,
       )
     }

372-386: LGTM! Clean handler invocation with RewriteCandidate.

Creating the RewriteCandidate object inline and passing it to the appropriate handler based on kind is clean and type-safe.


447-496: LGTM! Robust re-export chain resolution with cycle detection.

The findExportInModule implementation correctly:

  1. Uses visitedModules to prevent infinite loops in circular re-exports
  2. Checks direct exports first before traversing re-export chains
  3. Uses parallel resolution via Promise.all for efficiency
  4. Returns the first valid result, which is correct since "valid code won't have duplicate exports across chains"

507-517: LGTM! Effective fast path for known library imports.

Short-circuiting resolution for known direct imports avoids async resolveId calls in the common case, providing significant performance improvement for typical usage patterns.


527-549: LGTM! Correct integration of findExportInModule.

The slow path now properly uses findExportInModule to resolve exports through export * from chains, then continues resolution on the found binding.


570-577: LGTM! Efficient TS wrapper unwrapping.

Unwrapping TypeScript wrappers (TSAsExpression, TSNonNullExpression) and parenthesized expressions upfront reduces repetitive checks in subsequent logic.


590-596: LGTM! Simplified kind checking.

Direct Set.has() call replaces iteration, improving efficiency.


699-711: LGTM! Optimized candidate detection.

Using the pre-computed IdentifierToKind map for O(1) lookup instead of iterating over lookupKinds is a good optimization.

packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (6)

1-3: LGTM!

Clean import updates for the candidate-based API with proper typing.


5-22: LGTM! Comprehensive JSDoc documentation.

The documentation clearly explains the function's purpose and the isProviderFile parameter's significance for controlling handler implementation placement.


24-41: LGTM! Improved error messages with location context.

Using codeFrameError with variableDeclarator.id.loc! provides better developer experience by pointing to the exact location of the issue in destructuring patterns.


43-60: LGTM! Clean inputValidator handling.

Accessing inputValidator.callPath.node.arguments[0] directly is cleaner than path-based traversal. The client-side replacement logic correctly unwraps the call expression.


65-82: LGTM! Robust handler validation.

The explicit type guard t.isExpression(handlerFnPath.node) with a descriptive error message helps catch misuse of the handler API (e.g., passing spread elements).


142-144: LGTM!

Correctly pushes the handler function as a second argument only for provider files, avoiding code duplication in caller files.


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

@nx-cloud
Copy link

nx-cloud bot commented Dec 21, 2025

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 335d039

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 13m 57s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 20s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-21 00:43:52 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 21, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6166

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@6166

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6166

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6166

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6166

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6166

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6166

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6166

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6166

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6166

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6166

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6166

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6166

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6166

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6166

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6166

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6166

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6166

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6166

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6166

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@6166

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6166

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6166

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6166

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6166

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6166

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6166

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6166

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6166

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6166

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6166

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6166

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6166

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6166

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6166

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6166

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6166

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6166

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6166

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6166

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6166

commit: 335d039

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: 0

🧹 Nitpick comments (4)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (1)

39-44: Inconsistent guard condition between inputValidator and server checks.

Line 22 checks if (inputValidator), but line 39 checks if (server && server.firstArgPath?.node). The server.firstArgPath?.node check seems unnecessary since the removal logic (lines 41-43) only uses server.callPath, not firstArgPath. This could silently skip valid server call expressions that have no arguments.

Consider aligning with the inputValidator pattern:

Proposed fix
-  if (server && server.firstArgPath?.node) {
+  if (server) {
     // remove the server call expression
     if (t.isMemberExpression(server.callPath.node.callee)) {
       server.callPath.replaceWith(server.callPath.node.callee.object)
     }
   }
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (2)

33-34: Unsafe type assertion on variable declarator id.

The assertion (variableDeclarator.id as t.Identifier).name assumes the variable declarator always uses a simple identifier. This would fail for destructuring patterns like const { fn } = ... or const [fn] = ....

Consider adding a guard:

Proposed fix
   const variableDeclarator = path.parentPath.node
-  const existingVariableName = (variableDeclarator.id as t.Identifier).name
+  if (!t.isIdentifier(variableDeclarator.id)) {
+    throw new Error('createServerFn must be assigned to a simple variable, not a destructuring pattern!')
+  }
+  const existingVariableName = variableDeclarator.id.name

58-68: Type assertion on firstArgPath.node may be unsafe.

Line 68 casts handlerFnPath.node as t.Expression, but firstArgPath is typed as babel.NodePath | null which could point to any node type (e.g., SpreadElement). While the validation on line 60 checks for existence, it doesn't verify the node type.

Consider adding explicit type validation:

Proposed fix
-  const handlerFn = handlerFnPath.node as t.Expression
+  if (!t.isExpression(handlerFnPath.node)) {
+    throw codeFrameError(
+      opts.code,
+      path.node.callee.loc!,
+      `createServerFn handler must be an expression!`,
+    )
+  }
+  const handlerFn = handlerFnPath.node
packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (1)

359-372: Passing entire object p instead of structured RewriteCandidate.

The handlers expect a RewriteCandidate with path and methodChain properties. The object p has { path, kind, methodChain }, which includes an extra kind property. This works due to structural typing, but could be cleaner.

Optional: Extract RewriteCandidate explicitly
     if (p.kind === 'ServerFn') {
-      handleCreateServerFn(p, {
+      handleCreateServerFn({ path: p.path, methodChain: p.methodChain }, {
         env: this.options.env,
         code,
         directive: this.options.directive,
         isProviderFile,
       })
     } else {
-      handleCreateMiddleware(p, {
+      handleCreateMiddleware({ path: p.path, methodChain: p.methodChain }, {
         env: this.options.env,
       })
     }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75e1387 and b43fe8e.

📒 Files selected for processing (10)
  • e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts (2 hunks)
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportA.ts (1 hunks)
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportB.ts (1 hunks)
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportC.ts (1 hunks)
  • e2e/react-start/server-functions/src/routes/factory/index.tsx (2 hunks)
  • e2e/react-start/server-functions/tests/server-functions.spec.ts (1 hunks)
  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (9 hunks)
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (2 hunks)
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (5 hunks)
  • packages/start-plugin-core/src/create-server-fn-plugin/types.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • e2e/react-start/server-functions/tests/server-functions.spec.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/types.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportB.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportA.ts
  • e2e/react-start/server-functions/src/routes/factory/index.tsx
  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportC.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • e2e/react-start/server-functions/tests/server-functions.spec.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/types.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportB.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
  • packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportA.ts
  • e2e/react-start/server-functions/src/routes/factory/index.tsx
  • packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts
  • e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportC.ts
🧠 Learnings (1)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • e2e/react-start/server-functions/tests/server-functions.spec.ts
  • e2e/react-start/server-functions/src/routes/factory/index.tsx
🧬 Code graph analysis (4)
e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts (1)
e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportC.ts (1)
  • nestedReexportFactory (18-20)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (1)
packages/start-plugin-core/src/create-server-fn-plugin/types.ts (1)
  • RewriteCandidate (39-42)
e2e/react-start/server-functions/src/routes/factory/index.tsx (1)
e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts (1)
  • nestedReexportedFactoryFn (123-130)
packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (3)
packages/start-plugin-core/src/create-server-fn-plugin/types.ts (1)
  • MethodChainPaths (18-24)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (1)
  • handleCreateServerFn (11-129)
packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (1)
  • handleCreateMiddleware (10-45)
⏰ 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 (26)
e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportC.ts (2)

1-16: LGTM! Well-documented middleware implementation.

The JSDoc clearly explains the position in the re-export chain, and the middleware implementation correctly augments the context with type-safe values using as const.


18-20: LGTM! Factory configuration is correct.

The server function factory is properly configured with the GET method and middleware attachment, following the established pattern in the codebase.

e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportA.ts (1)

1-7: LGTM! Clean re-export with clear documentation.

The JSDoc clearly documents this module's role as the top-level entry point in the nested re-export chain, and the re-export syntax is correct.

e2e/react-start/server-functions/src/routes/factory/-functions/nestedReexportB.ts (1)

1-7: LGTM! Clean re-export with clear documentation.

The JSDoc clearly documents this module's role as the middle link in the nested re-export chain, and the re-export syntax is correct.

e2e/react-start/server-functions/src/routes/factory/index.tsx (2)

15-15: LGTM! Import is correctly added.

The import of nestedReexportedFactoryFn is properly placed with other factory function imports.


156-165: LGTM! Test case configuration is correct and well-documented.

The test case properly configures the expected behavior for the nested re-export chain, with expected context matching the middleware output from nestedReexportC.ts. The comment clearly explains the A -> B -> C chain pattern.

e2e/react-start/server-functions/tests/server-functions.spec.ts (1)

595-617: LGTM! Comprehensive e2e test for nested re-export chain.

The test properly verifies that middleware executes correctly through the A -> B -> C nested re-export chain. The test pattern is consistent with existing re-export tests and includes appropriate assertions for both the middleware context and result comparison.

e2e/react-start/server-functions/src/routes/factory/-functions/functions.ts (2)

9-10: LGTM! Import correctly references the top of the re-export chain.

The import properly starts from nestedReexportA, which is the entry point of the A -> B -> C chain, and the comment clearly explains the test scenario.


121-130: LGTM! Factory function implementation is correct and consistent.

The nestedReexportedFactoryFn implementation follows the established pattern for factory-based server functions, properly accessing the middleware context and returning the expected structure for testing.

packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts (2)

2-3: LGTM!

Clean import structure with the new RewriteCandidate type from the types module.


10-18: LGTM!

The function signature refactor to accept RewriteCandidate is well-documented and the server environment guard is appropriate.

packages/start-plugin-core/src/create-server-fn-plugin/types.ts (3)

1-12: LGTM!

Well-structured type definitions with appropriate JSDoc documentation. The MethodCallInfo interface cleanly captures the call path and optional first argument path.


14-34: LGTM!

The MethodChainPaths interface and METHOD_CHAIN_KEYS constant provide a clear contract for the method chain structure. Using ReadonlyArray with as const ensures immutability.


36-42: LGTM!

The RewriteCandidate interface cleanly encapsulates the path and method chain information needed for rewrite operations.

packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts (3)

2-3: LGTM!

Clean import updates for the new type structure.


11-25: LGTM!

Well-documented function signature with the new directive field and clear JSDoc for isProviderFile.


103-120: LGTM!

The handler replacement logic correctly constructs the arrow function with the 'use server' directive and references the original variable name for __executeServer.

packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts (9)

45-53: LGTM!

Good performance optimization with pre-computed IdentifierToKind map enabling O(1) candidate detection instead of iterating over lookup kinds.


261-276: LGTM!

Parallel resolution of candidates using Promise.all is a sound performance improvement. The subsequent filtering into toRewriteMap correctly handles the resolved results.


288-298: LGTM!

Collecting all CallExpression paths into a Map for O(1) lookup is an effective optimization that avoids repeated AST traversals.


316-348: Method chain walking logic looks correct.

The downward traversal through the call chain correctly collects method call info for each known method name. The use of callExprPaths.get(currentNode)! is safe here since these nodes were collected in the prior traversal.

One minor observation: if a method appears multiple times in the chain (e.g., .handler().handler()), only the outermost occurrence is recorded since the inner one would overwrite. This appears intentional given the fluent API design.


350-355: LGTM!

Good defensive check ensuring all candidates were successfully resolved to paths.


429-482: LGTM!

The findExportInModule method correctly implements recursive export resolution through export * from chains with:

  • Cycle detection via visitedModules set
  • Parallel resolution of re-export sources for performance
  • First-match-wins semantics appropriate for valid code without duplicate exports

453-478: Parallel resolution may mask errors from failed module loads.

If one re-export source fails to resolve while another succeeds, the error is silently ignored and the first valid result is returned. This is likely intentional for robustness, but could mask configuration issues during development.

Consider whether failed resolutions should be logged at debug level for troubleshooting.


543-550: LGTM!

Efficiently unwrapping TypeScript wrapper expressions (TSAsExpression, TSNonNullExpression, ParenthesizedExpression) before processing improves resolution efficiency by avoiding repeated checks.


669-686: LGTM!

The refactored isCandidateCallExpression correctly uses the pre-computed IdentifierToKind map for O(1) lookup, improving performance over the previous iteration-based approach.

@schiller-manuel schiller-manuel merged commit e8f2174 into main Dec 21, 2025
5 of 6 checks passed
@schiller-manuel schiller-manuel deleted the fix-serverfn-compiler branch December 21, 2025 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants