Skip to content

refactor(router-core): parse masked locations without mutating shared state - #8421

Merged
schiller-manuel merged 2 commits into
codex/resolve-path-positionalfrom
codex/parse-masked-location
Sep 15, 2026
Merged

schiller-manuel merged 2 commits into
codex/resolve-path-positionalfrom
codex/parse-masked-location

Conversation

@schiller-manuel

@schiller-manuel schiller-manuel commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

🎯 Changes

parseLocation built the presented location of a masked entry by parsing
the stored __tempLocation and then patching and delete-ing keys on the
resulting state, which replaceEqualDeep may have shared with the
previous location, before spreading the result once more. The inner parser
now takes the state to use, so the masked branch passes the intended state
up front and assigns maskedLocation on the fresh object.

The slow parsing path only runs the input rewrite when one is configured,
and resolvePathWithBase is inlined into its two callers.

Verification on main

  • router-core test:unit (3252 passed), test:types, test:eslint

Relationship to other PRs

Stacked on #8419 (positional resolvePath): the inlined resolvePathWithBase callers use the positional signature. Merge #8419 first and GitHub retargets this one to main.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with the relevant test commands, or tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of masked temporary locations during navigation without altering shared state.
    • Simplified URL rewrite processing for more consistent navigation behavior.
    • Improved path resolution when building locations and matching routes.
    • Improved route matching and cache behavior when using case-sensitive paths.
  • Release
    • Published a patch release of the router core package containing these navigation and routing improvements.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 45026fb7-abfa-4c89-8c7a-714d7d8cd5f7

📥 Commits

Reviewing files that changed from the base of the PR and between bb56d2a and 20d9a05.

📒 Files selected for processing (1)
  • packages/router-core/src/router.ts

📝 Walkthrough

Walkthrough

The router now tracks rewrite and case-sensitivity changes together, validates cached route trees with case-sensitivity data, parses masked locations with merged state, and uses direct resolvePath calls for location building and matching.

Changes

Router location flow

Layer / File(s) Summary
Rewrite updates and cache handling
packages/router-core/src/router.ts
update uses one rewriteChanged flag for basepath, rewrite, and caseSensitive changes. Route-tree refreshes and location-store updates follow that flag. __TSR_CACHE__ entries now include caseSensitive. invalidate uses a shared callback to collect invalid IDs.
Location parsing and path resolution
packages/router-core/src/router.ts, .changeset/whole-coins-sin.md
parse accepts state separately. Masked temporary locations pass merged state directly into parsing. Rewrite execution uses one call. buildLocation and matchRoute call resolvePath directly, and resolvePathWithBase was removed. matchRoute uses boolean partial comparisons. The changeset declares a patch release.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: sheraff

Merge Risk: ⚪ Minimal · up to bb56d

The router-core refactor preserves existing location and rewrite behavior and is ready to merge subject to normal checks.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description explains the state-mutation fix, rewrite-path change, helper inlining, verification results, stacked-PR dependency, and release impact. It follows the required template. The AI-underst…
Title check ✅ Passed The title clearly and concisely describes the primary change: refactoring router-core to parse masked locations without mutating shared state.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/parse-masked-location

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.

@nx-cloud

nx-cloud Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit bb56d2a

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

☁️ Nx Cloud last updated this comment at 2026-09-15 21:21:59 UTC

@schiller-manuel
schiller-manuel added this pull request to stack #8427 September 14, 2026 17:49
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

4 package(s) bumped directly, 19 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/react-router 1.170.36 → 1.170.37 Changeset
@tanstack/router-core 1.171.30 → 1.171.31 Changeset
@tanstack/solid-router 1.170.34 → 1.170.35 Changeset
@tanstack/vue-router 1.170.33 → 1.170.34 Changeset
@tanstack/react-start 1.168.54 → 1.168.55 Dependent
@tanstack/react-start-client 1.168.34 → 1.168.35 Dependent
@tanstack/react-start-rsc 0.1.53 → 0.1.54 Dependent
@tanstack/react-start-server 1.167.41 → 1.167.42 Dependent
@tanstack/router-cli 1.167.36 → 1.167.37 Dependent
@tanstack/router-generator 1.167.36 → 1.167.37 Dependent
@tanstack/router-plugin 1.168.38 → 1.168.39 Dependent
@tanstack/router-vite-plugin 1.167.38 → 1.167.39 Dependent
@tanstack/solid-start 1.168.52 → 1.168.53 Dependent
@tanstack/solid-start-client 1.168.33 → 1.168.34 Dependent
@tanstack/solid-start-server 1.167.40 → 1.167.41 Dependent
@tanstack/start-client-core 1.170.30 → 1.170.31 Dependent
@tanstack/start-plugin-core 1.171.44 → 1.171.45 Dependent
@tanstack/start-server-core 1.169.35 → 1.169.36 Dependent
@tanstack/start-static-server-functions 1.167.35 → 1.167.36 Dependent
@tanstack/start-storage-context 1.167.32 → 1.167.33 Dependent
@tanstack/vue-start 1.168.51 → 1.168.52 Dependent
@tanstack/vue-start-client 1.167.36 → 1.167.37 Dependent
@tanstack/vue-start-server 1.167.40 → 1.167.41 Dependent

@pkg-pr-new

pkg-pr-new Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@8421

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@8421

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@8421

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@8421

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@8421

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@8421

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@8421

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@8421

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@8421

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@8421

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@8421

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@8421

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@8421

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@8421

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@8421

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@8421

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@8421

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@8421

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@8421

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@8421

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@8421

commit: bb56d2a

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 451d156e5917
  • Measured at: 2026-09-15T22:45:15.908Z
  • Baseline source: history:a0b2ad99aee6
  • Dashboard: bundle-size history

The following scenarios have bundle-size changes compared with the baseline:

Scenario Current (gzip) Initial (gzip) Raw Brotli Trend
react-router.minimal 83.9 KiB
-44 B
83.7 KiB
-41 B
261.2 KiB
-111 B
73.2 KiB
-8 B
▆▆████▆▆▆▆▃▁
react-router.full 87.3 KiB
-36 B
87.2 KiB
-40 B
272.9 KiB
-111 B
76.2 KiB
-34 B
▇▆████▆▆▆▆▃▁
solid-router.minimal 33.3 KiB
-34 B
33.2 KiB
-33 B
95.5 KiB
-111 B
30.1 KiB
-36 B
██▇▇▇▇▆▆▆▆▃▁
solid-router.full 38.2 KiB
-35 B
38.1 KiB
-39 B
110.2 KiB
-111 B
34.4 KiB
-58 B
██████▇▇▇▇▃▁
vue-router.minimal 49.4 KiB
-38 B
49.3 KiB
-37 B
136.7 KiB
-111 B
44.7 KiB
-65 B
██▆▆▆▆▄▄▄▄▂▁
vue-router.full 54.9 KiB
-38 B
54.8 KiB
-35 B
154.9 KiB
-111 B
49.6 KiB
-29 B
██▆▆▆▆▅▅▅▅▂▁
react-start.minimal 96.8 KiB
-44 B
96.7 KiB
-40 B
303.5 KiB
-111 B
84.0 KiB
-19 B
▅▅████▆▆▆▆▃▁
react-start.query-integration 104.1 KiB
-39 B
104.0 KiB
-39 B
330.0 KiB
-111 B
90.3 KiB
-44 B
▆▅████▆▆▆▆▂▁
react-start.deferred-hydration 97.5 KiB
-44 B
96.7 KiB
-40 B
304.9 KiB
-111 B
84.7 KiB
+28 B
▅▅████▆▆▆▆▃▁
react-start.full 100.0 KiB
-36 B
99.8 KiB
-35 B
313.2 KiB
-111 B
86.6 KiB
-103 B
▅▅████▆▆▆▆▃▁
react-start.rsbuild.minimal 100.1 KiB
-54 B
99.9 KiB
-54 B
314.1 KiB
-19 B
86.5 KiB
-28 B
▂▂████▇▇▇▇▄▁
react-start.rsbuild.minimal-iife 100.5 KiB
-52 B
100.4 KiB
-52 B
315.1 KiB
-19 B
86.8 KiB
-10 B
▂▂████▇▇▇▇▄▁
react-start.rsbuild.full 103.3 KiB
-75 B
103.2 KiB
-75 B
324.2 KiB
-19 B
89.2 KiB
-31 B
▅▄████▇▆▆▆▄▁
solid-start.minimal 46.3 KiB
-19 B
46.1 KiB
-18 B
136.6 KiB
-113 B
41.2 KiB
+28 B
▆▆████▇▇▇▇▂▁
solid-start.deferred-hydration 49.3 KiB
-36 B
46.2 KiB
-34 B
144.0 KiB
-113 B
44.0 KiB
+51 B
▆▇████▇▇▇▇▃▁
solid-start.full 51.3 KiB
-41 B
51.2 KiB
-42 B
152.0 KiB
-111 B
45.5 KiB
-63 B
▆▅████▇▇▇▇▃▁
vue-start.minimal 65.5 KiB
-35 B
65.4 KiB
-34 B
187.5 KiB
-111 B
58.4 KiB
-42 B
██▆▆▆▆▄▄▄▄▂▁
vue-start.full 69.4 KiB
-39 B
69.2 KiB
-37 B
199.8 KiB
-111 B
61.6 KiB
-132 B
██▆▆▆▆▅▅▅▅▂▁

Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better.

@codspeed

codspeed Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 180 untouched benchmarks


Comparing codex/parse-masked-location (20d9a05) with codex/resolve-path-positional (7b6125d)

Open in CodSpeed

Comment thread packages/router-core/src/router.ts Outdated
schiller-manuel and others added 2 commits September 16, 2026 00:41
… state

`parseLocation` built the presented location of a masked entry by parsing
the stored `__tempLocation` and then patching and `delete`-ing keys on the
resulting `state`, which `replaceEqualDeep` may have shared with the
previous location, before spreading the result once more. The inner parser
now takes the state to use, so the masked branch passes the intended state
up front and assigns `maskedLocation` on the fresh object.

The slow parsing path only runs the input rewrite when one is configured,
and `resolvePathWithBase` is inlined into its two callers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit cc6159628cd22faf9c16e6e432cb35093b2826a8)
@schiller-manuel
schiller-manuel force-pushed the codex/parse-masked-location branch from bb56d2a to 20d9a05 Compare September 15, 2026 22:41
@schiller-manuel
schiller-manuel merged commit 1ca361b into main Sep 15, 2026
24 of 32 checks passed
@schiller-manuel
schiller-manuel deleted the codex/parse-masked-location branch September 15, 2026 22:42
@github-actions github-actions Bot mentioned this pull request Sep 15, 2026
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