Skip to content

fix(router-core): lane match loader rewrite - #7805

Open
Sheraff wants to merge 64 commits into
mainfrom
fix-router-core-lane-match-loader
Open

fix(router-core): lane match loader rewrite#7805
Sheraff wants to merge 64 commits into
mainfrom
fix-router-core-lane-match-loader

Conversation

@Sheraff

@Sheraff Sheraff commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

fixed by this PR

fixes #2980, fixes #3179, fixes #3920, fixes #3928, fixes #4444, fixes #4467, fixes #4476, fixes #4572, fixes #4614, fixes #4759, fixes #5427, fixes #6107, fixes #6221, fixes #6351, fixes #6371, fixes #7051, fixes #7120, fixes #7283, fixes #7367, fixes #7379, fixes #7457, fixes #7602, fixes #7635, fixes #7673, fixes #7753, fixes #7759, fixes #7815

Already fixed on main (but we added tests)

Ignored by this PR

Summary by CodeRabbit

  • New Features
    • Added selective SSR coverage with new non-SSR route demonstrating pending behavior.
  • Bug Fixes
    • Improved pending UI presentation across navigation, retries, and forced-pending replacements.
    • Fixed SSR HTTP response status codes for render/redirect/error/not-found outcomes.
    • Improved resilience so loader/router event errors don’t break later rendering.
  • Tests
    • Added/expanded Solid, React, Vue, and TanStack Router regression and hydration boundary tests.
  • Documentation / Compatibility
    • Updated preloading and router docs/types to clarify pending and preload semantics.

@nx-cloud

nx-cloud Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 1d20a9d

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

☁️ Nx Cloud last updated this comment at 2026-07-30 12:36:26 UTC

@github-actions

github-actions Bot commented Jul 13, 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.18 → 1.170.19 Changeset
@tanstack/router-core 1.171.15 → 1.171.16 Changeset
@tanstack/solid-router 1.170.18 → 1.170.19 Changeset
@tanstack/vue-router 1.170.17 → 1.170.18 Changeset
@tanstack/react-start 1.168.33 → 1.168.34 Dependent
@tanstack/react-start-client 1.168.16 → 1.168.17 Dependent
@tanstack/react-start-rsc 0.1.32 → 0.1.33 Dependent
@tanstack/react-start-server 1.167.22 → 1.167.23 Dependent
@tanstack/router-cli 1.167.21 → 1.167.22 Dependent
@tanstack/router-generator 1.167.21 → 1.167.22 Dependent
@tanstack/router-plugin 1.168.23 → 1.168.24 Dependent
@tanstack/router-vite-plugin 1.167.23 → 1.167.24 Dependent
@tanstack/solid-start 1.168.32 → 1.168.33 Dependent
@tanstack/solid-start-client 1.168.16 → 1.168.17 Dependent
@tanstack/solid-start-server 1.167.22 → 1.167.23 Dependent
@tanstack/start-client-core 1.170.14 → 1.170.15 Dependent
@tanstack/start-plugin-core 1.171.24 → 1.171.25 Dependent
@tanstack/start-server-core 1.169.17 → 1.169.18 Dependent
@tanstack/start-static-server-functions 1.167.19 → 1.167.20 Dependent
@tanstack/start-storage-context 1.167.17 → 1.167.18 Dependent
@tanstack/vue-start 1.168.31 → 1.168.32 Dependent
@tanstack/vue-start-client 1.167.19 → 1.167.20 Dependent
@tanstack/vue-start-server 1.167.22 → 1.167.23 Dependent

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR rewrites router loading around client/server lanes, simplifies match stores, updates React/Solid/Vue rendering and SSR integration, changes HMR refresh behavior, adds extensive lifecycle and hydration tests, and updates loading documentation and end-to-end fixtures.

Changes

Router loading pipeline

Layer / File(s) Summary
Client/server lane orchestration
packages/router-core/src/load-client.ts, packages/router-core/src/load-server.ts, packages/router-core/src/router.ts
Client and server navigation use lane-based contextualization, loading, failure reduction, asset projection, caching, cancellation, and commit flows.
Match and store contracts
packages/router-core/src/Matches.ts, packages/router-core/src/stores.ts, packages/router-core/src/route.ts, packages/router-core/src/redirect.ts
Pending, redirect, lazy-loading, and internal match state shapes are simplified and aligned with semantic match reuse.
Adapter rendering and transitions
packages/react-router/src/*, packages/solid-router/src/*, packages/vue-router/src/*
Pending rendering, reset keys, transition acknowledgement, not-found propagation, hydration behavior, and SSR response statuses are updated across adapters.
Regression coverage
packages/router-core/tests/*, packages/react-router/tests/*, packages/solid-router/tests/*, packages/vue-router/tests/*, packages/start-server-core/tests/*
Tests cover hydration, preload adoption, abort ownership, pending generations, redirects, lazy chunks, server failures, request cancellation, and lifecycle events.
HMR refresh flow
packages/router-plugin/src/core/hmr/handle-route-update.ts, packages/router-plugin/tests/*
HMR updates rebuild route trees, clear lazy state and path caches, synchronize route exports, and invoke targeted route refreshes.
Documentation and end-to-end fixtures
docs/router/*, e2e/*, benchmarks/memory/*, .changeset/lane-match-loader-rewrite.md
Public loading semantics, cache timing, match state, SSR behavior, issue reproductions, and benchmark cancellation handling are updated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

  • #2980 — Preload and cache-generation handling covers reuse of active ancestor data across repeated preloads.
  • #3179 — Preload and semantic match handling covers cause and beforeLoad behavior across cached and active matches.
  • #3928 — Loader flight cancellation and abort-aware result handling are directly covered by the client lane pipeline and regression tests.
  • #4614 — Selective SSR preload context behavior is covered by the cached-parent end-to-end test.
  • #7283 — Solid selective SSR hydration for ssr: false and ssr: 'data-only' pending routes is covered by the DEV-mode end-to-end suite.
  • #7379 — Direct-load head({ matches }) context and loader data population are covered by router-core tests.
  • #7457 — Initial redirects after asynchronous beforeLoad are covered by a React end-to-end reproduction.
  • #7910 — Pending-match loadPromise synchronization removal directly relates to the retrieved stale pending snapshot regression.

Possibly related PRs

  • TanStack/router#5518 — Shares Solid hydration/pending refactors across the same Solid router components.
  • TanStack/router#6704 — Shares the pending-match store removal and rewiring of Match/Transitioner reactivity.
  • TanStack/router#7152 — Shares router store-based match/pending lookup refactors across React and Solid routers.

Suggested reviewers: schiller-manuel

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main router-core lane loader rewrite.
Linked Issues check ✅ Passed [#2980,#3179,#3928,#4476,#4572,#6371,#7602,#7759] Cache, preload, cause, and abort behavior are covered by the load/invalidate rewrite and tests.
Linked Issues check ✅ Passed [#3920,#4444,#4467,#4759,#7051,#7120,#7283,#7367,#7457,#7673,#7753] Match/Transitioner changes and tests cover pending, redirect, and undefined-throw races.
Linked Issues check ✅ Passed [#4614,#5427,#6107,#6221,#6351,#7379,#7635,#7815] SSR, head/notFound, and scroll-restoration cases are covered by server, hydration, and e2e updates.
Out of Scope Changes check ✅ Passed The changes stay within the router rewrite and its supporting tests, docs, and fixtures; no clearly unrelated code stands out.
✨ 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 fix-router-core-lane-match-loader

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.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 24071d30b49e
  • Measured at: 2026-07-30T12:31:34.718Z
  • Baseline source: history:88f366ab8e04
  • Dashboard: bundle-size history

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

Scenario Current (gzip) Delta vs baseline Initial gzip Raw Brotli Trend
react-router.minimal 87.21 KiB -145 B (-0.16%) 87.07 KiB 269.46 KiB 75.94 KiB ███████████▁
react-router.full 91.00 KiB -69 B (-0.07%) 90.86 KiB 281.47 KiB 79.30 KiB ███████████▁
solid-router.minimal 34.91 KiB -629 B (-1.73%) 34.79 KiB 100.24 KiB 31.48 KiB ███████████▁
solid-router.full 40.01 KiB -582 B (-1.40%) 39.89 KiB 115.47 KiB 36.00 KiB ███████████▁
vue-router.minimal 52.22 KiB -802 B (-1.48%) 52.08 KiB 143.40 KiB 47.04 KiB ███████████▁
vue-router.full 58.19 KiB -769 B (-1.27%) 58.05 KiB 162.17 KiB 52.25 KiB ███████████▁
react-start.minimal 102.20 KiB +215 B (+0.21%) 102.06 KiB 318.61 KiB 88.84 KiB ▁▁▁▁▁▁▁▁▁▁▁█
react-start.deferred-hydration 102.93 KiB +214 B (+0.20%) 102.08 KiB 319.99 KiB 89.33 KiB ▁▁▁▁▁▁▁▁▁▁▁█
react-start.full 105.61 KiB +251 B (+0.23%) 105.47 KiB 328.61 KiB 91.55 KiB ▁▁▁▁▁▁▁▁▁▁▁█
react-start.rsbuild.minimal 99.92 KiB +250 B (+0.24%) 99.75 KiB 313.00 KiB 86.22 KiB ▁▁▁▁▁▁▁▁▁▁▁█
react-start.rsbuild.minimal-iife 100.32 KiB +249 B (+0.24%) 100.16 KiB 313.94 KiB 86.41 KiB ▁▁▁▁▁▁▁▁▁▁▁█
react-start.rsbuild.full 103.25 KiB +369 B (+0.35%) 103.08 KiB 323.15 KiB 88.89 KiB ▁▁▁▁▁▁▁▁▁▁▁█
solid-start.minimal 49.84 KiB +239 B (+0.47%) 49.71 KiB 148.28 KiB 44.31 KiB ▁▁▁▁▁▁▁▁▁▁▁█
solid-start.deferred-hydration 53.11 KiB +243 B (+0.45%) 49.77 KiB 156.32 KiB 47.28 KiB ▁▁▁▁▁▁▁▁▁▁▁█
solid-start.full 55.11 KiB -318 B (-0.56%) 54.98 KiB 164.07 KiB 48.82 KiB ███████████▁
vue-start.minimal 70.59 KiB -447 B (-0.61%) 70.46 KiB 201.32 KiB 62.65 KiB ███████████▁
vue-start.full 74.57 KiB -476 B (-0.62%) 74.43 KiB 213.93 KiB 66.16 KiB ███████████▁

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.

@pkg-pr-new

pkg-pr-new Bot commented Jul 13, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-rsc

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: b8204ea

@codspeed-hq

codspeed-hq Bot commented Jul 13, 2026

Copy link
Copy Markdown

Merging this PR will regress 15 benchmarks

⚠️ 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

⚡ 105 improved benchmarks
❌ 27 (👁 12) regressed benchmarks
✅ 48 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory mem server serialization-payload (react) 3.4 MB 5.2 MB -33.99%
Simulation client-control-flow navigation loop (vue) 50.4 ms 56.7 ms -11.05%
Simulation client-async-pipeline navigation loop (vue) 45.9 ms 51.5 ms -10.92%
Simulation ssr loaders (react) 59.2 ms 65 ms -8.96%
Simulation ssr request loop (solid) 147 ms 158.1 ms -7.04%
Simulation client-preload interaction loop (vue) 54.9 ms 58.9 ms -6.92%
Simulation ssr global-mw server-fn (vue) 59.9 ms 64.2 ms -6.63%
Simulation ssr server-fn raw-response (vue) 56.5 ms 60.3 ms -6.31%
Simulation ssr server-fn not-found (vue) 74 ms 78.9 ms -6.19%
Simulation ssr server-fn send-context (vue) 72.8 ms 77.5 ms -6.06%
Simulation ssr server-fn POST (vue) 71.5 ms 75.3 ms -5.14%
Simulation ssr server-fn raw-response (react) 55.3 ms 58.2 ms -5.02%
Simulation ssr server-fn GET (vue) 74.5 ms 77.6 ms -4.07%
Simulation ssr server-fn multipart (react) 58.8 ms 60.8 ms -3.3%
Simulation ssr server-fn multipart (vue) 64.3 ms 66.4 ms -3.17%
Memory mem client interrupted-navigations (solid) 841 KB 403.7 KB ×2.1
Memory mem server error-paths redirect (vue) 676.3 KB 351.7 KB +92.32%
Memory mem client interrupted-navigations (react) 757.4 KB 409.3 KB +85.03%
Simulation ssr redirect (solid) 59.5 ms 36.8 ms +61.6%
Simulation ssr redirect (react) 61.2 ms 38.2 ms +60.06%
... ... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix-router-core-lane-match-loader (b8204ea) with main (a3ee355)

Open in CodSpeed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/vue-router/src/useMatch.tsx (1)

137-154: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Preserve the generic result type instead of erasing it with any.

Vue.computed<any> allows the implementation to violate the declared ThrowOrOptional<UseMatchResult<...>> contract without a compiler error. Type match and result from the existing generic aliases.

As per coding guidelines, “Use TypeScript strict mode with extensive type safety.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/vue-router/src/useMatch.tsx` around lines 137 - 154, Update the
computed result in the useMatch flow to preserve the existing generic result
type instead of using Vue.computed<any>. Type match and result with the existing
generic aliases, including the declared ThrowOrOptional<UseMatchResult<...>>
contract, so incorrect return values are caught by TypeScript while preserving
the current selection and missing-match behavior.

Source: Coding guidelines

🧹 Nitpick comments (7)
e2e/solid-start/selective-ssr/tests/issue-7283-dev-hydration.spec.ts (1)

27-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use braces for all conditional bodies.

These one-line if statements violate the repository’s TypeScript control-flow convention.

As per coding guidelines, **/*.{ts,tsx,js,jsx} must use curly braces for control statements.

Also applies to: 79-79, 84-84

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/solid-start/selective-ssr/tests/issue-7283-dev-hydration.spec.ts` at line
27, Update the one-line conditional statements in
issue-7283-dev-hydration.spec.ts, including the checks around lines 27, 79, and
84, to wrap each conditional body in curly braces while preserving their
existing behavior.

Source: Coding guidelines

packages/solid-router/tests/transitioner-remount.test.tsx (1)

54-54: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid discarding location-state type safety.

Assert the partial state shape directly instead of casting to any.

Proposed change
-    expect((router.state.location.state as any).remounted).toBe(true)
+    expect(router.state.location.state).toMatchObject({ remounted: true })

As per coding guidelines, TypeScript files must use strict mode with extensive type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/solid-router/tests/transitioner-remount.test.tsx` at line 54,
Replace the any cast in the remounted-state assertion with a type-safe assertion
of the partial location-state shape, using an appropriate typed access or
narrowing approach so router.state.location.state remains checked by TypeScript.

Source: Coding guidelines

packages/router-core/tests/fatal-load-rejection.test.ts (1)

25-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Model the error component without bypassing its route contract.

as any prevents this test from detecting changes to the errorComponent interface. Use a callable mock component with its preload property attached, matching the runtime shape used elsewhere.

Proposed fix
+    const ErrorComponent = Object.assign(() => null, {
+      preload: errorComponentPreload,
+    })
+
     const rootRoute = new BaseRootRoute({
       loader: () => 'root data',
-      errorComponent: { preload: errorComponentPreload } as any,
+      errorComponent: ErrorComponent,
     })

As per coding guidelines, TypeScript files must use strict mode with extensive type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/router-core/tests/fatal-load-rejection.test.ts` around lines 25 -
30, Update the errorComponent setup in the BaseRootRoute test to use a typed
callable mock component with its preload property attached, matching the runtime
component shape. Remove the as any cast so TypeScript validates the
errorComponent contract and the test catches interface changes.

Source: Coding guidelines

packages/router-core/tests/issue-6371-search-default-normalization-abort.test.ts (1)

60-75: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep the canonical replacement setup type-checked.

Both as any casts allow this regression test to keep compiling if buildLocation or commitLocation changes incompatibly. Please use their declared/internal option types or a typed helper for the Transitioner operation being reproduced.

As per coding guidelines, TypeScript files must use strict mode with extensive type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/router-core/tests/issue-6371-search-default-normalization-abort.test.ts`
around lines 60 - 75, Remove the as any casts from the buildLocation and
commitLocation calls in this regression test. Use the declared option types or a
typed helper representing the Transitioner operation so both canonical
replacement setup calls remain strictly type-checked while preserving their
existing behavior.

Source: Coding guidelines

packages/router-core/tests/issue-4444-param-parse-error-lazy-child.test.ts (1)

19-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert that the lazy child chunk was never requested.

The test can currently pass even if lazyFn runs before the child is trimmed, leaving the documented regression partially uncovered.

Proposed assertion
 expect(
   router.state.matches.find((match) => match.status === 'pending'),
 ).toBeUndefined()
+expect(lazyFn).not.toHaveBeenCalled()
 expect(router.state.isLoading).toBe(false)

Also applies to: 60-68

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/router-core/tests/issue-4444-param-parse-error-lazy-child.test.ts`
around lines 19 - 21, Update the test using the lazyFn mock so it explicitly
asserts lazyFn was never called when the child route is trimmed after the
parameter parse error. Place the assertion after the relevant navigation or
error-handling flow, preserving the existing test behavior while verifying the
lazy child chunk is not requested.
packages/react-router/tests/transactional-loading.test.tsx (1)

130-148: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Capture every committed pair to verify atomic publication.

The final sequential assertions can miss a transient mixed-generation render after childRefresh resolves. Record parent/child values on each committed render and assert that neither parent-v2/child-v1 nor parent-v1/child-v2 occurs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-router/tests/transactional-loading.test.tsx` around lines 130
- 148, Update the transactional loading test around the final refresh sequence
to record the parent and child values on every committed render, then assert no
mixed-generation pair occurs: parent-v2 with child-v1 or parent-v1 with
child-v2. Keep the existing final-state assertions and use the
render-observation mechanism already provided by the test setup.
packages/router-core/src/router.ts (1)

1330-1338: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Silent catch {} hides listener failures.

Swallowing all listener exceptions keeps one bad listener from breaking others, but the fully empty catch also hides real bugs during development. Consider logging in non-production.

♻️ Suggested dev logging
       if (listener.eventType === routerEvent.type) {
         try {
           listener.fn(routerEvent)
-        } catch {}
+        } catch (err) {
+          if (process.env.NODE_ENV !== 'production') {
+            console.error(
+              `Error in router event listener for "${routerEvent.type}":`,
+              err,
+            )
+          }
+        }
       }

If tests assert fully-silent behavior, feel free to disregard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/router-core/src/router.ts` around lines 1330 - 1338, Update the
catch block in the emit method to retain listener isolation while reporting
listener exceptions in non-production environments. Preserve the existing
behavior of continuing to notify other subscribers and keeping production
logging silent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/solid-start/selective-ssr/src/routes/ssr-false-pending-min.tsx`:
- Around line 6-13: Update recordEvent to avoid casting window to any by
declaring a local Window augmentation for the __events event buffer, then
initialize and append through window.__events. Preserve the existing server
guard and event shape, including the performance timestamp.

In `@packages/react-router/tests/router.test.tsx`:
- Around line 2463-2467: Update the navigation assertion in the router test to
target the parent route’s specific not-found boundary, using its unique test
identifier or boundary-specific text instead of the broad “Not Found” match;
keep the existing home-page and navigation steps unchanged.

In `@packages/router-core/tests/issue-6221-head-waits-for-loader.test.ts`:
- Line 23: Update the authentication check in the relevant test to wrap the
notFound call inside curly braces, preserving the existing condition and
behavior.

In `@packages/solid-router/src/Transitioner.tsx`:
- Around line 47-65: Move the Solid.onCleanup registration for unsub immediately
after router.history.subscribe(router.load), before the early return in the
Transitioner setup. Keep the existing cleanup callback unchanged and remove the
later registration so every execution path disposes the history subscription.

In `@packages/solid-router/tests/on-rendered-change-info.test.tsx`:
- Around line 44-61: Update the onRendered transition handling to call
getLocationChangeInfo with the previously rendered location as the first
argument and the latest resolved location as the second. Ensure fromLocation,
toLocation, and change flags reflect the actual transition, including same-href
state changes; locate the change in the code that constructs the onRendered
event.

In `@packages/vue-router/tests/pending-fallback-promise-replacement.test.tsx`:
- Around line 13-18: Update the afterEach cleanup hook to drain and await all
testCleanups while fake timers remain active, then restore real timers in a
finally block so timer state is reset even if cleanup fails. Preserve the
existing cleanup() call after the callbacks settle.

---

Outside diff comments:
In `@packages/vue-router/src/useMatch.tsx`:
- Around line 137-154: Update the computed result in the useMatch flow to
preserve the existing generic result type instead of using Vue.computed<any>.
Type match and result with the existing generic aliases, including the declared
ThrowOrOptional<UseMatchResult<...>> contract, so incorrect return values are
caught by TypeScript while preserving the current selection and missing-match
behavior.

---

Nitpick comments:
In `@e2e/solid-start/selective-ssr/tests/issue-7283-dev-hydration.spec.ts`:
- Line 27: Update the one-line conditional statements in
issue-7283-dev-hydration.spec.ts, including the checks around lines 27, 79, and
84, to wrap each conditional body in curly braces while preserving their
existing behavior.

In `@packages/react-router/tests/transactional-loading.test.tsx`:
- Around line 130-148: Update the transactional loading test around the final
refresh sequence to record the parent and child values on every committed
render, then assert no mixed-generation pair occurs: parent-v2 with child-v1 or
parent-v1 with child-v2. Keep the existing final-state assertions and use the
render-observation mechanism already provided by the test setup.

In `@packages/router-core/src/router.ts`:
- Around line 1330-1338: Update the catch block in the emit method to retain
listener isolation while reporting listener exceptions in non-production
environments. Preserve the existing behavior of continuing to notify other
subscribers and keeping production logging silent.

In `@packages/router-core/tests/fatal-load-rejection.test.ts`:
- Around line 25-30: Update the errorComponent setup in the BaseRootRoute test
to use a typed callable mock component with its preload property attached,
matching the runtime component shape. Remove the as any cast so TypeScript
validates the errorComponent contract and the test catches interface changes.

In `@packages/router-core/tests/issue-4444-param-parse-error-lazy-child.test.ts`:
- Around line 19-21: Update the test using the lazyFn mock so it explicitly
asserts lazyFn was never called when the child route is trimmed after the
parameter parse error. Place the assertion after the relevant navigation or
error-handling flow, preserving the existing test behavior while verifying the
lazy child chunk is not requested.

In
`@packages/router-core/tests/issue-6371-search-default-normalization-abort.test.ts`:
- Around line 60-75: Remove the as any casts from the buildLocation and
commitLocation calls in this regression test. Use the declared option types or a
typed helper representing the Transitioner operation so both canonical
replacement setup calls remain strictly type-checked while preserving their
existing behavior.

In `@packages/solid-router/tests/transitioner-remount.test.tsx`:
- Line 54: Replace the any cast in the remounted-state assertion with a
type-safe assertion of the partial location-state shape, using an appropriate
typed access or narrowing approach so router.state.location.state remains
checked by TypeScript.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a9eff563-1e9d-4b5e-9e0d-17c99dcf056c

📥 Commits

Reviewing files that changed from the base of the PR and between 41f7bf3 and ceaa4d2.

📒 Files selected for processing (162)
  • benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts
  • e2e/solid-start/selective-ssr/src/routeTree.gen.ts
  • e2e/solid-start/selective-ssr/src/routes/ssr-false-pending-min.tsx
  • e2e/solid-start/selective-ssr/tests/issue-7283-dev-hydration.spec.ts
  • packages/react-router/src/Match.tsx
  • packages/react-router/src/Matches.tsx
  • packages/react-router/src/Transitioner.tsx
  • packages/react-router/src/lazyRouteComponent.tsx
  • packages/react-router/src/ssr/renderRouterToStream.tsx
  • packages/react-router/src/ssr/renderRouterToString.tsx
  • packages/react-router/tests/Matches.test.tsx
  • packages/react-router/tests/ancestor-loader-child-pending-min.test.tsx
  • packages/react-router/tests/component-preload-retry-pending-min.test.tsx
  • packages/react-router/tests/component-preload-retry.test.tsx
  • packages/react-router/tests/errorComponent.test.tsx
  • packages/react-router/tests/hydration-capped-boundary-pending.test.tsx
  • packages/react-router/tests/hydration-terminal-lane.test.tsx
  • packages/react-router/tests/issue-4759-pending-frame.test.tsx
  • packages/react-router/tests/issue-7051-force-pending-suspense.test.tsx
  • packages/react-router/tests/issue-7367-pending-min-redirect.test.tsx
  • packages/react-router/tests/issue-7457-redirect-chain-first-load.test.tsx
  • packages/react-router/tests/issue-7638-invalidate-transition-error.test.tsx
  • packages/react-router/tests/loaders.test.tsx
  • packages/react-router/tests/on-rendered-same-href-state.test.tsx
  • packages/react-router/tests/pending-fallback-promise-replacement.test.tsx
  • packages/react-router/tests/preloaded-mount-resolution.test.tsx
  • packages/react-router/tests/redirect.test.tsx
  • packages/react-router/tests/root-pending-min.test.tsx
  • packages/react-router/tests/router.test.tsx
  • packages/react-router/tests/store-updates-during-navigation.test.tsx
  • packages/react-router/tests/transactional-loading.test.tsx
  • packages/react-router/tests/transitioner-listener-errors.test.tsx
  • packages/react-router/tests/transitioner-render-ack.test.tsx
  • packages/react-router/tests/transitioner-router-swap.test.tsx
  • packages/react-router/tests/useNavigate.test.tsx
  • packages/router-core/src/Matches.ts
  • packages/router-core/src/hydrate.ts
  • packages/router-core/src/isServer/client.ts
  • packages/router-core/src/isServer/development.ts
  • packages/router-core/src/isServer/server.ts
  • packages/router-core/src/load-matches.ts
  • packages/router-core/src/load.client.ts
  • packages/router-core/src/load.server.ts
  • packages/router-core/src/redirect.ts
  • packages/router-core/src/route-chunks.ts
  • packages/router-core/src/route.ts
  • packages/router-core/src/router.ts
  • packages/router-core/src/ssr/createRequestHandler.ts
  • packages/router-core/src/ssr/ssr-client.ts
  • packages/router-core/src/ssr/ssr-server.ts
  • packages/router-core/src/stores.ts
  • packages/router-core/tests/background-assets-stale.test.ts
  • packages/router-core/tests/background-trim-abort.test.ts
  • packages/router-core/tests/blocked-navigation-current-load.test.ts
  • packages/router-core/tests/boundary-component-chunk.test.ts
  • packages/router-core/tests/callbacks.test.ts
  • packages/router-core/tests/chunk-failure-lifecycle.test.ts
  • packages/router-core/tests/client-lane-adversarial.test.ts
  • packages/router-core/tests/fatal-load-rejection.test.ts
  • packages/router-core/tests/granular-stores.test.ts
  • packages/router-core/tests/hydrate.test.ts
  • packages/router-core/tests/hydrated-stay-match-data.test.ts
  • packages/router-core/tests/hydration-asset-context-order.test.ts
  • packages/router-core/tests/hydration-boundary-chunks.test.ts
  • packages/router-core/tests/hydration-currentness.test.ts
  • packages/router-core/tests/invalidate-pre-rematch-failure.test.ts
  • packages/router-core/tests/issue-3928-rapid-reload-abort.test.ts
  • packages/router-core/tests/issue-4078-loader-notfound-root-boundary.test.ts
  • packages/router-core/tests/issue-4444-param-parse-error-lazy-child.test.ts
  • packages/router-core/tests/issue-4476-preload-navigate-abort.test.ts
  • packages/router-core/tests/issue-4572-preload-root-beforeload-flags.test.ts
  • packages/router-core/tests/issue-4684-head-on-beforeload-error.test.ts
  • packages/router-core/tests/issue-5106-hydrated-notfound-boundary.test.ts
  • packages/router-core/tests/issue-6107-preload-chunk-failure.test.ts
  • packages/router-core/tests/issue-6221-head-waits-for-loader.test.ts
  • packages/router-core/tests/issue-6351-fuzzy-notfound-layout.test.ts
  • packages/router-core/tests/issue-6371-search-default-normalization-abort.test.ts
  • packages/router-core/tests/issue-7379-head-matches-direct-load.test.ts
  • packages/router-core/tests/issue-7635-dehydrated-error-child-head.test.ts
  • packages/router-core/tests/load-route-chunk.test.ts
  • packages/router-core/tests/load.test.ts
  • packages/router-core/tests/preflight-reentrant-context.test.ts
  • packages/router-core/tests/preload-adoption.test.ts
  • packages/router-core/tests/preload-background-parent-coherence.test.ts
  • packages/router-core/tests/preload-public-cache-behavior.test.ts
  • packages/router-core/tests/preload-public-signal-lifetime.test.ts
  • packages/router-core/tests/routerTestUtils.ts
  • packages/router-core/tests/serial-failure-foreground-prefix.test.ts
  • packages/router-core/tests/server-async-headers-decorative-hang.test.ts
  • packages/router-core/tests/server-beforeload-preload-flag.test.ts
  • packages/router-core/tests/server-chunk-failure-lifecycle.test.ts
  • packages/router-core/tests/server-concurrent-error-notfound.test.ts
  • packages/router-core/tests/server-headers-asset-failure.test.ts
  • packages/router-core/tests/server-loader-abort-error.test.ts
  • packages/router-core/tests/server-serial-ssr-notfound.test.ts
  • packages/router-core/tests/server-ssr-false-assets.test.ts
  • packages/router-core/tests/server-ssr-option-error.test.ts
  • packages/router-core/tests/stay-match-abort.test.ts
  • packages/router-core/tests/superseded-load-await.test.ts
  • packages/router-devtools-core/src/AgeTicker.tsx
  • packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx
  • packages/router-plugin/src/core/hmr/handle-route-update.ts
  • packages/router-plugin/tests/add-hmr.test.ts
  • packages/router-plugin/tests/add-hmr/snapshots/react/arrow-function@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/arrow-function@webpack-hot.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/createRootRoute-inline-component@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/createRootRoute@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/createRootRouteWithContext-type-args@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/explicit-undefined-component@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/function-declaration@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/multi-component@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/react/string-literal-keys@true.tsx
  • packages/router-plugin/tests/add-hmr/snapshots/solid/arrow-function@true.tsx
  • packages/router-plugin/tests/handle-route-update.test.ts
  • packages/solid-router/src/ClientOnly.tsx
  • packages/solid-router/src/Match.tsx
  • packages/solid-router/src/Matches.tsx
  • packages/solid-router/src/Transitioner.tsx
  • packages/solid-router/src/lazyRouteComponent.tsx
  • packages/solid-router/src/matchContext.tsx
  • packages/solid-router/src/routerStores.ts
  • packages/solid-router/src/ssr/renderRouterToStream.tsx
  • packages/solid-router/src/ssr/renderRouterToString.tsx
  • packages/solid-router/src/useMatch.tsx
  • packages/solid-router/tests/Transitioner.test.tsx
  • packages/solid-router/tests/component-preload-retry.test.tsx
  • packages/solid-router/tests/link.test.tsx
  • packages/solid-router/tests/loaders.test.tsx
  • packages/solid-router/tests/on-rendered-change-info.test.tsx
  • packages/solid-router/tests/pending-fallback-promise-replacement.test.tsx
  • packages/solid-router/tests/redirect.test.tsx
  • packages/solid-router/tests/router.test.tsx
  • packages/solid-router/tests/same-route-pending-blank.test.tsx
  • packages/solid-router/tests/server/errorComponent.test.tsx
  • packages/solid-router/tests/store-updates-during-navigation.test.tsx
  • packages/solid-router/tests/transitioner-listener-errors.test.tsx
  • packages/solid-router/tests/transitioner-remount.test.tsx
  • packages/solid-router/tests/transitioner-render-ack.test.tsx
  • packages/solid-router/tests/use-match-outgoing-transition.test.tsx
  • packages/start-server-core/src/createStartHandler.ts
  • packages/vue-router/src/Match.tsx
  • packages/vue-router/src/Matches.tsx
  • packages/vue-router/src/Transitioner.tsx
  • packages/vue-router/src/lazyRouteComponent.tsx
  • packages/vue-router/src/matchContext.tsx
  • packages/vue-router/src/routerStores.ts
  • packages/vue-router/src/ssr/renderRouterToStream.tsx
  • packages/vue-router/src/ssr/renderRouterToString.tsx
  • packages/vue-router/src/useMatch.tsx
  • packages/vue-router/tests/Matches.test.tsx
  • packages/vue-router/tests/Transitioner.test.tsx
  • packages/vue-router/tests/component-preload-retry.test.tsx
  • packages/vue-router/tests/hydration-capped-boundary-pending.test.tsx
  • packages/vue-router/tests/link.test.tsx
  • packages/vue-router/tests/loaders.test.tsx
  • packages/vue-router/tests/pending-fallback-promise-replacement.test.tsx
  • packages/vue-router/tests/redirect.test.tsx
  • packages/vue-router/tests/router.test.tsx
  • packages/vue-router/tests/store-updates-during-navigation.test.tsx
  • packages/vue-router/tests/transitioner-idle-after-render.test.tsx
  • packages/vue-router/tests/transitioner-listener-errors.test.tsx
  • packages/vue-router/tests/transitioner-remount-rendered.test.tsx
💤 Files with no reviewable changes (13)
  • packages/router-plugin/tests/add-hmr.test.ts
  • packages/solid-router/src/matchContext.tsx
  • packages/router-core/src/load-matches.ts
  • packages/solid-router/tests/server/errorComponent.test.tsx
  • packages/solid-router/tests/Transitioner.test.tsx
  • packages/router-core/src/redirect.ts
  • packages/vue-router/src/routerStores.ts
  • packages/router-core/src/ssr/ssr-server.ts
  • packages/solid-router/src/routerStores.ts
  • packages/router-core/tests/callbacks.test.ts
  • packages/vue-router/tests/redirect.test.tsx
  • packages/solid-router/tests/redirect.test.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts

Comment thread e2e/solid-start/selective-ssr/src/routes/ssr-false-pending-min.tsx
Comment thread packages/react-router/tests/router.test.tsx Outdated
Comment thread packages/router-core/tests/issue-6221-head-waits-for-loader.test.ts Outdated
Comment thread packages/solid-router/src/Transitioner.tsx Outdated
Comment thread packages/solid-router/tests/on-rendered-change-info.test.tsx Outdated
@github-actions github-actions Bot added the documentation Everything documentation related label Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/router-core/tests/preload-beforeload-reuse.test.ts (1)

222-280: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a same-route loaderDeps case. This test only changes the parent match; it doesn’t cover reusing preloaded child context when the route’s own deps change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/router-core/tests/preload-beforeload-reuse.test.ts` around lines 222
- 280, Extend the test around childBeforeLoad to add a same-route loaderDeps
scenario where the child route’s own dependencies change between preload and
navigation. Configure childRoute with loaderDeps and assert the preloaded child
context is not reused, including updated context values and the expected preload
flags.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/router-core/tests/preload-beforeload-reuse.test.ts`:
- Around line 242-245: Update the regression case around loaderDeps and context
to preserve type checking for the version contract: add a typed validateSearch
definition for version, replace Record<string, any> with the inferred or
explicit validated search type, and remove the as any casts around preloadRoute,
navigate, and beforeLoad replacement by using typed route refresh helpers or a
type-compatible mock.

---

Nitpick comments:
In `@packages/router-core/tests/preload-beforeload-reuse.test.ts`:
- Around line 222-280: Extend the test around childBeforeLoad to add a
same-route loaderDeps scenario where the child route’s own dependencies change
between preload and navigation. Configure childRoute with loaderDeps and assert
the preloaded child context is not reused, including updated context values and
the expected preload flags.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: beb16cf3-124d-4a1b-ae41-86535af7b3c1

📥 Commits

Reviewing files that changed from the base of the PR and between adf73dd and 6f75f50.

📒 Files selected for processing (3)
  • docs/router/guide/preloading.md
  • packages/router-core/src/load-client.ts
  • packages/router-core/tests/preload-beforeload-reuse.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/router-core/src/load-client.ts

Comment thread packages/router-core/tests/preload-beforeload-reuse.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/router-core/tests/hydration-currentness.test.ts`:
- Around line 205-232: Extract the repeated mockWindow.$_TSR scaffolding in the
hydration currentness tests into a helper such as mockDehydratedRouter,
accepting only the matches array and preserving the shared manifest,
dehydratedData, callbacks, buffer, and initialized values. Replace the
duplicated setups at the referenced test blocks with this helper while keeping
each test’s matches payload unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dae5e328-1744-4525-a06b-e2022da66f47

📥 Commits

Reviewing files that changed from the base of the PR and between 6f75f50 and f4b8934.

📒 Files selected for processing (10)
  • e2e/react-start/basic/src/routes/specialChars/search.tsx
  • e2e/react-start/basic/tests/special-characters.spec.ts
  • packages/react-router/src/Transitioner.tsx
  • packages/router-core/src/load-client.ts
  • packages/router-core/src/router.ts
  • packages/router-core/tests/hydrated-stay-match-data.test.ts
  • packages/router-core/tests/hydration-currentness.test.ts
  • packages/solid-router/src/Transitioner.tsx
  • packages/solid-router/tests/transitioner-render-ack.test.tsx
  • packages/vue-router/src/Transitioner.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/solid-router/tests/transitioner-render-ack.test.tsx
  • packages/react-router/src/Transitioner.tsx
  • packages/router-core/tests/hydrated-stay-match-data.test.ts
  • packages/solid-router/src/Transitioner.tsx
  • packages/vue-router/src/Transitioner.tsx
  • packages/router-core/src/load-client.ts
  • packages/router-core/src/router.ts

Comment thread packages/router-core/tests/hydration-currentness.test.ts Outdated
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

Sheraff added 2 commits July 20, 2026 18:52
* fix(router-core): complete lane match loader rewrite

* fix(router-core): harden match loading lifecycle

* fix(router-core): preserve hydrated context handoff

* bench(memory): accept expected abort errors

* perf(ssr): reduce request cancellation overhead (#7862)
…match-loader

# Conflicts:
#	e2e/react-start/selective-ssr/src/routeTree.gen.ts
#	e2e/solid-start/selective-ssr/src/routeTree.gen.ts
nx-cloud[bot]

This comment was marked as outdated.

Sheraff and others added 6 commits July 22, 2026 00:43
* fix(router-core): harden lane loading lifecycle

* ci: apply automated fixes

* fix(router-core): optimize lane loading followups

* fix(router-core): simplify redirect limit handling

* refactor(router-core): clarify loader state and caches

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* perf(router): reduce SSR lane loading overhead

* ci: apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix(router): address lane loader regressions

* perf(router-core): shave asset-prefix bookkeeping bytes

- rename the internal `_dataOnlyAssetEnd` match field to `_assetEnd`:
  property keys survive minification, so the shorter internal name saves
  bytes at every site in every bundle
- reduce the `_getAssetMatches` guard to a presence check: the field is
  only ever set on hydration presentation clones that already satisfy
  the pending/data-only/error-free/not-not-found conditions, and commits
  clear it (invariant documented at the guard)
- clone-then-patch the hydration handoff splice instead of spreading a
  conditional object per element, and drop the unreachable zero guard in
  `_getAssetMatches`

Measured (gzip, vs PR tip): react-router.full -43 B, vue-router.full
-35 B, react-router.minimal -8 B. All unit suites green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(router-devtools): preload lazy panel

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sheraff added 4 commits July 23, 2026 15:35
…7883)

* fix(router): final-review regressions, changeset, and byte recovery

Fixes the regressions vs main found in the final review of #7805:

- restore history-subscription cleanup on router provider unmount in all
  three adapters (react returns the unsubscribe unconditionally, solid
  uses onCleanup, vue uses onUnmounted), pinned by new
  transitioner-remount tests — a discarded router could previously keep
  loading on back/forward as a zombie
- same-destination navigations now join the in-flight transaction
  instead of aborting and restarting it (double-click no longer reruns
  loaders); reloads and same-location redirects keep restart semantics
- commitMatches cache retention can no longer resurrect a
  one-generation-old loaderData when a newer committed success exists
  for the same match id
- same-location dedup keeps __tempLocation/__tempKey so masked vs real
  same-href navigations commit their state again

Adds the missing release changeset enumerating the removed/changed
public API with migration hints.

Byte recovery: merges rendered-matches.ts, route-chunks.ts and
hydrate.ts into load-client.ts so the client bundle shares gzip
dictionary context across what were separate module boundaries
(-104..-186 gzip B per start scenario; plain router scenarios remain
net-negative vs main and hydration still tree-shakes out of them).

The solid/vue store-update-count pins were re-adjusted after verifying
the published update sequences are byte-identical: the counts only
shifted because a one-microtask timing change moves the tests'
waitFor-sampled window boundary (5 of 7 counts decreased).

* test(router-devtools-core): keep panel chunk warm-up out of the test budget

The cache-replacement test warmed Vite's lazy transform of
BaseTanStackRouterDevtoolsPanel inside the test body, so on slow CI
runners the transform alone could blow the 5s test timeout (observed at
5.89s). Move the warm-up to a beforeAll with its own generous timeout
and give the test itself explicit headroom. Pre-existing flake on the
lane branch tip, surfaced by this PR's CI being the first to run on it.

* refactor(router-core): extend lane typestate to matches and commits

The lane pipeline already carried phase brands at lane granularity
(Lane<'matched'|'contextualized'|'reduced'|'projected'>); this finishes
the pattern at the two granularities it was missing, at zero runtime
cost (all emitted dist JS verified byte-identical):

- settleInto becomes the sole granter of a SettledMatch brand via an
  assertion signature, and cacheLoaderMatch requires it — the
  loader -> settle -> cache ordering is now compiler-enforced. The one
  legitimate phase jump (hydration cache-seeding of already-settled
  dehydrated data) is a single named, commented boundary cast.
- commitMatches/commitRefreshMatches only accept a projected lane's
  matches (LaneMatches<'projected'>), so committing an earlier-phase
  lane no longer compiles.
- LoadTransaction's dev-only refresh triple collapses into one optional
  slot [presentation, handoff?], making a half-armed refresh state
  unrepresentable and shrinking the clear/read sites.
…match-loader

# Conflicts:
#	e2e/react-start/selective-ssr/src/routeTree.gen.ts
#	e2e/react-start/selective-ssr/src/routes/__root.tsx
#	e2e/react-start/selective-ssr/tests/app.spec.ts
#	packages/react-router/tests/component-preload-retry-pending-min.test.tsx
#	packages/react-router/tests/not-found.test.tsx
#	packages/react-router/tests/public-presentation-lane-contract.test.tsx
#	packages/react-router/tests/redirect.test.tsx
#	packages/react-router/tests/transactional-loading.test.tsx
#	packages/react-router/tests/transitioner-remount.test.tsx
#	packages/react-start-client/src/tests/hydrateStart.test.ts
#	packages/router-core/tests/background-trim-abort.test.ts
#	packages/router-core/tests/boundary-component-chunk.test.ts
#	packages/router-core/tests/callbacks.test.ts
#	packages/router-core/tests/client-lane-adversarial.test.ts
#	packages/router-core/tests/error-boundary-cache-generation.test.ts
#	packages/router-core/tests/granular-stores.test.ts
#	packages/router-core/tests/hydrate.test.ts
#	packages/router-core/tests/issue-6221-head-waits-for-loader.test.ts
#	packages/router-core/tests/loader-architecture-regressions.test.ts
#	packages/router-core/tests/loader-self-abort.test.ts
#	packages/router-core/tests/masked-location-state-commit.test.ts
#	packages/router-core/tests/parent-match-promise.test.ts
#	packages/router-core/tests/preload-adoption.test.ts
#	packages/router-core/tests/preload-beforeload-reuse.test.ts
#	packages/router-core/tests/preload-navigation-adoption.test.ts
#	packages/router-core/tests/preload-public-cache-behavior.test.ts
#	packages/router-core/tests/public-client-loading-contract.test.ts
#	packages/router-core/tests/public-preload-lane-contract.test.ts
#	packages/router-core/tests/same-destination-navigation-join.test.ts
#	packages/router-core/tests/server-beforeload-preload-flag.test.ts
#	packages/router-core/tests/server-loader-abort-error.test.ts
#	packages/router-plugin/tests/handle-route-update.test.ts
#	packages/solid-router/tests/component-preload-retry.test.tsx
#	packages/solid-router/tests/createLazyRoute.test.tsx
#	packages/solid-router/tests/loaders.test.tsx
#	packages/solid-start-client/src/tests/hydrateStart.test.ts
#	packages/vue-router/tests/Transitioner.test.tsx
#	packages/vue-router/tests/disableGlobalCatchBoundary.test.tsx
#	packages/vue-router/tests/transitioner-remount-rendered.test.tsx
#	packages/vue-router/tests/transitioner-remount.test.tsx
#	packages/vue-router/tests/useMatch.test.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
e2e/react-router/issue-7120/package.json (1)

14-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Resolve the internal workspace protocol before merging.

These internal dependencies use workspace:^, while the current coding guideline requires workspace:*. The supplied repository learning states that e2e applications conventionally use workspace:^, so please confirm which policy governs this PR. If the current guideline is authoritative, update all three ranges:

Proposed fix
-    "`@tanstack/react-router`": "workspace:^",
-    "`@tanstack/router-plugin`": "workspace:^",
+    "`@tanstack/react-router`": "workspace:*",
+    "`@tanstack/router-plugin`": "workspace:*",
...
-    "`@tanstack/router-e2e-utils`": "workspace:^",
+    "`@tanstack/router-e2e-utils`": "workspace:*",

As per coding guidelines, internal dependencies in package.json must use workspace:*; based on learnings, e2e apps conventionally use workspace:^, so this policy conflict needs explicit resolution.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/react-router/issue-7120/package.json` around lines 14 - 21, Resolve the
policy conflict for internal workspace dependencies in this package: confirm
whether the current guideline or the e2e convention governs this PR, then update
all three workspace ranges in the package manifest to the authoritative
protocol, using workspace:* if the guideline applies.

Sources: Coding guidelines, Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/lane-match-loader-rewrite.md:
- Around line 2-5: Update the changeset release levels for
`@tanstack/router-core`, `@tanstack/react-router`, `@tanstack/solid-router`, and
`@tanstack/vue-router` from patch to major to reflect the removed public members
and changed StartTransitionFn signature.

In `@e2e/react-router/issue-7457/src/main.tsx`:
- Around line 21-25: Declare the ambient __pendingSeen flag in
e2e/react-router/issue-7457/src/vite-env.d.ts, then replace the any-cast global
access in DefaultPendingComponent within
e2e/react-router/issue-7457/src/main.tsx and the corresponding test access in
e2e/react-router/issue-7457/tests/issue-7457.repro.spec.ts with direct
globalThis.__pendingSeen usage.

---

Nitpick comments:
In `@e2e/react-router/issue-7120/package.json`:
- Around line 14-21: Resolve the policy conflict for internal workspace
dependencies in this package: confirm whether the current guideline or the e2e
convention governs this PR, then update all three workspace ranges in the
package manifest to the authoritative protocol, using workspace:* if the
guideline applies.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 51034e37-ca80-4e45-ba7e-ca5dbe8df417

📥 Commits

Reviewing files that changed from the base of the PR and between f4b8934 and a4d5b8f.

📒 Files selected for processing (46)
  • .changeset/lane-match-loader-rewrite.md
  • benchmarks/memory/server/scenarios/aborted-requests/shared.ts
  • docs/router/api/router/RouteMatchType.md
  • docs/router/api/router/RouteOptionsType.md
  • docs/router/api/router/RouterOptionsType.md
  • docs/router/api/router/RouterStateType.md
  • docs/router/api/router/RouterType.md
  • docs/router/api/router/useChildMatchesHook.md
  • docs/router/api/router/useMatchesHook.md
  • docs/router/api/router/useParentMatchesHook.md
  • docs/router/guide/data-loading.md
  • docs/router/guide/path-params.md
  • docs/router/guide/preloading.md
  • docs/router/how-to/debug-router-issues.md
  • e2e/react-router/issue-7120/index.html
  • e2e/react-router/issue-7120/package.json
  • e2e/react-router/issue-7120/playwright.config.ts
  • e2e/react-router/issue-7120/src/main.tsx
  • e2e/react-router/issue-7120/src/redirectGate.ts
  • e2e/react-router/issue-7120/src/routeTree.gen.ts
  • e2e/react-router/issue-7120/src/routes/__root.tsx
  • e2e/react-router/issue-7120/src/routes/index.tsx
  • e2e/react-router/issue-7120/src/routes/posts.lazy.tsx
  • e2e/react-router/issue-7120/src/routes/posts.tsx
  • e2e/react-router/issue-7120/src/vite-env.d.ts
  • e2e/react-router/issue-7120/tests/issue-7120.repro.spec.ts
  • e2e/react-router/issue-7120/tsconfig.json
  • e2e/react-router/issue-7120/vite.config.ts
  • e2e/react-router/issue-7457/index.html
  • e2e/react-router/issue-7457/package.json
  • e2e/react-router/issue-7457/playwright.config.ts
  • e2e/react-router/issue-7457/src/main.tsx
  • e2e/react-router/issue-7457/src/routeTree.gen.ts
  • e2e/react-router/issue-7457/src/routes/__root.tsx
  • e2e/react-router/issue-7457/src/routes/another.tsx
  • e2e/react-router/issue-7457/src/routes/index.tsx
  • e2e/react-router/issue-7457/src/vite-env.d.ts
  • e2e/react-router/issue-7457/tests/issue-7457.repro.spec.ts
  • e2e/react-router/issue-7457/tsconfig.json
  • e2e/react-router/issue-7457/vite.config.js
  • e2e/react-router/scroll-restoration-sandbox-vite/tests/app.spec.ts
  • e2e/react-start/selective-ssr/src/routes/__root.tsx
  • e2e/react-start/selective-ssr/tests/app.spec.ts
  • e2e/solid-start/selective-ssr/dev-server.ts
  • e2e/solid-start/selective-ssr/playwright.config.ts
  • e2e/solid-start/selective-ssr/tests/issue-7283-dev-hydration.spec.ts

Comment on lines +2 to +5
'@tanstack/router-core': patch
'@tanstack/react-router': patch
'@tanstack/solid-router': patch
'@tanstack/vue-router': patch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== changeset file =="
cat -n .changeset/lane-match-loader-rewrite.md

echo
echo "== repo files mentioning semver / changeset / major release =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' -e 'semver|major release|patch release|changeset' README* .changeset docs . 2>/dev/null | head -n 200

Repository: TanStack/router

Length of output: 18706


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file list around changesets =="
git ls-files '.changeset/*' | sed -n '1,120p'

echo
echo "== outline of the referenced changeset =="
wc -l .changeset/lane-match-loader-rewrite.md
sed -n '1,120p' .changeset/lane-match-loader-rewrite.md

Repository: TanStack/router

Length of output: 3407


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .changeset/config.json =="
cat -n .changeset/config.json

echo
echo "== docs / config mentioning patch or major policy =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/.git/**' -e 'patch.*major|major.*patch|breaking.*patch|changeset.*patch|changeset.*major|semver policy|version policy|breaking change' .changeset docs README* package.json .github . 2>/dev/null | head -n 200

Repository: TanStack/router

Length of output: 16531


Use a major changeset for the API removals. The affected sections remove public members and change StartTransitionFn’s signature, so patch release metadata is inconsistent with the documented breaking surface.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.changeset/lane-match-loader-rewrite.md around lines 2 - 5, Update the
changeset release levels for `@tanstack/router-core`, `@tanstack/react-router`,
`@tanstack/solid-router`, and `@tanstack/vue-router` from patch to major to reflect
the removed public members and changed StartTransitionFn signature.

Comment on lines +21 to +25
function DefaultPendingComponent() {
useEffect(() => {
;(globalThis as any).__pendingSeen = true
}, [])
return <div data-testid="app-pending">loading</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd '^tsconfig\.json$' e2e/react-router/issue-7457 -x sh -c '
  echo "--- $1"
  sed -n "1,220p" "$1"
' sh {}

rg -n --glob '*.{ts,tsx,d.ts}' \
  '\(globalThis as any\)\.__pendingSeen|declare global|__pendingSeen' \
  e2e/react-router/issue-7457

Repository: TanStack/router

Length of output: 756


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "--- files"
git ls-files e2e/react-router/issue-7457

echo
echo "--- declaration/global matches"
rg -n --glob 'e2e/react-router/issue-7457/**/*.{ts,tsx,d.ts}' \
  'declare global|interface Window|__pendingSeen|globalThis as any' \
  e2e/react-router/issue-7457

echo
echo "--- tsconfig files"
fd 'tsconfig\.json$' e2e/react-router/issue-7457 -x sh -c '
  echo "### $1"
  sed -n "1,220p" "$1"
' sh {}

Repository: TanStack/router

Length of output: 1377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "--- vite-env.d.ts"
cat -n e2e/react-router/issue-7457/src/vite-env.d.ts

echo
echo "--- package.json"
cat -n e2e/react-router/issue-7457/package.json

echo
echo "--- playwright.config.ts"
cat -n e2e/react-router/issue-7457/playwright.config.ts

Repository: TanStack/router

Length of output: 2095


Declare __pendingSeen instead of casting globalThis to any. Add the ambient flag declaration in e2e/react-router/issue-7457/src/vite-env.d.ts, then use globalThis.__pendingSeen directly in e2e/react-router/issue-7457/src/main.tsx and e2e/react-router/issue-7457/tests/issue-7457.repro.spec.ts.

📍 Affects 2 files
  • e2e/react-router/issue-7457/src/main.tsx#L21-L25 (this comment)
  • e2e/react-router/issue-7457/tests/issue-7457.repro.spec.ts#L29-L31
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/react-router/issue-7457/src/main.tsx` around lines 21 - 25, Declare the
ambient __pendingSeen flag in e2e/react-router/issue-7457/src/vite-env.d.ts,
then replace the any-cast global access in DefaultPendingComponent within
e2e/react-router/issue-7457/src/main.tsx and the corresponding test access in
e2e/react-router/issue-7457/tests/issue-7457.repro.spec.ts with direct
globalThis.__pendingSeen usage.

Source: Coding guidelines

* Always execute beforeLoad for client lanes

* Simplify hydration handoff validation

* ci: apply automated fixes

* doc update

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/router-core/src/load-client.ts (1)

456-463: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Mutating lease decrement inside the guard is easy to misread.

--flight[2] both decrements and drives control flow, and an already-zero lease (reserved by transferPredecessorResources) would underflow to -1 and silently keep the registry entry. Consider making the reservation state explicit.

♻️ Suggested clarification
-  if (!flight || --flight[2]) {
+  if (!flight) {
+    return
+  }
+  if (process.env.NODE_ENV !== 'production' && flight[2] < 1) {
+    throw new Error('Invariant failed: releasing a flight without a lease')
+  }
+  if (--flight[2]) {
     return
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/router-core/src/load-client.ts` around lines 456 - 463, Update
releaseOwnedFlight so the lease decrement is performed explicitly before the
guard, and handle an already-zero lease as a reserved state without underflowing
or retaining the registry entry. Preserve the existing early return for missing
flights and only release/delete the owned flight when the resulting lease count
indicates it is no longer reserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/router-core/src/load-client.ts`:
- Around line 456-463: Update releaseOwnedFlight so the lease decrement is
performed explicitly before the guard, and handle an already-zero lease as a
reserved state without underflowing or retaining the registry entry. Preserve
the existing early return for missing flights and only release/delete the owned
flight when the resulting lease count indicates it is no longer reserved.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0aebeb69-11ac-4054-a1d1-fbf438a22719

📥 Commits

Reviewing files that changed from the base of the PR and between 2d639e1 and 1d20a9d.

📒 Files selected for processing (17)
  • docs/router/api/router/RouterType.md
  • docs/router/guide/preloading.md
  • packages/react-router/src/Transitioner.tsx
  • packages/router-core/INTERNALS.md
  • packages/router-core/src/load-client.ts
  • packages/router-core/src/router.ts
  • packages/router-core/tests/issue-3928-rapid-reload-abort.test.ts
  • packages/router-core/tests/issue-6371-search-default-normalization-abort.test.ts
  • packages/router-core/tests/load.test.ts
  • packages/router-core/tests/loader-architecture-regressions.test.ts
  • packages/router-core/tests/preload-adoption.test.ts
  • packages/router-core/tests/preload-beforeload-reuse.test.ts
  • packages/router-core/tests/preload-navigation-adoption.test.ts
  • packages/router-core/tests/preload-public-cache-behavior.test.ts
  • packages/router-core/tests/public-hydration-contract.test.ts
  • packages/router-core/tests/public-preload-lane-contract.test.ts
  • packages/router-core/tests/same-destination-navigation-join.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/router/guide/preloading.md
  • docs/router/api/router/RouterType.md
  • packages/router-core/tests/preload-beforeload-reuse.test.ts

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud has identified a possible root cause for your failed CI:

We determined this failure is an environment state issue rather than a code regression. The error originates from a stale compiled dist artifact (e2e/e2e-utils/dist/esm/e2eSetupTeardown.js) that was missing the e2eStartDummyServer export at test execution time, even though the source file correctly defines it and the PR makes no changes to e2e-utils. The dist has since been rebuilt correctly, confirming this was a build ordering issue in the CI environment.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/router-plugin/tests/handle-route-update.test.ts (1)

603-606: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid unchecked any for the React act global.

Use a typed globalThis extension so writes to IS_REACT_ACT_ENVIRONMENT remain type-checked. As per coding guidelines, “Use TypeScript strict mode with extensive type safety.”

Proposed fix
+const testGlobal = globalThis as typeof globalThis & {
+  IS_REACT_ACT_ENVIRONMENT?: boolean
+}
+
- delete (globalThis as any).IS_REACT_ACT_ENVIRONMENT
+ delete testGlobal.IS_REACT_ACT_ENVIRONMENT
...
- ;(globalThis as any).IS_REACT_ACT_ENVIRONMENT = previousActEnvironment
+ testGlobal.IS_REACT_ACT_ENVIRONMENT = previousActEnvironment
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/router-plugin/tests/handle-route-update.test.ts` around lines 603 -
606, Replace the unchecked globalThis casts in the IS_REACT_ACT_ENVIRONMENT
restoration logic with a typed globalThis extension, declaring the optional
React act environment property in the appropriate global type scope. Keep the
existing delete behavior for undefined values and assignment behavior for saved
values while ensuring both writes remain type-checked.

Source: Coding guidelines

packages/start-server-core/tests/createStartHandler.test.ts (1)

577-583: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract repeated onTestFinished cleanup pair into a shared helper.

The consoleError.mockRestore() + router.serverSsr?.cleanup() pair is duplicated verbatim across this and (per the change-details) many other cancellation tests in this file. A small helper (e.g. registerCancellationCleanup(router, consoleError)) called once per test would reduce repetition and keep future changes to the cleanup sequence in one place.

♻️ Suggested helper
function registerCancellationCleanup(
  router: AnyRouter,
  consoleError: ReturnType<typeof vi.spyOn>,
) {
  onTestFinished(() => {
    consoleError.mockRestore()
  })
  onTestFinished(() => {
    router.serverSsr?.cleanup()
  })
}

Then in each test:

-      onTestFinished(() => {
-        consoleError.mockRestore()
-      })
-      onTestFinished(() => {
-        router.serverSsr?.cleanup()
-      })
+      registerCancellationCleanup(router, consoleError)

Also applies to: 641-646

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/start-server-core/tests/createStartHandler.test.ts` around lines 577
- 583, Extract the duplicated consoleError.mockRestore and
router.serverSsr?.cleanup registrations into a shared
registerCancellationCleanup helper near the test utilities, accepting the router
and spy arguments. Replace both cancellation-test cleanup pairs, including the
occurrences around the referenced tests, with one helper call per test while
preserving cleanup order and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/router-plugin/tests/handle-route-update.test.ts`:
- Around line 603-606: Replace the unchecked globalThis casts in the
IS_REACT_ACT_ENVIRONMENT restoration logic with a typed globalThis extension,
declaring the optional React act environment property in the appropriate global
type scope. Keep the existing delete behavior for undefined values and
assignment behavior for saved values while ensuring both writes remain
type-checked.

In `@packages/start-server-core/tests/createStartHandler.test.ts`:
- Around line 577-583: Extract the duplicated consoleError.mockRestore and
router.serverSsr?.cleanup registrations into a shared
registerCancellationCleanup helper near the test utilities, accepting the router
and spy arguments. Replace both cancellation-test cleanup pairs, including the
occurrences around the referenced tests, with one helper call per test while
preserving cleanup order and behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 92fb7592-301b-4518-bb89-d03cef737520

📥 Commits

Reviewing files that changed from the base of the PR and between 1d20a9d and b8204ea.

📒 Files selected for processing (25)
  • packages/react-router/tests/issue-4467-lazy-route-pending.test.tsx
  • packages/react-router/tests/issue-4476-react-query-cancellation.test.tsx
  • packages/react-router/tests/issue-4759-pending-frame.test.tsx
  • packages/react-router/tests/issue-6371-search-default-normalization-abort.test.tsx
  • packages/react-router/tests/preloaded-mount-resolution.test.tsx
  • packages/react-router/tests/renderRouterToStream.test.tsx
  • packages/router-core/tests/hmr-refresh-lifecycle.test.ts
  • packages/router-core/tests/hydration-currentness.test.ts
  • packages/router-core/tests/issue-4078-loader-notfound-root-boundary.test.ts
  • packages/router-core/tests/issue-5427-hydration-root-global-not-found.test.ts
  • packages/router-core/tests/issue-6221-head-waits-for-loader.test.ts
  • packages/router-core/tests/issue-7602-parent-beforeload-context-child-loader.test.ts
  • packages/router-core/tests/issue-7759-in-flight-preload-eviction.test.ts
  • packages/router-core/tests/public-hydration-contract.test.ts
  • packages/router-core/tests/public-preload-lane-contract.test.ts
  • packages/router-core/tests/server-chunk-failure-lifecycle.test.ts
  • packages/router-core/tests/ssr-server-cleanup.test.ts
  • packages/router-plugin/tests/handle-route-update.test.ts
  • packages/solid-router/tests/createLazyRoute.test.tsx
  • packages/solid-router/tests/errorComponent.test.tsx
  • packages/solid-router/tests/transitioner-listener-errors.test.tsx
  • packages/solid-router/tests/transitioner-render-ack.test.tsx
  • packages/start-server-core/tests/createStartHandler.test.ts
  • packages/vue-router/tests/Transitioner.test.tsx
  • packages/vue-router/tests/transitioner-listener-errors.test.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment