Skip to content

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Nov 1, 2025

Warning

DO NOT MERGE

Design exploration of a rewrite of processRouteTree to yield a trie-like tree of segments. This should replace

  • packages/router-core/src/process-route-tree.ts
  • parts of packages/router-core/src/path.ts

Goals:

  • faster pre-processing at start-time
  • faster matching at run-time
  • more consistent priority matching

Non-goals:

  • low RAM usage

to-do:

  • fix "off-by-1" (leading/trailing /)
  • implement sorting of same-type siblings at the node level (case sensitivity, prefix/suffix length)
  • implement single-match ("does A match B")
  • implement all-route-match ("which route does A match")
  • bench pre-processing against current implementation
  • bench single-match against current implementation
  • bench all-route-match against current implementation
  • fix not found page

Bench:

  • pre-processing
    • consistently >2x faster
  • needle-in-a-haystack route matching
    • for very small route trees: 3.5x faster
    • for very large route trees: 950x faster (430 routes)
    • non-matching: 90x faster (430 routes, random path "that almost matches" requested, this is a worst-case-scenario simulation)
  • 1-to-1 route matching (useMatchRoute)
    • for very simple routes: 1.5x slower
    • for very complex routes: 1x
  • resolvePath
    • 2.7x faster (added a LRU cache to this, it's called a lot and is easy to cache, but function itself could be improved)
  • interpolatePath
    • 1.4x faster

Notes:

  • in its current implementation, 1-to-1 route matching (useMatchRoute) does not care about the routeTree. It will match 2 arbitrary strings. This can lead to unexpected results, and is probably not the behavior we want in the long term.
    For now, this PR implements findSingleMatch to preserve that behavior, and this method is slower than the current implementation. However, when we switch to matching against the routeTree (using findRouteMatch instead), it will be faster.

Summary by CodeRabbit

  • Deprecations

    • The caseSensitive option on match-route options is deprecated; configure case sensitivity on routes or the router instead.
  • Breaking Changes

    • Legacy path parsing/matching exports and related types removed in favor of the new pipeline.
  • New Features

    • New processed route-tree matcher and updated path resolution/interpolation for improved matching and param handling.
  • Tests / Quality

    • Extensive new unit tests for the route-tree matcher; tests updated to the new APIs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 1, 2025

Walkthrough

This PR replaces legacy path parsing/matching and flat route lists with a segment-tree based route processor, adds a new route-tree implementation and tests, removes several path-related public exports, updates RouterCore to use a ProcessedTree, and marks MatchRouteOptions.caseSensitive as deprecated in docs and JSDoc.

Changes

Cohort / File(s) Summary
Documentation & Deprecation
docs/router/framework/react/api/router/MatchRouteOptionsType.md, packages/router-core/src/Matches.ts
caseSensitive?: boolean in MatchRouteOptions annotated as deprecated; JSDoc updated to recommend route-level or router-wide case sensitivity configuration.
Removed Legacy Route Processor
packages/router-core/src/process-route-tree.ts
Entire file removed — old route-tree building, scoring, sorting, flat route generation, and related exported types/functions deleted.
New Route Processing Module
packages/router-core/src/new-process-route-tree.ts
New segment-based parsing and matching subsystem: parsing primitives (parseSegment), node types/factories, tree sorting, processing APIs (processRouteTree, processFlatRouteList, findRouteMatch, findFlatMatch, findSingleMatch, trimPathRight) and related types exported.
Path Utilities Refactor
packages/router-core/src/path.ts
Rewrote path utilities to string-based model; removed old parsing/matching exports (parsePathname, matchPathname, matchByPath, Segment, segment constants); added joinPaths, cleanPath, trimPath*, removeTrailingSlash, exactPathTest, resolvePath; interpolatePath reimplemented to use new segment parsing.
Router Core Migration
packages/router-core/src/router.ts
Replaced public flatRoutes with processedTree: ProcessedTree<...>; updated imports and matching calls to use new-process-route-tree APIs; simplified GetMatchRoutesFn to take only pathname and return foundRoute.
Barrel & Public Exports
packages/router-core/src/index.ts, packages/react-router/src/index.tsx, packages/solid-router/src/index.tsx
Removed re-exports: parsePathname, matchPathname, matchByPath, Segment, and process-route-tree related types/functions from public barrels and framework packages.
Call Site Adjustments
packages/react-router/src/useBlocker.tsx, packages/solid-router/src/useBlocker.tsx, packages/start-server-core/src/createStartHandler.ts
Simplified calls to router.getMatchedRoutes by dropping an explicit undefined second argument (now called with only pathname).
HMR & Plugin Updates
packages/router-plugin/src/core/route-hmr-statement.ts
Updated imports to include AnyRouter; replaced flatRoutes in-place swap with segment-tree walk/replace (walkReplaceSegmentTree) to update processedTree nodes and clear caches.
Devtools Surface
packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx
Removed flatRoutes key from public explorerState shaping; explorer no longer exposes flatRoutes.
Tests: New & Updated
packages/router-core/tests/new-process-route-tree.test.ts, packages/router-core/tests/*.test.ts
Added extensive tests for new-process-route-tree; updated tests to import parsing/matching primitives from new-process-route-tree and path changes; some tests recreate match helpers using processRouteTree and findSingleMatch.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Router
    participant Old as "Old Processor\n(process-route-tree)"
    participant New as "New Processor\n(new-process-route-tree)"

    rect rgb(240,228,228)
    Note over Old: Legacy flow (removed)
    User->>Router: buildRouteTree(routeTree)
    Router->>Old: processRouteTree(routeTree)
    Old->>Old: sort & flatten routes
    Old-->>Router: flatRoutes
    User->>Router: getMatchedRoutes(pathname, routePathname)
    Router->>Old: matchPathname / matchByPath
    Old-->>Router: matchedRoutes
    end

    rect rgb(228,240,232)
    Note over New: New flow (added)
    User->>Router: buildRouteTree(routeTree)
    Router->>New: processRouteTree(routeTree, caseSensitive)
    New->>New: parseSegments -> build segment tree
    New-->>Router: processedTree
    User->>Router: getMatchedRoutes(pathname)
    Router->>New: findRouteMatch(pathname, processedTree)
    New->>New: DFS traversal, extract params
    New-->>Router: matchedRoutes + foundRoute + params
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

  • Pay special attention to:
    • packages/router-core/src/new-process-route-tree.ts — algorithmic complexity: parsing, trie construction, matching, params extraction.
    • packages/router-core/src/path.ts — refactor of interpolation/resolution semantics.
    • packages/router-core/src/router.ts — API/signature changes and state migration to processedTree.
    • Cross-package re-exports and test updates to ensure no removed symbols remain referenced.

Possibly related PRs

Suggested reviewers

  • schiller-manuel
  • nlynzaad

Poem

🐇
I hopped the branches, carved a tree,
Turned flat lists into roots for me.
Segments tucked in leaf and vine —
I traced your path and found the line. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.93% 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
Title check ✅ Passed The title clearly and specifically describes the main refactoring: replacing the flatRoutes representation with a segment tree in the router-core's processRouteTree function.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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 refactor-router-core-process-route-tree-into-segment-tree

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

@nx-cloud
Copy link

nx-cloud bot commented Nov 1, 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 4601eff

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

☁️ Nx Cloud last updated this comment at 2025-11-13 22:25:03 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 1, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: 4601eff

@Sheraff
Copy link
Contributor Author

Sheraff commented Nov 13, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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