Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Sep 11, 2025

Just to make it easier to tweak the values and understand the scales / functions, we extract all score modifiers to constants w/ descriptive names.

This PR is a no-op, no logic was modified.

Summary by CodeRabbit

  • Bug Fixes

    • Improved route matching accuracy by prioritizing routes with static segments that appear after dynamic parameters.
    • More predictable matching in complex paths; reduces unexpected selections.
    • Wildcard routes handled more consistently.
  • Refactor

    • Updated internal route scoring to consider deeper static segments without changing the public API.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Walkthrough

Refactors route scoring in process-route-tree to use new constants and a full lookahead for dynamic parameters, adding a bonus when any subsequent static segment exists. Standardizes PATHNAME scoring, handles wildcard via general branch, and removes fallback scoring quirks without changing public APIs.

Changes

Cohort / File(s) Summary of changes
Routing score computation
packages/router-core/src/process-route-tree.ts
Introduced SLASH_SCORE, STATIC_SEGMENT_SCORE, and STATIC_AFTER_DYNAMIC_BONUS_SCORE. Standardized PATHNAME scoring. Reworked dynamic-param scoring to scan all subsequent segments for static pathnames and apply a bonus when found. Simplified wildcard handling and removed inconsistent fallback return paths. No public API changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App as App
  participant Router as Router
  participant Processor as RouteProcessor
  participant Scorer as SegmentScorer

  App->>Router: register routes / resolve request
  Router->>Processor: processRouteTree(segments)
  loop for each segment
    Processor->>Scorer: score(segment)
    alt PATHNAME
      Scorer-->>Processor: STATIC_SEGMENT_SCORE or SLASH_SCORE
    else Dynamic Param
      Scorer->>Scorer: scan subsequent segments
      alt any subsequent static pathname exists
        Note right of Scorer: Apply STATIC_AFTER_DYNAMIC_BONUS_SCORE
        Scorer-->>Processor: baseScore + bonus via handleParam
      else none found
        Scorer-->>Processor: baseScore via handleParam
      end
    else Wildcard/Other
      Scorer-->>Processor: baseScore via general branch
    end
  end
  Processor-->>Router: ranked routes
  Router-->>App: selected route
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • schiller-manuel

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 succinctly describes the primary change: refactoring router-core's processRouteTree sorting to use constants for score modifiers. It explicitly names the affected package and the intent, which matches the PR description and the raw summary about extracting scoring constants. The phrasing is concise and clear enough for a reviewer scanning history to understand the main change.

Poem

A bunny hops through paths so wide,
Sniffs static signs where routes abide;
A bonus nibble after dash,
Dynamic burrows, swift as flash.
With every slash and name in view,
I rank the trails—then hop on through! 🐇✨

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-router-core-process-route-tree-score-variables

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

@nx-cloud
Copy link

nx-cloud bot commented Sep 11, 2025

View your CI Pipeline Execution ↗ for commit fc8b367

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 4m 19s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 33s View ↗

☁️ Nx Cloud last updated this comment at 2025-09-11 16:53:01 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 11, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-plugin

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-plugin

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-server-functions-client

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

@tanstack/start-server-functions-fetcher

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

@tanstack/start-server-functions-server

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: fc8b367

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/router-core/src/process-route-tree.ts (4)

13-18: Good extraction of scoring knobs; add brief rationale docstrings.

Constants make tuning explicit. Add 1–2 line comments on why 0.75/1/0.2 were chosen to help future maintainers adjust safely.


85-91: Unify PATHNAME and slash handling to one branch.

Slightly simplifies control flow and ensures slash is only treated when type is PATHNAME.

-      if (segment.value === '/') {
-        return SLASH_SCORE
-      }
-
-      if (segment.type === SEGMENT_TYPE_PATHNAME) {
-        return STATIC_SEGMENT_SCORE
-      }
+      if (segment.type === SEGMENT_TYPE_PATHNAME) {
+        return segment.value === '/' ? SLASH_SCORE : STATIC_SEGMENT_SCORE
+      }

99-101: Prefer explicit wildcard handling over a catch-all else.

Future segment types will be accidentally scored as wildcard. Handle the wildcard explicitly and make unknown types obvious.

-      } else {
-        baseScore = WILDCARD_PARAM_BASE_SCORE
-      }
+      } else if (segment.type === SEGMENT_TYPE_WILDCARD) {
+        baseScore = WILDCARD_PARAM_BASE_SCORE
+      } else {
+        baseScore = 0 // unknown type; intentionally lowest score
+      }

Add the missing import:

// top of file
import { SEGMENT_TYPE_WILDCARD } from './path'

103-117: Guard the dynamic lookahead bonus to params only; avoid awarding wildcard and rename inner loop index.

Comment says the boost is for required/optional params, but current code applies to any non-PATHNAME (including wildcard). Guard it and avoid shadowing outer i.

-      // if there is any static segment (that is not an index) after a required / optional param,
-      // we will boost this param so it ranks higher than a required/optional param without a static segment after it
-      // JUST FOR SORTING, NOT FOR MATCHING
-      for (let i = index + 1; i < parsed.length; i++) {
-        const nextSegment = parsed[i]!
-        if (
-          nextSegment.type === SEGMENT_TYPE_PATHNAME &&
-          nextSegment.value !== '/'
-        ) {
-          hasStaticAfter = true
-          return handleParam(
-            segment,
-            baseScore + STATIC_AFTER_DYNAMIC_BONUS_SCORE,
-          )
-        }
-      }
-
-      return handleParam(segment, baseScore)
+      // Only boost required/optional params when a later static segment exists (not index '/')
+      if (
+        segment.type === SEGMENT_TYPE_PARAM ||
+        segment.type === SEGMENT_TYPE_OPTIONAL_PARAM
+      ) {
+        for (let j = index + 1; j < parsed.length; j++) {
+          const nextSegment = parsed[j]!
+          if (
+            nextSegment.type === SEGMENT_TYPE_PATHNAME &&
+            nextSegment.value !== '/'
+          ) {
+            hasStaticAfter = true
+            return handleParam(
+              segment,
+              baseScore + STATIC_AFTER_DYNAMIC_BONUS_SCORE,
+            )
+          }
+        }
+      }
+      return handleParam(segment, baseScore)

Optional: precompute a suffix array like hasStaticAfterFrom[i] in O(n) to avoid O(n^2) scans per route if paths get long.

Also applies to: 120-120

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d6cb80 and fc8b367.

📒 Files selected for processing (1)
  • packages/router-core/src/process-route-tree.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/router-core/src/process-route-tree.ts (1)
packages/router-core/src/path.ts (1)
  • SEGMENT_TYPE_PATHNAME (6-6)
⏰ 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

@Sheraff Sheraff merged commit d681a0c into main Sep 11, 2025
6 checks passed
@Sheraff Sheraff deleted the refactor-router-core-process-route-tree-score-variables branch September 11, 2025 16:57
LadyBluenotes pushed a commit to LadyBluenotes/router that referenced this pull request Sep 19, 2025
…l score modifiers (TanStack#5131)

Just to make it easier to tweak the values and understand the scales /
functions, we extract all score modifiers to constants w/ descriptive
names.

This PR is a no-op, no logic was modified.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- Bug Fixes
- Improved route matching accuracy by prioritizing routes with static
segments that appear after dynamic parameters.
- More predictable matching in complex paths; reduces unexpected
selections.
  - Wildcard routes handled more consistently.

- Refactor
- Updated internal route scoring to consider deeper static segments
without changing the public API.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
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