Skip to content

refactor(router-core): clarify segment interpolation - #8319

Open
schiller-manuel wants to merge 1 commit into
optimize-link-solid-vue-statefrom
optimize-link-segment-interpolation
Open

refactor(router-core): clarify segment interpolation#8319
schiller-manuel wants to merge 1 commit into
optimize-link-solid-vue-statefrom
optimize-link-segment-interpolation

Conversation

@schiller-manuel

@schiller-manuel schiller-manuel commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

🎯 Changes

Simplify path interpolation into ordered segment blocks while preserving one-pass parsing and optional metadata collection.

This is PR 4 of a stacked series and is based on optimize-link-solid-vue-state.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with the relevant test commands.
  • 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 changesets.
  • This change is docs/CI/dev-only.

Summary by CodeRabbit

  • Improvements

    • Improved URL path generation for routes combining named, optional, and wildcard parameters.
    • Preserved consistent handling of prefixes, suffixes, empty wildcard values, and missing parameters.
    • Streamlined path interpolation for more efficient route processing.
  • Testing

    • Added coverage and performance benchmarks for complex path interpolation scenarios.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: ffdf7538-6e25-4013-af8a-bce1fe8b5c60

📥 Commits

Reviewing files that changed from the base of the PR and between 2440a00 and 2e22a79.

📒 Files selected for processing (4)
  • .changeset/lucky-candies-smoke.md
  • packages/router-core/src/path.ts
  • packages/router-core/tests/path-interpolation.bench.ts
  • packages/router-core/tests/path.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Path interpolation now reuses one result object for the interpolated path, used parameters, and missing-parameter metadata. Parser handling for wildcard, optional, and named parameters was reorganized. Tests and benchmarks cover mixed segments and direct pathname interpolation.

Changes

Path interpolation

Layer / File(s) Summary
Shared interpolation result and parser handling
packages/router-core/src/path.ts
interpolatePath passes shared metadata to interpolatePathname. Server and general parser paths record missing parameters through that metadata. Splat encoding returns early for falsy values.
Interpolation coverage and release metadata
packages/router-core/tests/path.test.ts, packages/router-core/tests/path-interpolation.bench.ts, .changeset/lucky-candies-smoke.md
Tests and benchmarks cover mixed named, optional, and splat segments, including direct pathname interpolation. A patch release changeset documents the refactor.

Priority: ⬇️ Low

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

Suggested reviewers: sheraff

Merge Risk: ⚪ Minimal · up to 2e22a

This change refactors internal path-interpolation logic and its metadata handling while preserving existing outputs, parameter behavior, and public API contracts. Investigation found no evidence of broken callers or behavioral regressions, so this refactor appears safe to merge with normal review confidence.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: refactoring router-core path interpolation to clarify segment interpolation.
Description check ✅ Passed The description includes all required sections, explains the change and motivation, completes the checklist, and identifies the release impact with a generated changeset.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch optimize-link-segment-interpolation

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 9, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 2e22a79

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 31s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-10 21:51:55 UTC

@pkg-pr-new

pkg-pr-new Bot commented Sep 9, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-rsc

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 2e22a79

@github-actions

github-actions Bot commented Sep 9, 2026

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.35 → 1.170.36 Changeset
@tanstack/router-core 1.171.29 → 1.171.30 Changeset
@tanstack/solid-router 1.170.33 → 1.170.34 Changeset
@tanstack/vue-router 1.170.32 → 1.170.33 Changeset
@tanstack/react-start 1.168.52 → 1.168.53 Dependent
@tanstack/react-start-client 1.168.33 → 1.168.34 Dependent
@tanstack/react-start-rsc 0.1.51 → 0.1.52 Dependent
@tanstack/react-start-server 1.167.40 → 1.167.41 Dependent
@tanstack/router-cli 1.167.35 → 1.167.36 Dependent
@tanstack/router-generator 1.167.35 → 1.167.36 Dependent
@tanstack/router-plugin 1.168.37 → 1.168.38 Dependent
@tanstack/router-vite-plugin 1.167.37 → 1.167.38 Dependent
@tanstack/solid-start 1.168.50 → 1.168.51 Dependent
@tanstack/solid-start-client 1.168.32 → 1.168.33 Dependent
@tanstack/solid-start-server 1.167.39 → 1.167.40 Dependent
@tanstack/start-client-core 1.170.29 → 1.170.30 Dependent
@tanstack/start-plugin-core 1.171.42 → 1.171.43 Dependent
@tanstack/start-server-core 1.169.34 → 1.169.35 Dependent
@tanstack/start-static-server-functions 1.167.34 → 1.167.35 Dependent
@tanstack/start-storage-context 1.167.31 → 1.167.32 Dependent
@tanstack/vue-start 1.168.49 → 1.168.50 Dependent
@tanstack/vue-start-client 1.167.35 → 1.167.36 Dependent
@tanstack/vue-start-server 1.167.39 → 1.167.40 Dependent

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 378e2719c50d
  • Measured at: 2026-09-10T21:44:09.206Z
  • Baseline source: history:6494e75362ff
  • 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 84.0 KiB
+64 B
83.9 KiB
+59 B
262.2 KiB
-165 B
73.1 KiB
-68 B
▁▁███████▄▄▆
react-router.full 87.5 KiB
+52 B
87.4 KiB
+54 B
273.8 KiB
-165 B
76.2 KiB
+2 B
▁▁███████▅▅▆
solid-router.minimal 33.5 KiB
+64 B
33.4 KiB
+67 B
96.6 KiB
-138 B
30.3 KiB
+35 B
▁▁▆▆▆▆▆▆▆▆▆█
solid-router.full 38.4 KiB
+74 B
38.2 KiB
+74 B
111.3 KiB
-138 B
34.6 KiB
+98 B
▁▁▆▆▆▆▆▆▆▆▆█
vue-router.minimal 49.6 KiB
-17 B
49.4 KiB
-18 B
137.8 KiB
-566 B
44.8 KiB
-112 B
▂▂███████▁▁▁
vue-router.full 55.2 KiB
-20 B
55.0 KiB
-20 B
156.0 KiB
-566 B
49.8 KiB
-21 B
▂▂███████▁▁▁
react-start.minimal 96.9 KiB
+55 B
96.8 KiB
+57 B
304.4 KiB
-165 B
84.0 KiB
-57 B
▁▁███████▄▄▆
react-start.query-integration 104.3 KiB
+47 B
104.1 KiB
+50 B
330.9 KiB
-165 B
90.5 KiB
+116 B
▁▁███████▅▅▆
react-start.deferred-hydration 97.7 KiB
+60 B
96.8 KiB
+62 B
305.8 KiB
-165 B
84.7 KiB
-26 B
▁▁███████▄▄▆
react-start.full 100.1 KiB
+59 B
100.0 KiB
+60 B
314.1 KiB
-165 B
86.7 KiB
+20 B
▁▁███████▄▄▆
react-start.rsbuild.minimal 100.2 KiB
+45 B
100.0 KiB
+45 B
314.7 KiB
-146 B
86.5 KiB
+120 B
▁▁███████▃▃▅
react-start.rsbuild.minimal-iife 100.6 KiB
+46 B
100.4 KiB
+46 B
315.6 KiB
-146 B
86.8 KiB
-49 B
▁▁███████▃▃▅
react-start.rsbuild.full 103.5 KiB
+42 B
103.3 KiB
+42 B
324.8 KiB
-146 B
89.2 KiB
+31 B
▁▁███████▂▂▄
solid-start.minimal 46.4 KiB
+103 B
46.3 KiB
+102 B
137.7 KiB
-140 B
41.3 KiB
+74 B
▁▁▆▆▆▆▆▆▆▆▆█
solid-start.deferred-hydration 49.5 KiB
+66 B
46.4 KiB
+63 B
145.1 KiB
-136 B
44.0 KiB
+18 B
▁▁▇▇▆▆▆▆▆▆▆█
solid-start.full 51.5 KiB
+89 B
51.3 KiB
+86 B
153.1 KiB
-138 B
45.6 KiB
+86 B
▁▁▆▆▆▆▆▆▆▆▆█
vue-start.minimal 65.7 KiB
-35 B
65.6 KiB
-33 B
188.6 KiB
-566 B
58.5 KiB
-23 B
▂▂███████▂▂▁
vue-start.full 69.6 KiB
-2 B
69.5 KiB
0 B
200.9 KiB
-566 B
61.8 KiB
+27 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-hq

codspeed-hq Bot commented Sep 9, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 8.67%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 3 improved benchmarks
✅ 177 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation client-links navigation loop (react) 216.8 ms 190.4 ms +13.82%
Simulation client-links navigation loop (vue) 344.7 ms 321.7 ms +7.14%
Simulation client-links navigation loop (solid) 522.7 ms 496.7 ms +5.25%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing optimize-link-segment-interpolation (2e22a79) with main (6494e75)1

Open in CodSpeed

Footnotes

  1. No successful run was found on optimize-link-solid-vue-state (2440a00) during the generation of this report, so main (6494e75) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@schiller-manuel
schiller-manuel force-pushed the optimize-link-segment-interpolation branch 2 times, most recently from 3ed796e to 17e00ed Compare September 10, 2026 20:29
keys?: Array<string>,
server?: boolean,
onMissing?: () => void,
metadata?: { isMissingParams: boolean },

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit but if this is meant to be an internal key, we might save a couple bytes w/ a shorter property name (or by using a tuple instead)

Organize the generic interpolation loop into static, wildcard, and named-parameter behavior blocks. Keep one shared key lookup, one encoding step, and one prefix/value/suffix assembly. Name affix boundaries and keep optional/missing wildcard behavior local to its segment type.

Replace the self-clearing onMissing callback with an optional metadata result object. The public interpolatePath wrapper reuses its existing result object; pathname-only callers still allocate no metadata. Preserve one parameter read, the reusable parser buffer, absent optional cache keys, canonical and legacy splat metadata, and public return values. Fast-path empty splat strings before the URL-safe regex so sharing the encoding step does not penalize omitted values.

Final official gzip measurements versus 5017a72:
- React minimal: 85771 -> 85769 (-2 bytes).
- React full: 89384 -> 89382 (-2 bytes).
- All 18 fixtures range from -4 to +8 bytes; no unrelated source changes compensate for interpolation cost.

Added mixed-type/affix metadata coverage and direct pathname-kernel benchmarks. Paired fixed-seed CPU measurements of the real parent/current modules show effectively flat required client pathname interpolation (+0.04%) and 0.37-4.14% lower time in the other sampled required/optional/splat/mixed/missing client/server combinations. These are focused kernel diagnostics, not a broad application speedup claim.

Preserve the experiments, rejected larger variants, full fixture metrics, and raw benchmark output in uncommitted LOG.md and session artifacts.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@schiller-manuel
schiller-manuel force-pushed the optimize-link-segment-interpolation branch from 17e00ed to 2e22a79 Compare September 10, 2026 21:12
@schiller-manuel
schiller-manuel added this pull request to stack #8346 September 10, 2026 21:30
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