Skip to content

benchmark: memory (codspeed)#7623

Open
Sheraff wants to merge 22 commits into
mainfrom
bench-codspeed-memory
Open

benchmark: memory (codspeed)#7623
Sheraff wants to merge 22 commits into
mainfrom
bench-codspeed-memory

Conversation

@Sheraff

@Sheraff Sheraff commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

TODO:

  • SSR memory benchmarks: how can we make sure we only measure server-side memory, right now we're calling handler.fetch in the same process that we process the request
  • How can we get data locally? CI CodSpeed is good, but local is just vitest bench which only gives timing numbers. This isn't helpful to "work on memory".
  • We need to make sure we're measuring steady state. CodSpeed reports peak memory as the main number. We don't have historical data yet so I'm not sure which number is looked at for the "3% threshold to denote significant changes", but i'm assuming it's peak memory. In that case we should make sure the peak isn't from the setup / initial loop (which seems to be the case in some of our benchmarks)
  • add solid and vue once react is properly set up

Summary by CodeRabbit

  • Chores
    • Added comprehensive memory benchmarking infrastructure with support for React, Solid, and Vue frameworks.
    • Implemented client-side and server-side benchmark scenarios measuring memory performance under various conditions.
    • Integrated flame graph profiling and performance monitoring tooling.

@Sheraff Sheraff requested a review from a team as a code owner June 12, 2026 22:02
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔄 Running review...
📝 Walkthrough

Walkthrough

Adds a memory benchmarking suite for client and server benchmarks, shared runners and profiling tools, React/Solid/Vue scenario implementations, generated route apps, workspace packages, and CI workflow updates for CodSpeed memory mode and local flame profiling.

Changes

Memory benchmark suite

Layer / File(s) Summary
Memory docs, workflow, and profiling tools
benchmarks/memory/README.md, benchmarks/memory/flame-control.ts, benchmarks/memory/run-flame.mjs, .github/workflows/client-nav-benchmarks.yml, .gitignore
Documents the memory benchmark suite, enables memory-mode workflow runs, ignores generated profile output, and adds shared heap-profile capture and report generation tools.
Client benchmark package and runners
benchmarks/memory/client/package.json, benchmarks/memory/client/*.ts, benchmarks/memory/client/vitest*.ts, benchmarks/memory/client/tsconfig.json
Adds the client benchmark package, shared benchmark interfaces and runners, jsdom bootstrap, Vitest project configs, and deterministic benchmark utilities.
Client interrupted navigations scenario
benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts, .../{react,solid,vue}/*
Adds interrupted-navigation memory benchmarks across React, Solid, and Vue with shared interruption orchestration, slow-loader registries, route apps, and scenario build/test wiring.
Client loader-data-retention scenario
benchmarks/memory/client/scenarios/loader-data-retention/shared.ts, .../{react,solid,vue}/*
Adds loader-data-retention benchmarks with deterministic loader payload generation, shared navigation assertions, framework route apps, and scenario wiring.
Client mount-unmount scenario
benchmarks/memory/client/scenarios/mount-unmount/shared.ts, .../{react,solid,vue}/*
Adds mount/unmount memory benchmarks with a shared cycle harness, per-framework route apps, and scenario build, flame, and typecheck targets.
Client navigation-churn scenario
benchmarks/memory/client/scenarios/navigation-churn/shared.ts, .../{react,solid,vue}/*
Adds alternating navigation-churn benchmarks with shared lifecycle logic, framework route apps for /a and /b, and scenario wiring.
Client preload-churn scenario
benchmarks/memory/client/scenarios/preload-churn/shared.ts, .../{react,solid,vue}/*
Adds preload-churn benchmarks with shared preload/eviction logic, deterministic item payloads and loader tracking, framework route apps, and scenario config.
Client unique-location-churn scenario
benchmarks/memory/client/scenarios/unique-location-churn/shared.ts, .../{react,solid,vue}/*
Adds unique-location churn benchmarks with generated {id,q} locations, framework route apps that validate search input, and scenario build/test wiring.
Server benchmark package and aborted-requests scenario
benchmarks/memory/server/package.json, benchmarks/memory/server/*.ts, benchmarks/memory/server/scenarios/aborted-requests/shared.ts, .../aborted-requests/{react,solid,vue}/*
Adds the server benchmark package, shared sequential request runners, and aborted-request streaming benchmarks across React, Solid, and Vue.
Server error-paths scenario
benchmarks/memory/server/scenarios/error-paths/react/*
Adds the React server error-paths benchmark with redirect, not-found, thrown-error, unmatched-route, and target-route handlers plus scenario wiring.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐇 I packed some heaps in moonlit crates,
And labeled routes with careful fates.
A churn here, a peak there too,
With flame-lit trails to follow through.
Now benchmarks hop in neat array—
Soft-pawed and measured all the way.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bench-codspeed-memory

@nx-cloud

nx-cloud Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit cbfde6d

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

☁️ Nx Cloud last updated this comment at 2026-06-13 20:38:08 UTC

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

3 package(s) bumped directly, 10 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/react-router 1.170.15 → 1.170.16 Changeset
@tanstack/solid-router 1.170.15 → 1.170.16 Changeset
@tanstack/start-server-core 1.169.14 → 1.169.15 Changeset
@tanstack/react-start 1.168.25 → 1.168.26 Dependent
@tanstack/react-start-client 1.168.13 → 1.168.14 Dependent
@tanstack/react-start-rsc 0.1.24 → 0.1.25 Dependent
@tanstack/react-start-server 1.167.19 → 1.167.20 Dependent
@tanstack/solid-start 1.168.25 → 1.168.26 Dependent
@tanstack/solid-start-client 1.168.13 → 1.168.14 Dependent
@tanstack/solid-start-server 1.167.19 → 1.167.20 Dependent
@tanstack/start-plugin-core 1.171.17 → 1.171.18 Dependent
@tanstack/vue-start 1.168.24 → 1.168.25 Dependent
@tanstack/vue-start-server 1.167.19 → 1.167.20 Dependent

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 09d4f9333413
  • Measured at: 2026-06-13T20:36:59.798Z
  • Baseline source: history:689c5ab32e9b
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Initial gzip Raw Brotli Trend
react-router.minimal 87.29 KiB 0 B (0.00%) 87.15 KiB 273.66 KiB 75.88 KiB ▁▁▁▁▃██████
react-router.full 91.02 KiB 0 B (0.00%) 90.88 KiB 285.56 KiB 79.09 KiB █▁▁▁▁▄▄▄▄▄▄
solid-router.minimal 35.48 KiB 0 B (0.00%) 35.36 KiB 105.86 KiB 32.03 KiB ▆▆█▁▁▁▁▁▁▁▁
solid-router.full 40.53 KiB 0 B (0.00%) 40.41 KiB 121.08 KiB 36.46 KiB ▆▆█▁▁▁▁▁▁▁▁
vue-router.minimal 52.97 KiB 0 B (0.00%) 52.84 KiB 149.90 KiB 47.62 KiB ██▁▁▁▁▁▁▁▁▁
vue-router.full 58.96 KiB 0 B (0.00%) 58.83 KiB 168.66 KiB 52.87 KiB ▁▁█████████
react-start.minimal 101.91 KiB 0 B (0.00%) 101.77 KiB 321.98 KiB 88.21 KiB ▁▁▂▂▃██████
react-start.deferred-hydration 102.65 KiB 0 B (0.00%) 101.80 KiB 323.36 KiB 88.90 KiB ▁▂▂▂▂██████
react-start.full 105.31 KiB 0 B (0.00%) 105.18 KiB 331.91 KiB 91.06 KiB █▁▁▁▂▆▆▆▆▆▆
react-start.rsbuild.minimal 99.63 KiB 0 B (0.00%) 99.46 KiB 316.43 KiB 85.79 KiB ▃▁▂▂▃██████
react-start.rsbuild.minimal-iife 100.03 KiB 0 B (0.00%) 99.87 KiB 317.37 KiB 86.08 KiB ▃▁▂▂▃██████
react-start.rsbuild.full 102.86 KiB 0 B (0.00%) 102.68 KiB 326.48 KiB 88.53 KiB █▁▁▁▁▅▅▅▅▅▅
solid-start.minimal 49.60 KiB 0 B (0.00%) 49.47 KiB 151.93 KiB 43.79 KiB ▆▆█▁▁▁▁▁▁▁▁
solid-start.deferred-hydration 52.86 KiB 0 B (0.00%) 49.53 KiB 159.97 KiB 46.81 KiB ▄▄█▁▁▁▁▁▁▁▁
solid-start.full 55.40 KiB 0 B (0.00%) 55.27 KiB 168.97 KiB 48.80 KiB ▅▅█▁▁▁▁▁▁▁▁
vue-start.minimal 71.02 KiB 0 B (0.00%) 70.89 KiB 207.04 KiB 62.93 KiB ▁▁█████████
vue-start.full 75.01 KiB 0 B (0.00%) 74.88 KiB 219.68 KiB 66.40 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 Jun 12, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-rsc

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: ab7fb18

@codspeed-hq

codspeed-hq Bot commented Jun 12, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 5.39%

⚡ 2 improved benchmarks
✅ 94 untouched benchmarks
🆕 16 new benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation client-side navigation loop (solid) 116.9 ms 110.4 ms +5.87%
Simulation client-side navigation loop (vue) 85.2 ms 81.2 ms +4.91%
🆕 Memory mem aborted-requests (react) N/A 1.1 MB N/A
🆕 Memory mem error-paths error (react) N/A 674.6 KB N/A
🆕 Memory mem error-paths not-found (react) N/A 943 KB N/A
🆕 Memory mem error-paths redirect (react) N/A 472.4 KB N/A
🆕 Memory mem error-paths unmatched (react) N/A 1.1 MB N/A
🆕 Memory mem peak-large-page (react) N/A 2 MB N/A
🆕 Memory mem request-churn (react) N/A 1.6 MB N/A
🆕 Memory mem serialization-payload (react) N/A 32.6 MB N/A
🆕 Memory mem server-fn-churn (react) N/A 394 KB N/A
🆕 Memory mem streaming-peak chunked (react) N/A 10.9 MB N/A
🆕 Memory mem interrupted-navigations (react) N/A 757.3 KB N/A
🆕 Memory mem loader-data-retention (react) N/A 2.4 MB N/A
🆕 Memory mem mount-unmount (react) N/A 644.8 KB N/A
🆕 Memory mem navigation-churn (react) N/A 429.5 KB N/A
🆕 Memory mem preload-churn (react) N/A 633.8 KB N/A
🆕 Memory mem unique-location-churn (react) N/A 729.1 KB N/A

Tip

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


Comparing bench-codspeed-memory (ed51981) with main (36ed574)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (689c5ab) during the generation of this report, so 36ed574 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@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: 4

🧹 Nitpick comments (4)
.github/workflows/memory-benchmarks.yml (1)

8-14: 📐 Maintainability & Code Quality | ⚡ Quick win

Broaden the trigger set for workspace changes.

This workflow will not rerun when root workspace files like pnpm-workspace.yaml change, so benchmark registration/dependency drift can slip past CI. Consider including the workspace manifest and lockfile in the paths filter.

🤖 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 @.github/workflows/memory-benchmarks.yml around lines 8 - 14, The workflow's
path filters only include 'packages/**' and 'benchmarks/**', so changes to
workspace-level files (e.g., pnpm-workspace.yaml or the lockfile) won't trigger
the job; update both the push and pull_request paths arrays to also include the
workspace manifest and lockfile (for example add 'pnpm-workspace.yaml' and
'pnpm-lock.yaml' or your workspace's lockfile name) so modifications to
workspace configuration and dependency lockfiles rerun the memory-benchmarks
workflow.
benchmarks/memory/client/scenarios/interrupted-navigations/react/vite.config.ts (1)

13-17: 📐 Maintainability & Code Quality | ⚡ Quick win

Simplify plugin array pattern.

The !!(condition) && plugin() pattern in benchmarks/memory/client/scenarios/interrupted-navigations/react/vite.config.ts, benchmarks/memory/client/scenarios/mount-unmount/react/vite.config.ts, benchmarks/memory/client/scenarios/navigation-churn/react/vite.config.ts, and benchmarks/memory/client/scenarios/preload-churn/react/vite.config.ts produces an array containing false when the condition is falsy. While Vite filters falsy values, conditional spread is cleaner and more explicit.

♻️ Recommended pattern
   plugins: [
-    !!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) &&
-      codspeedPlugin(),
+    ...(process.env.VITEST && process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()] : []),
     react(),
   ],

Alternatively, use .filter(Boolean) at the end of the array.

🤖 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
`@benchmarks/memory/client/scenarios/interrupted-navigations/react/vite.config.ts`
around lines 13 - 17, The plugins array uses the pattern "!!(process.env.VITEST
&& process.env.WITH_INSTRUMENTATION) && codspeedPlugin()" which yields falsy
entries; update the plugins array to conditionally include codspeedPlugin() more
cleanly (e.g., use a conditional spread like ...(process.env.VITEST &&
process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()] : []) or build the array
and call .filter(Boolean) at the end) so only actual plugin functions (react(),
codspeedPlugin()) remain in the final plugins list; apply this change for the
plugins array that contains codspeedPlugin() and react().
benchmarks/memory/client/scenarios/unique-location-churn/react/vite.config.ts (1)

14-15: 🎯 Functional Correctness

Guard CodSpeed activation against "false"/"0" env strings.

Current CI/README wiring always sets WITH_INSTRUMENTATION=1, so the existing process.env.* truthiness check is unlikely to misfire in benchmarks today. Still, if WITH_INSTRUMENTATION (or VITEST) is ever set to "false"/"0" in other scripts, those values are truthy and would enable codspeedPlugin() unintentionally—parse the env vars explicitly (e.g., === 'true' || === '1') like in the proposed fix.

🤖 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
`@benchmarks/memory/client/scenarios/unique-location-churn/react/vite.config.ts`
around lines 14 - 15, The current truthiness check for enabling codspeedPlugin
uses !!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) which treats
strings like "false" or "0" as truthy; update the condition in vite.config.ts to
explicitly compare process.env.VITEST and process.env.WITH_INSTRUMENTATION
against accepted true values (e.g., === 'true' || === '1') before invoking
codspeedPlugin(), so codspeedPlugin() is only activated when both env vars are
explicitly set to a truthy string.
benchmarks/memory/server/scenarios/peak-large-page/react/src/large-page-data.ts (1)

98-111: 📐 Maintainability & Code Quality | 💤 Low value

Duplicated LCG logic requires manual synchronization.

The comment notes this is a local copy of benchmarks/memory/server/bench-utils.ts that must be kept in sync manually. Consider whether the benchmark harness could provide this utility at build time or through a shared constant to eliminate the sync risk.

🤖 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
`@benchmarks/memory/server/scenarios/peak-large-page/react/src/large-page-data.ts`
around lines 98 - 111, Duplicate LCG logic exists in createDeterministicRandom
and randomSegment and is manually kept in sync with
benchmarks/memory/server/bench-utils.ts; replace the local copy by importing the
shared generator (or move the functions into a common module/package used by
both the app and benchmark harness) or wire the harness to inject the utility at
build time so createDeterministicRandom and randomSegment are removed from this
file and the single shared implementation is consumed instead.
🤖 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 `@benchmarks/memory/client/scenarios/mount-unmount/react/project.json`:
- Line 15: The inline env assignment in the "command" string
("NODE_ENV=production vite build --config {projectRoot}/vite.config.ts") is not
cross‑platform; update the project.json to either prefix the command with
cross-env (e.g., use "cross-env NODE_ENV=production vite build --config
{projectRoot}/vite.config.ts") after adding cross-env as a dependency, or remove
the inline NODE_ENV and set production mode via the Nx executor configuration or
Vite's default production mode/define block in vite.config.ts so builds work on
Windows and Unix alike.

In `@benchmarks/memory/server/package.json`:
- Around line 6-7: The package.json in benchmarks/memory/server has internal
dependencies "`@tanstack/react-router`" and "`@tanstack/react-start`" pinned with
"workspace:^" which violates the repo policy; update their versions to use the
workspace protocol "workspace:*" by replacing the version strings for
"`@tanstack/react-router`" and "`@tanstack/react-start`" in package.json so they
read "workspace:*".

In `@benchmarks/memory/server/scenarios/server-fn-churn/react/memory.bench.ts`:
- Around line 240-252: The expectedIdsByRequest map is only populated for index
=== 0 and index === 1, so most requests bypass validation; remove the
conditional index checks and always set expectedIdsByRequest for each built
request (e.g., for the GET path where expectedIdsByRequest.set(request,
fixture.id) is currently under index === 0, and for the POST flow where it's
under index === 1), ensuring every call to buildPostRequest/buildGetRequest
stores fixture.id (from postFixtures/getFixtures and fixtureIndex) into
expectedIdsByRequest so validateServerFnBody can validate every iteration.

In `@packages/react-router/src/ssr/renderRouterToStream.tsx`:
- Around line 60-63: The onError handler in renderRouterToStream.tsx uses a
single-line if without braces (if (isAbortError(error)) return) which violates
the TypeScript style rule; update the onError callback (the onError function
handling errors in renderRouterToStream) to wrap the early return in curly
braces (e.g., if (isAbortError(error)) { return } ) so that isAbortError(error)
check uses a block-scoped body while preserving the existing console.error
behavior.

---

Nitpick comments:
In @.github/workflows/memory-benchmarks.yml:
- Around line 8-14: The workflow's path filters only include 'packages/**' and
'benchmarks/**', so changes to workspace-level files (e.g., pnpm-workspace.yaml
or the lockfile) won't trigger the job; update both the push and pull_request
paths arrays to also include the workspace manifest and lockfile (for example
add 'pnpm-workspace.yaml' and 'pnpm-lock.yaml' or your workspace's lockfile
name) so modifications to workspace configuration and dependency lockfiles rerun
the memory-benchmarks workflow.

In
`@benchmarks/memory/client/scenarios/interrupted-navigations/react/vite.config.ts`:
- Around line 13-17: The plugins array uses the pattern "!!(process.env.VITEST
&& process.env.WITH_INSTRUMENTATION) && codspeedPlugin()" which yields falsy
entries; update the plugins array to conditionally include codspeedPlugin() more
cleanly (e.g., use a conditional spread like ...(process.env.VITEST &&
process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()] : []) or build the array
and call .filter(Boolean) at the end) so only actual plugin functions (react(),
codspeedPlugin()) remain in the final plugins list; apply this change for the
plugins array that contains codspeedPlugin() and react().

In
`@benchmarks/memory/client/scenarios/unique-location-churn/react/vite.config.ts`:
- Around line 14-15: The current truthiness check for enabling codspeedPlugin
uses !!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) which treats
strings like "false" or "0" as truthy; update the condition in vite.config.ts to
explicitly compare process.env.VITEST and process.env.WITH_INSTRUMENTATION
against accepted true values (e.g., === 'true' || === '1') before invoking
codspeedPlugin(), so codspeedPlugin() is only activated when both env vars are
explicitly set to a truthy string.

In
`@benchmarks/memory/server/scenarios/peak-large-page/react/src/large-page-data.ts`:
- Around line 98-111: Duplicate LCG logic exists in createDeterministicRandom
and randomSegment and is manually kept in sync with
benchmarks/memory/server/bench-utils.ts; replace the local copy by importing the
shared generator (or move the functions into a common module/package used by
both the app and benchmark harness) or wire the harness to inject the utility at
build time so createDeterministicRandom and randomSegment are removed from this
file and the single shared implementation is consumed instead.
🪄 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: 7c7015ad-66f5-470f-b9d5-dcd60d724b08

📥 Commits

Reviewing files that changed from the base of the PR and between a2b9d51 and eab7570.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (156)
  • .github/workflows/memory-benchmarks.yml
  • benchmarks/memory/README.md
  • benchmarks/memory/client/bench-utils.ts
  • benchmarks/memory/client/package.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/project.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/setup.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/app.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/router.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/routes/fast.$id.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/routes/slow.$id.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/src/slow-loaders.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/tsconfig.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/vite.config.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json
  • benchmarks/memory/client/scenarios/loader-data-retention/react/setup.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/app.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/loader-data.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/router.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/routes/page.$id.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/routes/shell.index.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/routes/shell.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/tsconfig.json
  • benchmarks/memory/client/scenarios/loader-data-retention/react/vite.config.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json
  • benchmarks/memory/client/scenarios/mount-unmount/react/setup.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/src/app.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/react/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/src/router.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/react/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/react/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/react/tsconfig.json
  • benchmarks/memory/client/scenarios/mount-unmount/react/vite.config.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/project.json
  • benchmarks/memory/client/scenarios/navigation-churn/react/setup.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/src/app.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/react/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/src/router.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/react/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/react/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/react/src/routes/b.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/navigation-churn/react/vite.config.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/project.json
  • benchmarks/memory/client/scenarios/preload-churn/react/setup.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/src/app.tsx
  • benchmarks/memory/client/scenarios/preload-churn/react/src/item-payload.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/src/router.tsx
  • benchmarks/memory/client/scenarios/preload-churn/react/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/preload-churn/react/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/preload-churn/react/src/routes/items.$id.tsx
  • benchmarks/memory/client/scenarios/preload-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/preload-churn/react/vite.config.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/project.json
  • benchmarks/memory/client/scenarios/unique-location-churn/react/setup.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/src/app.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/react/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/src/router.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/react/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/react/src/routes/items.$id.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/react/vite.config.ts
  • benchmarks/memory/client/tsconfig.json
  • benchmarks/memory/client/vitest.react.config.ts
  • benchmarks/memory/client/vitest.setup.ts
  • benchmarks/memory/server/bench-utils.ts
  • benchmarks/memory/server/package.json
  • benchmarks/memory/server/scenarios/aborted-requests/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/project.json
  • benchmarks/memory/server/scenarios/aborted-requests/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/src/router.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/react/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/react/src/routes/stream.$id.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/react/tsconfig.json
  • benchmarks/memory/server/scenarios/aborted-requests/react/vite.config.ts
  • benchmarks/memory/server/scenarios/error-paths/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/error-paths/react/project.json
  • benchmarks/memory/server/scenarios/error-paths/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/error-paths/react/src/router.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/src/routes/boom.$id.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/src/routes/from.$id.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/src/routes/missing.$id.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/src/routes/target.$id.tsx
  • benchmarks/memory/server/scenarios/error-paths/react/tsconfig.json
  • benchmarks/memory/server/scenarios/error-paths/react/vite.config.ts
  • benchmarks/memory/server/scenarios/peak-large-page/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/peak-large-page/react/project.json
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/large-page-data.ts
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/router.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.l3.l4.l5.l6.l7.l8.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.l3.l4.l5.l6.l7.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.l3.l4.l5.l6.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.l3.l4.l5.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.l3.l4.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.l3.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.l2.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/src/routes/l1.tsx
  • benchmarks/memory/server/scenarios/peak-large-page/react/tsconfig.json
  • benchmarks/memory/server/scenarios/peak-large-page/react/vite.config.ts
  • benchmarks/memory/server/scenarios/request-churn/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/request-churn/react/project.json
  • benchmarks/memory/server/scenarios/request-churn/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/request-churn/react/src/router.tsx
  • benchmarks/memory/server/scenarios/request-churn/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/request-churn/react/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/request-churn/react/src/routes/items.$id.tsx
  • benchmarks/memory/server/scenarios/request-churn/react/tsconfig.json
  • benchmarks/memory/server/scenarios/request-churn/react/vite.config.ts
  • benchmarks/memory/server/scenarios/serialization-payload/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/serialization-payload/react/project.json
  • benchmarks/memory/server/scenarios/serialization-payload/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/serialization-payload/react/src/router.tsx
  • benchmarks/memory/server/scenarios/serialization-payload/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/serialization-payload/react/src/routes/data.$id.tsx
  • benchmarks/memory/server/scenarios/serialization-payload/react/tsconfig.json
  • benchmarks/memory/server/scenarios/serialization-payload/react/vite.config.ts
  • benchmarks/memory/server/scenarios/server-fn-churn/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/server-fn-churn/react/project.json
  • benchmarks/memory/server/scenarios/server-fn-churn/react/src/fns.ts
  • benchmarks/memory/server/scenarios/server-fn-churn/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/server-fn-churn/react/src/router.tsx
  • benchmarks/memory/server/scenarios/server-fn-churn/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/server-fn-churn/react/src/routes/api.fn-urls.ts
  • benchmarks/memory/server/scenarios/server-fn-churn/react/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/server-fn-churn/react/tsconfig.json
  • benchmarks/memory/server/scenarios/server-fn-churn/react/vite.config.ts
  • benchmarks/memory/server/scenarios/streaming-peak/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/streaming-peak/react/project.json
  • benchmarks/memory/server/scenarios/streaming-peak/react/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/streaming-peak/react/src/router.tsx
  • benchmarks/memory/server/scenarios/streaming-peak/react/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/streaming-peak/react/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/streaming-peak/react/src/routes/stream.$id.tsx
  • benchmarks/memory/server/scenarios/streaming-peak/react/tsconfig.json
  • benchmarks/memory/server/scenarios/streaming-peak/react/vite.config.ts
  • benchmarks/memory/server/tsconfig.json
  • benchmarks/memory/server/vitest.react.config.ts
  • packages/react-router/src/ssr/renderRouterToStream.tsx
  • pnpm-workspace.yaml

Comment thread benchmarks/memory/server/package.json Outdated
Comment thread benchmarks/memory/server/scenarios/server-fn-churn/react/memory.bench.ts Outdated
Comment thread packages/react-router/src/ssr/renderRouterToStream.tsx

@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

A new CI pipeline execution was requested that may update the conclusion below...

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

We classified this failure as an environment issue rather than a code change because the SyntaxError: missing ) after argument list occurs in the external dummy server process used by the e2e test infrastructure, and cannot be traced to any specific line in the PR's diff. Our changes to renderRouterToStream.tsx are syntactically valid TypeScript and would not produce this kind of runtime syntax error when compiled.

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 (1)
.github/workflows/client-nav-benchmarks.yml (1)

55-57: 📐 Maintainability & Code Quality

Clear documentation of the React-only limitation.

The TODO comment appropriately explains why memory benchmarks are currently React-only and notes the path to future unification.

Would you like me to open a tracking issue for the planned unification once Solid and Vue memory benchmarks are added?

🤖 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 @.github/workflows/client-nav-benchmarks.yml around lines 55 - 57, Clarify
the existing TODO by explicitly stating that memory benchmarks currently run
only for React (add a short line like "Currently React-only") and add a
follow-up action to create a tracking issue for unifying memory benchmarks
across frameworks; reference the benchmark matrix and the identifiers
`memory-server` and `memory-client` and the `mode: simulation|memory` constraint
so the commenter knows exactly what to track and later link the issue to.
🤖 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 @.github/workflows/client-nav-benchmarks.yml:
- Around line 55-57: Clarify the existing TODO by explicitly stating that memory
benchmarks currently run only for React (add a short line like "Currently
React-only") and add a follow-up action to create a tracking issue for unifying
memory benchmarks across frameworks; reference the benchmark matrix and the
identifiers `memory-server` and `memory-client` and the `mode:
simulation|memory` constraint so the commenter knows exactly what to track and
later link the issue to.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c996e485-c1b0-434e-903c-c0b78c498af2

📥 Commits

Reviewing files that changed from the base of the PR and between eab7570 and 3d31b79.

📒 Files selected for processing (1)
  • .github/workflows/client-nav-benchmarks.yml

@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 @.github/workflows/client-nav-benchmarks.yml:
- Line 71: The workflow is passing an unsupported CodSpeed `mode` via
matrix.mode (used by CodSpeedHQ/action@v4.17.0); update the matrix so the `mode`
values are only documented options (e.g., replace `"memory"` with `"walltime"`
or a comma-separated list like `"simulation,walltime"`), or change the step
input `mode: ${{ matrix.mode }}` to a fixed supported value and/or add a
separate matrix axis mapping memory benchmarks to the correct CodSpeed
configuration; ensure the `mode` input to CodSpeedHQ/action is one of the
supported strings (simulation or walltime) rather than `"memory"`.
🪄 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: 8ea06633-d580-4838-a05d-b41422f4a838

📥 Commits

Reviewing files that changed from the base of the PR and between 3d31b79 and 4c6d3af.

📒 Files selected for processing (1)
  • .github/workflows/client-nav-benchmarks.yml

Comment thread .github/workflows/client-nav-benchmarks.yml
@socket-security

socket-security Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedjsdom@​29.1.18110010093100

View full report

@socket-security

socket-security Bot commented Jun 13, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm css-tree is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: pnpm-lock.yamlnpm/jsdom@29.1.1npm/css-tree@3.2.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/css-tree@3.2.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm data-urls is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: pnpm-lock.yamlnpm/jsdom@29.1.1npm/data-urls@7.0.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/data-urls@7.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm jsdom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: benchmarks/memory/client/package.jsonnpm/jsdom@29.1.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/jsdom@29.1.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm jsdom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: benchmarks/memory/client/package.jsonnpm/jsdom@29.1.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/jsdom@29.1.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@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

🧹 Nitpick comments (3)
benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts (1)

12-13: 💤 Low value

Consider using array filtering for conditional plugins across Vite configs. The !!(condition) && plugin() pattern works because Vite filters falsy values, but explicit spread/filtering is clearer and more maintainable:

  • benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts#L12-L13: replace !!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) && codspeedPlugin() with ...(process.env.VITEST && process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()] : [])
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/vite.config.ts#L14-L15: same replacement pattern
  • benchmarks/memory/client/scenarios/preload-churn/vue/vite.config.ts#L15-L16: same replacement pattern
🤖 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 `@benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts`
around lines 12 - 13, Replace the conditional plugin expression that relies on
`!!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) && codspeedPlugin()`
with an explicit spread of a conditional array so falsy values are not injected
implicitly: in
benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts (lines
12-13) use the pattern that spreads either [codspeedPlugin()] or [] based on
(process.env.VITEST && process.env.WITH_INSTRUMENTATION); do the same
replacement in
benchmarks/memory/client/scenarios/unique-location-churn/solid/vite.config.ts
(lines 14-15) and
benchmarks/memory/client/scenarios/preload-churn/vue/vite.config.ts (lines
15-16), keeping the plugin factory `codspeedPlugin()` and the environment checks
unchanged.
benchmarks/memory/client/scenarios/loader-data-retention/solid/vite.config.ts (1)

14-15: 💤 Low value

Consider using array filter for cleaner plugin configuration.

The double-negation short-circuit pattern !!(condition) && plugin() works because Vite filters out falsy values, but it can be clearer to use array methods:

...(process.env.VITEST && process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()] : [])

This makes the intent more explicit and avoids false entries in the array.

🤖 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
`@benchmarks/memory/client/scenarios/loader-data-retention/solid/vite.config.ts`
around lines 14 - 15, Replace the double-negation short-circuit expression with
an explicit spread/ternary so the plugin array contains either codspeedPlugin()
or nothing; specifically, change the entry "!!(process.env.VITEST &&
process.env.WITH_INSTRUMENTATION) && codspeedPlugin()" to use the pattern
"...(process.env.VITEST && process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()]
: [])" so the intent is clearer and no falsy value can appear in the plugins
array.
benchmarks/memory/server/scenarios/aborted-requests/vue/project.json (1)

15-15: ⚡ Quick win

Shell-specific environment variable syntax breaks Windows compatibility.

The NODE_ENV=production prefix is a Unix shell pattern that won't work in Windows Command Prompt or PowerShell. Consider using cross-env or NX's built-in environment variable support:

"command": "cross-env NODE_ENV=production vite build --config {projectRoot}/vite.config.ts"

Or use NX environment options if available.

🤖 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 `@benchmarks/memory/server/scenarios/aborted-requests/vue/project.json` at line
15, The "command" property currently uses Unix-only syntax ("NODE_ENV=production
vite build --config {projectRoot}/vite.config.ts"); replace this with a
cross-platform invocation by prefixing with cross-env (e.g., "cross-env
NODE_ENV=production vite build --config {projectRoot}/vite.config.ts") or, if
using Nx, move NODE_ENV into the executor/target's environment configuration
(use the target's "options" or "env" support) so the build runs on Windows as
well.
🤖 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 `@benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts`:
- Around line 18-24: MountedApp currently types router as unknown which forces
an unchecked cast later; change the type to the concrete router interface used
by before()/interrupt() (e.g., replace "router: unknown" with "router:
InterruptedNavigationRouter") so the compiler enforces the router contract,
ensure InterruptedNavigationRouter is imported or declared in this module, and
keep MountTestApp and ResolveAllSlowLoaders signatures as they are; after this
change you can remove the force-cast at the usage site (around line 224) because
the returned MountedApp.router will already be correctly typed.

In `@benchmarks/memory/client/scenarios/loader-data-retention/shared.ts`:
- Around line 118-124: The waitForNextRender function can hang indefinitely;
update it to include a configurable timeout (e.g., 10–30s) so the returned
Promise rejects when the timeout elapses, and ensure the timeout is cleared when
resolveRendered is called; specifically, in waitForNextRender assign a timer via
setTimeout that rejects the promise with a clear error message, store/clear that
timer inside the resolveRendered handler, and propagate the rejection to callers
(e.g., navigateTo) so the benchmark fails fast instead of hanging.
- Around line 8-14: Change the MountedApp type so router is strongly typed as
LoaderDataRouter instead of unknown, update MountTestApp accordingly, and remove
the force-cast of mounted.router (i.e., stop using mounted.router as
LoaderDataRouter) so the returned mount implementations must match the
LoaderDataRouter contract at compile time; also add the necessary import for the
LoaderDataRouter type where MountedApp is declared.

In `@benchmarks/memory/client/scenarios/mount-unmount/react/project.json`:
- Line 15: Replace the platform-dependent inline env assignments with cross-env
in the listed project.json targets: in
benchmarks/memory/client/scenarios/mount-unmount/react/project.json (15-15)
update the build:client command to use cross-env NODE_ENV=production vite build;
in the same file (28-28) update build:client:flame to use cross-env
NODE_ENV=production vite build; in the same file (37-37) update test:flame to
use cross-env NODE_ENV=production node; in
benchmarks/memory/client/scenarios/mount-unmount/vue/project.json (15-15) update
build:client to cross-env NODE_ENV=production vite build; (28-28) update
build:client:flame to cross-env NODE_ENV=production vite build; (37-37) update
test:flame to cross-env NODE_ENV=production node; in
benchmarks/memory/client/scenarios/loader-data-retention/react/project.json
(15-15) update build:client to cross-env NODE_ENV=production vite build; (28-28)
update build:client:flame to cross-env NODE_ENV=production vite build; (37-37)
update test:flame to cross-env NODE_ENV=production node so the commands work
cross-platform.

In `@benchmarks/memory/client/scenarios/mount-unmount/shared.ts`:
- Around line 3-13: The MountedApp type currently declares router as unknown
which forces a runtime assertion elsewhere; change MountedApp.router from
unknown to RenderRouter (type MountedApp = { router: RenderRouter; unmount: ()
=> void }) and remove the explicit cast of mounted.router to RenderRouter where
used so the compiler enforces the contract; ensure MountTestApp still returns
MountedApp and update any affected usages to satisfy the stricter type if
needed.

In `@benchmarks/memory/client/scenarios/unique-location-churn/shared.ts`:
- Around line 13-16: MountedApp.router is typed as unknown which forces a
runtime cast to NavigationRouter; change the MountedApp type so router:
NavigationRouter (and add the necessary import for NavigationRouter), then
remove the cast at the site that currently casts to NavigationRouter (around the
code that references router at ~line 103) so callers use the typed property
directly.

---

Nitpick comments:
In
`@benchmarks/memory/client/scenarios/loader-data-retention/solid/vite.config.ts`:
- Around line 14-15: Replace the double-negation short-circuit expression with
an explicit spread/ternary so the plugin array contains either codspeedPlugin()
or nothing; specifically, change the entry "!!(process.env.VITEST &&
process.env.WITH_INSTRUMENTATION) && codspeedPlugin()" to use the pattern
"...(process.env.VITEST && process.env.WITH_INSTRUMENTATION ? [codspeedPlugin()]
: [])" so the intent is clearer and no falsy value can appear in the plugins
array.

In `@benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts`:
- Around line 12-13: Replace the conditional plugin expression that relies on
`!!(process.env.VITEST && process.env.WITH_INSTRUMENTATION) && codspeedPlugin()`
with an explicit spread of a conditional array so falsy values are not injected
implicitly: in
benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts (lines
12-13) use the pattern that spreads either [codspeedPlugin()] or [] based on
(process.env.VITEST && process.env.WITH_INSTRUMENTATION); do the same
replacement in
benchmarks/memory/client/scenarios/unique-location-churn/solid/vite.config.ts
(lines 14-15) and
benchmarks/memory/client/scenarios/preload-churn/vue/vite.config.ts (lines
15-16), keeping the plugin factory `codspeedPlugin()` and the environment checks
unchanged.

In `@benchmarks/memory/server/scenarios/aborted-requests/vue/project.json`:
- Line 15: The "command" property currently uses Unix-only syntax
("NODE_ENV=production vite build --config {projectRoot}/vite.config.ts");
replace this with a cross-platform invocation by prefixing with cross-env (e.g.,
"cross-env NODE_ENV=production vite build --config
{projectRoot}/vite.config.ts") or, if using Nx, move NODE_ENV into the
executor/target's environment configuration (use the target's "options" or "env"
support) so the build runs on Windows as well.
🪄 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: 13bdfa67-9a85-48f2-8aa0-778341660347

📥 Commits

Reviewing files that changed from the base of the PR and between 025d4b4 and ab7fb18.

📒 Files selected for processing (240)
  • .github/workflows/client-nav-benchmarks.yml
  • .gitignore
  • benchmarks/memory/README.md
  • benchmarks/memory/client/bench-utils.ts
  • benchmarks/memory/client/benchmark.ts
  • benchmarks/memory/client/flame-runner.ts
  • benchmarks/memory/client/jsdom.ts
  • benchmarks/memory/client/package.json
  • benchmarks/memory/client/runner.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/project.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/setup.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/tsconfig.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/project.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/setup.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/app.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routes/fast.$id.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routes/slow.$id.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/slow-loaders.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/project.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/setup.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/app.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/fast.$id.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/slow.$id.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/slow-loaders.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json
  • benchmarks/memory/client/scenarios/loader-data-retention/react/setup.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/loader-data.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/tsconfig.json
  • benchmarks/memory/client/scenarios/loader-data-retention/shared.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/project.json
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/setup.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/app.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/loader-data.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routes/page.$id.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routes/shell.index.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routes/shell.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/project.json
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/setup.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/app.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/loader-data.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/page.$id.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/shell.index.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/shell.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json
  • benchmarks/memory/client/scenarios/mount-unmount/react/setup.ts
  • benchmarks/memory/client/scenarios/mount-unmount/react/tsconfig.json
  • benchmarks/memory/client/scenarios/mount-unmount/shared.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/project.json
  • benchmarks/memory/client/scenarios/mount-unmount/solid/setup.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/app.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/mount-unmount/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/mount-unmount/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/mount-unmount/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json
  • benchmarks/memory/client/scenarios/mount-unmount/vue/setup.ts
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/app.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/mount-unmount/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/project.json
  • benchmarks/memory/client/scenarios/navigation-churn/react/setup.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/navigation-churn/shared.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/project.json
  • benchmarks/memory/client/scenarios/navigation-churn/solid/setup.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/app.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routes/b.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/navigation-churn/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/project.json
  • benchmarks/memory/client/scenarios/navigation-churn/vue/setup.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/app.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/routes/b.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/navigation-churn/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/project.json
  • benchmarks/memory/client/scenarios/preload-churn/react/setup.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/preload-churn/shared.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/project.json
  • benchmarks/memory/client/scenarios/preload-churn/solid/setup.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/app.tsx
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/item-payload.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/routes/items.$id.tsx
  • benchmarks/memory/client/scenarios/preload-churn/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/preload-churn/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/project.json
  • benchmarks/memory/client/scenarios/preload-churn/vue/setup.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/app.tsx
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/item-payload.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/routes/items.$id.tsx
  • benchmarks/memory/client/scenarios/preload-churn/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/preload-churn/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/project.json
  • benchmarks/memory/client/scenarios/unique-location-churn/react/setup.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/shared.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/project.json
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/setup.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/app.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/routes/items.$id.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/project.json
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/setup.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/app.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/routes/items.$id.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/vite.config.ts
  • benchmarks/memory/client/vitest.react.config.ts
  • benchmarks/memory/client/vitest.setup.ts
  • benchmarks/memory/client/vitest.solid.config.ts
  • benchmarks/memory/client/vitest.vue.config.ts
  • benchmarks/memory/flame-control.ts
  • benchmarks/memory/run-flame.mjs
  • benchmarks/memory/server/bench-utils.ts
  • benchmarks/memory/server/benchmark.ts
  • benchmarks/memory/server/flame-runner.ts
  • benchmarks/memory/server/package.json
  • benchmarks/memory/server/runner.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/memory.flame.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/project.json
  • benchmarks/memory/server/scenarios/aborted-requests/react/setup.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/tsconfig.json
  • benchmarks/memory/server/scenarios/aborted-requests/shared.ts
  • benchmarks/memory/server/scenarios/aborted-requests/solid/memory.bench.ts
  • benchmarks/memory/server/scenarios/aborted-requests/solid/memory.flame.ts
  • benchmarks/memory/server/scenarios/aborted-requests/solid/project.json
  • benchmarks/memory/server/scenarios/aborted-requests/solid/setup.ts
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/router.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/routes/stream.$id.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/solid/tsconfig.json
  • benchmarks/memory/server/scenarios/aborted-requests/solid/vite.config.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/memory.bench.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/memory.flame.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/project.json
  • benchmarks/memory/server/scenarios/aborted-requests/vue/setup.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/router.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/routes/__root.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/routes/stream.$id.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/vue/tsconfig.json
  • benchmarks/memory/server/scenarios/aborted-requests/vue/vite.config.ts
  • benchmarks/memory/server/scenarios/error-paths/react/memory.bench.ts
  • benchmarks/memory/server/scenarios/error-paths/react/memory.flame.ts
  • benchmarks/memory/server/scenarios/error-paths/react/project.json
  • benchmarks/memory/server/scenarios/error-paths/react/setup.ts
  • benchmarks/memory/server/scenarios/error-paths/react/tsconfig.json
✅ Files skipped from review due to trivial changes (83)
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routes/shell.index.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/shell.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/vue/setup.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/memory.flame.ts
  • benchmarks/memory/client/vitest.vue.config.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routes/page.$id.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/memory.bench.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/setup.ts
  • benchmarks/memory/server/runner.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/react/memory.flame.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/slow.$id.tsx
  • benchmarks/memory/client/benchmark.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/tsconfig.json
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/routes/index.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/index.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/preload-churn/solid/memory.flame.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/routes/a.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/router.tsx
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/shell.index.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/vite.config.ts
  • benchmarks/memory/server/benchmark.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/memory.flame.ts
  • benchmarks/memory/client/runner.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routes/a.tsx
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/memory.bench.ts
  • benchmarks/memory/client/scenarios/mount-unmount/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/navigation-churn/solid/vite.config.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/memory.flame.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/setup.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/vite.config.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/navigation-churn/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/router.tsx
  • benchmarks/memory/client/scenarios/mount-unmount/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/mount-unmount/solid/tsconfig.json
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/project.json
  • benchmarks/memory/client/scenarios/mount-unmount/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/tsconfig.json
  • benchmarks/memory/client/scenarios/preload-churn/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/routes/__root.tsx
  • benchmarks/memory/client/scenarios/loader-data-retention/react/setup.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/navigation-churn/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/routeTree.gen.ts
  • benchmarks/memory/server/scenarios/aborted-requests/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/preload-churn/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/preload-churn/react/project.json
  • benchmarks/memory/client/scenarios/preload-churn/react/tsconfig.json
  • benchmarks/memory/server/scenarios/aborted-requests/solid/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/unique-location-churn/react/tsconfig.json
  • benchmarks/memory/client/scenarios/unique-location-churn/vue/src/routeTree.gen.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/vue/src/routeTree.gen.ts
  • benchmarks/memory/README.md
  • benchmarks/memory/client/scenarios/loader-data-retention/solid/src/routeTree.gen.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • benchmarks/memory/client/vitest.react.config.ts
  • benchmarks/memory/client/bench-utils.ts
  • benchmarks/memory/client/scenarios/navigation-churn/react/setup.ts
  • benchmarks/memory/server/scenarios/error-paths/react/tsconfig.json
  • benchmarks/memory/client/scenarios/mount-unmount/react/tsconfig.json
  • benchmarks/memory/client/scenarios/navigation-churn/react/memory.bench.ts
  • benchmarks/memory/client/scenarios/interrupted-navigations/react/tsconfig.json
  • benchmarks/memory/server/bench-utils.ts
  • benchmarks/memory/client/scenarios/loader-data-retention/react/src/loader-data.ts
  • benchmarks/memory/server/scenarios/aborted-requests/react/project.json

Comment on lines +18 to +24
type MountedApp = {
router: unknown
unmount: () => void
}

type MountTestApp = (container: HTMLDivElement) => MountedApp
type ResolveAllSlowLoaders = () => void

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the root-cause pattern in the shared harness:
rg -n "type MountedApp|router: unknown|as InterruptedNavigationRouter" benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts

Repository: TanStack/router

Length of output: 172


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"

echo "== MountedApp and related types =="
sed -n '1,80p' "$FILE" | nl -ba | sed -n '1,80p'

echo
echo "== Around forced cast at line 224 =="
sed -n '200,250p' "$FILE" | nl -ba

echo
echo "== Find before()/interrupt() occurrences =="
rg -n "before\\(|interrupt\\(" "$FILE"

echo
echo "== Show around those occurrences =="
# Print a small window around each match
rg -n "before\\(|interrupt\\(" "$FILE" | cut -d: -f1 | sort -u | while read -r ln; do
  start=$((ln-15)); end=$((ln+30));
  echo "-- $ln --"
  sed -n "${start},${end}p" "$FILE" | nl -ba
done

echo
echo "== Find InterruptedNavigationRouter definition/import =="
rg -n "InterruptedNavigationRouter" "$FILE"

Repository: TanStack/router

Length of output: 155


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"

python3 - <<'PY'
import itertools

path = "benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"
with open(path, "r", encoding="utf-8") as f:
    lines = f.readlines()

def show(a,b):
    for i in range(a-1,b):
        if 0 <= i < len(lines):
            print(f"{i+1:4d}:{lines[i].rstrip()}")

print("== Lines 10-40 ==")
show(10,40)
print("\n== Lines 200-250 ==")
show(200,250)

print("\n== Occurrences: before( or interrupt( ==")
for idx, line in enumerate(lines, start=1):
    if "before(" in line or "interrupt(" in line:
        start = max(1, idx-10)
        end = min(len(lines), idx+20)
        print(f"\n-- match around line {idx} --")
        show(start,end)

print("\n== Lines mentioning InterruptedNavigationRouter ==")
for idx, line in enumerate(lines, start=1):
    if "InterruptedNavigationRouter" in line:
        print(f"{idx}: {line.rstrip()}")
PY

Repository: TanStack/router

Length of output: 6222


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"

python3 - <<'PY'
path = "benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"
with open(path, "r", encoding="utf-8") as f:
    lines = f.readlines()

def show(a,b):
    for i in range(a-1,b):
        if 0 <= i < len(lines):
            print(f"{i+1:4d}:{lines[i].rstrip()}")

print("== InterruptedNavigationRouter type (35-140) ==")
show(35,140)

print("\n== mountTestApp usages/definitions in this file ==")
for idx, line in enumerate(lines, start=1):
    if "mountTestApp" in line:
        print(f"{idx}: {line.rstrip()}")

PY

Repository: TanStack/router

Length of output: 3440


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"

python3 - <<'PY'
path = "benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts"
with open(path, "r", encoding="utf-8") as f:
    lines = f.readlines()

def show(a,b):
    for i in range(a-1,b):
        if 0 <= i < len(lines):
            print(f"{i+1:4d}:{lines[i].rstrip()}")

print("== Lines 140-210 (around mountTestApp) ==")
show(140,210)

print("\n== Lines mentioning mounted.router ==")
for i,l in enumerate(lines, start=1):
    if ".router" in l:
        if "mounted.router" in l or "router =" in l:
            print(f"{i}: {l.rstrip()}")

print("\n== Lines 210-260 (before() continues + navigateFast etc) ==")
show(210,260)

PY

rg -n "function \\w+\\(|const \\w+ = \\(container: HTMLDivElement\\)|mountTestApp" "$FILE"
rg -n "mounted\\.router|getLatestLoadPromise" "$FILE"

Repository: TanStack/router

Length of output: 5478


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "createSetup\\(|interrupted-navigations" benchmarks/memory/client/scenarios/interrupted-navigations -S

Repository: TanStack/router

Length of output: 1780


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  benchmarks/memory/client/scenarios/interrupted-navigations/react/setup.ts \
  benchmarks/memory/client/scenarios/interrupted-navigations/solid/setup.ts \
  benchmarks/memory/client/scenarios/interrupted-navigations/vue/setup.ts
do
  echo "===== $f ====="
  python3 - <<PY
import re
path="$f"
with open(path,'r',encoding='utf-8') as fh:
    lines=fh.readlines()
for i,l in enumerate(lines, start=1):
    if 'mountTestApp' in l or 'MountedApp' in l or 'router' in l and 'mounted' in l:
        pass
# print whole file if small, else print key ranges
print("file_lines:", len(lines))
if len(lines) <= 200:
    for i,l in enumerate(lines, start=1):
        print(f"{i:4d}:{l.rstrip()}")
else:
    # heuristic: show first 120 lines and any lines containing 'mountTestApp'
    for i in range(1,121):
        if i<=len(lines):
            print(f"{i:4d}:{lines[i-1].rstrip()}")
    for i,l in enumerate(lines, start=1):
        if 'mountTestApp' in l or 'router' in l:
            start=max(1,i-10); end=min(len(lines),i+20)
            print("\\n-- around line", i, "--")
            for j in range(start,end+1):
                print(f"{j:4d}:{lines[j-1].rstrip()}")
PY
done

Repository: TanStack/router

Length of output: 1966


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "mountTestApp|MountedApp" benchmarks/memory/client/scenarios/interrupted-navigations -S

Repository: TanStack/router

Length of output: 1453


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  benchmarks/memory/client/scenarios/interrupted-navigations/react/src/app.tsx \
  benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/app.tsx \
  benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/app.tsx
do
  echo "===== $f ====="
  python3 - <<PY
path="$f"
with open(path,'r',encoding='utf-8') as fh:
    lines=fh.readlines()
print("file_lines:", len(lines))
# print import area + mountTestApp + returned object
for i in range(1, min(160, len(lines))+1):
    if i<=40 or (10<=i<=130 and ("mountTestApp" in lines[i-1] or "return" in lines[i-1] or "router" in lines[i-1] or "unmount" in lines[i-1] )):
        pass
# show first 60 lines
for j in range(1, min(80, len(lines))+1):
    print(f"{j:4d}:{lines[j-1].rstrip()}")
print("\n-- around mountTestApp --")
for idx,l in enumerate(lines, start=1):
    if "mountTestApp" in l:
        start=max(1, idx-15); end=min(len(lines), idx+80)
        for k in range(start, end+1):
            print(f"{k:4d}:{lines[k-1].rstrip()}")
        break
PY
done

Repository: TanStack/router

Length of output: 7004


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  benchmarks/memory/client/scenarios/interrupted-navigations/react/src/router.ts \
  benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/router.ts \
  benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/router.ts
do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    python3 - <<PY
path="$f"
with open(path,'r',encoding='utf-8') as fh:
    lines=fh.readlines()
print("file_lines:", len(lines))
for i in range(1, min(220, len(lines))+1):
    if i<=120 or ( "export function getRouter" in lines[i-1] ) or ("function getRouter" in lines[i-1]) or ("return" in lines[i-1] and i<200) or ("latestLoadPromise" in lines[i-1]):
        print(f"{i:4d}:{lines[i-1].rstrip()}")
PY
  else
    echo "missing: $f"
  fi
done

Repository: TanStack/router

Length of output: 321


🏁 Script executed:

#!/bin/bash
set -euo pipefail

BASE="benchmarks/memory/client/scenarios/interrupted-navigations"
find "$BASE" -maxdepth 3 -type f \( -name "*router*" -o -name "*route*" \) | sort

echo
echo "== rg getRouter definitions =="

rg -n "export (async )?function getRouter|getRouter\\(" "$BASE" -S

Repository: TanStack/router

Length of output: 1244


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  benchmarks/memory/client/scenarios/interrupted-navigations/react/src/router.tsx \
  benchmarks/memory/client/scenarios/interrupted-navigations/solid/src/router.tsx \
  benchmarks/memory/client/scenarios/interrupted-navigations/vue/src/router.tsx
do
  echo "===== $f ====="
  python3 - <<PY
path="$f"
with open(path,'r',encoding='utf-8') as fh:
    lines=fh.readlines()
print("file_lines:", len(lines))
# print all (they're likely small); otherwise print key ranges
for i,l in enumerate(lines, start=1):
    if i<=200:
        print(f"{i:4d}:{l.rstrip()}")
PY
done

Repository: TanStack/router

Length of output: 1772


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "latestLoadPromise" -S .
rg -n "onRendered" benchmarks/memory/client/scenarios/interrupted-navigations -S
rg -n "subscribe\\('onRendered'" -S .
rg -n "navigate\\(\\{\\s*to:" benchmarks/memory/client/scenarios/interrupted-navigations -S

Repository: TanStack/router

Length of output: 5210


🏁 Script executed:

#!/bin/bash
set -euo pipefail

RG_BASE="packages/router-core/src/router.ts"

echo "== Subscribe type (onRendered) =="
rg -n "subscribe\\(" "$RG_BASE"
rg -n "onRendered" "$RG_BASE"

echo
echo "== load property/method =="
rg -n "load\\b" "$RG_BASE" | head -n 80

echo
echo "== navigate signature =="
rg -n "navigate\\(" "$RG_BASE" | head -n 80

Repository: TanStack/router

Length of output: 93


🏁 Script executed:

#!/bin/bash
set -euo pipefail

RG_DIR="packages/router-core/src"

echo "== locate subscribe in router-core src =="
rg -n "subscribe" "$RG_DIR" -S

echo
echo "== locate navigate in router-core src =="
rg -n "navigate\\(" "$RG_DIR" -S | head -n 50

echo
echo "== locate latestLoadPromise in router-core/src/router.ts =="
rg -n "latestLoadPromise" "packages/router-core/src/router.ts" -S

echo
echo "== show around latestLoadPromise block (router.ts:2380-2660) =="
python3 - <<'PY'
path="packages/router-core/src/router.ts"
start=2360
end=2670
with open(path,'r',encoding='utf-8') as f:
    lines=f.readlines()
for i in range(start, min(end, len(lines))):
    print(f"{i+1:5d}:{lines[i].rstrip()}")
PY

Repository: TanStack/router

Length of output: 15634


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/router-core/src/router.ts"

python3 - <<'PY'
path="packages/router-core/src/router.ts"
with open(path,'r',encoding='utf-8') as f:
    lines=f.readlines()

def show(a,b):
    for i in range(a-1,b):
        if 0 <= i < len(lines):
            print(f"{i+1:5d}:{lines[i].rstrip()}")

print("== Subscribe method/type block (~615, 616, 1260-1305) ==")
show(600,720)
print("\n== subscribe: SubscribeFn block ==")
show(1230,1315)

print("\n== navigate method block (best-effort search) ==")
# Find first occurrence of "navigate =" or "navigate(" near the method section
for idx,l in enumerate(lines, start=1):
    if "navigate:" in l and "=>" not in l:
        # likely part of type, ignore
        pass
# brute print around the first "navigate(" definition in the class
# find "navigate ="
start=None
for idx,l in enumerate(lines, start=1):
    if "navigate:" in l and "navigate:" in l:
        pass
for idx,l in enumerate(lines, start=1):
    if "navigate(" in l and "navigate(" in l:
        # could be calls; but we want method declaration "navigate: NavigateFn"
        pass

# simpler: search for "navigate: NavigateFn" and print around it
for idx,l in enumerate(lines, start=1):
    if "navigate" in l and "NavigateFn" in l:
        print(f"\nFOUND at {idx}: {l.strip()}")
        show(idx-40, idx+120)
        break
else:
    # fall back: show around "navigate =" occurrence
    for idx,l in enumerate(lines, start=1):
        if "navigate" in l and "navigate =" in l:
            print(f"\nFOUND at {idx}: {l.strip()}")
            show(idx-40, idx+140)
            break
    else:
        # last resort: locate "navigate(" near line 1600-1750
        show(1550,1850)
PY

Repository: TanStack/router

Length of output: 13048


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/router-core/src/router.ts"

rg -n "type LoadFn|export type LoadFn" "$FILE" -S

echo
echo "== show around LoadFn definition =="

python3 - <<'PY'
path="packages/router-core/src/router.ts"
with open(path,'r',encoding='utf-8') as f:
    lines=f.readlines()

# find first "LoadFn" definition line
for idx,l in enumerate(lines, start=1):
    if "LoadFn" in l and "=" not in l and ("export type" in l or "type" in l) and "LoadFn" in l:
        start=idx-40
        end=idx+120
        for i in range(start,end):
            if 0<=i<len(lines):
                print(f"{i+1:5d}:{lines[i].rstrip()}")
        break
else:
    # fallback: print around where "load: LoadFn" appears
    for idx,l in enumerate(lines, start=1):
        if "load: LoadFn" in l:
            start=idx-60; end=idx+80
            for i in range(start,end):
                if 0<=i<len(lines):
                    print(f"{i+1:5d}:{lines[i].rstrip()}")
            break
PY

Repository: TanStack/router

Length of output: 6390


Tighten MountedApp.router to remove the unchecked cast
File: benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts (Lines: 18-24)

type MountedApp = {
  router: unknown
  unmount: () => void
}

type MountTestApp = (container: HTMLDivElement) => MountedApp
type ResolveAllSlowLoaders = () => void

MountedApp.router is unknown and then force-cast at line 224 to InterruptedNavigationRouter, which removes strict compile-time checks for the router contract used by before()/interrupt().

Suggested refactor
 type MountedApp = {
-  router: unknown
+  router: InterruptedNavigationRouter
   unmount: () => void
 }
-    const router = mounted.router as InterruptedNavigationRouter
+    const router = mounted.router

Also applies to: 224-224

🤖 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 `@benchmarks/memory/client/scenarios/interrupted-navigations/shared.ts` around
lines 18 - 24, MountedApp currently types router as unknown which forces an
unchecked cast later; change the type to the concrete router interface used by
before()/interrupt() (e.g., replace "router: unknown" with "router:
InterruptedNavigationRouter") so the compiler enforces the router contract,
ensure InterruptedNavigationRouter is imported or declared in this module, and
keep MountTestApp and ResolveAllSlowLoaders signatures as they are; after this
change you can remove the force-cast at the usage site (around line 224) because
the returned MountedApp.router will already be correctly typed.

Source: Coding guidelines

Comment on lines +8 to +14
type MountedApp = {
router: unknown
unmount: () => void
}

type MountTestApp = (container: HTMLDivElement) => MountedApp

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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify where the unsafe cast/unknown contract exists and inspect setup providers.
rg -nP 'router:\s+unknown|as\s+LoaderDataRouter|createSetup\(' -C2 benchmarks/memory/client/scenarios/loader-data-retention
fd -i 'setup.ts' benchmarks/memory/client/scenarios/loader-data-retention --exec sed -n '1,220p' {}

Repository: TanStack/router

Length of output: 3586


Replace MountedApp.router: unknown with LoaderDataRouter and remove the mounted.router as LoaderDataRouter cast.

benchmarks/memory/client/scenarios/loader-data-retention/shared.ts declares MountedApp.router as unknown and then force-casts mounted.router at lines 134-136, so drift between each framework’s mountTestApp return type and the LoaderDataRouter contract won’t be caught at compile time.

Proposed fix
 type MountedApp = {
-  router: unknown
+  router: LoaderDataRouter
   unmount: () => void
 }
@@
-    const router = mounted.router as LoaderDataRouter
+    const router = mounted.router

As per coding guidelines, **/*.{ts,tsx}: 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 `@benchmarks/memory/client/scenarios/loader-data-retention/shared.ts` around
lines 8 - 14, Change the MountedApp type so router is strongly typed as
LoaderDataRouter instead of unknown, update MountTestApp accordingly, and remove
the force-cast of mounted.router (i.e., stop using mounted.router as
LoaderDataRouter) so the returned mount implementations must match the
LoaderDataRouter contract at compile time; also add the necessary import for the
LoaderDataRouter type where MountedApp is declared.

Source: Coding guidelines

Comment on lines +118 to +124
function waitForNextRender(pathname: string) {
expectedRenderedPath = pathname

return new Promise<void>((resolve) => {
resolveRendered = resolve
})
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a timeout to render waiting to prevent benchmark hangs.

navigateTo can wait forever if the expected onRendered event never arrives, which can stall CI runs instead of failing fast.

Proposed fix
-function waitForNextRender(pathname: string) {
+function waitForNextRender(pathname: string, timeoutMs = 5_000) {
   expectedRenderedPath = pathname
 
-  return new Promise<void>((resolve) => {
-    resolveRendered = resolve
+  return new Promise<void>((resolve, reject) => {
+    const timer = setTimeout(() => {
+      resolveRendered = () => {}
+      expectedRenderedPath = undefined
+      reject(new Error(`Timed out waiting for render: ${pathname}`))
+    }, timeoutMs)
+
+    resolveRendered = () => {
+      clearTimeout(timer)
+      resolve()
+    }
   })
 }

Also applies to: 152-162

🤖 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 `@benchmarks/memory/client/scenarios/loader-data-retention/shared.ts` around
lines 118 - 124, The waitForNextRender function can hang indefinitely; update it
to include a configurable timeout (e.g., 10–30s) so the returned Promise rejects
when the timeout elapses, and ensure the timeout is cleared when resolveRendered
is called; specifically, in waitForNextRender assign a timer via setTimeout that
rejects the promise with a clear error message, store/clear that timer inside
the resolveRendered handler, and propagate the rejection to callers (e.g.,
navigateTo) so the benchmark fails fast instead of hanging.

}
],
"options": {
"command": "NODE_ENV=production vite build --config {projectRoot}/vite.config.ts"

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Cross-platform environment variable issue in command strings.

Inline NODE_ENV=production assignments fail on Windows (requires Unix shell syntax). Use cross-env or rely on Vite's default production mode.

  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json#L15-L15: Replace NODE_ENV=production vite build with cross-env NODE_ENV=production vite build in the build:client target's command.
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json#L28-L28: Replace NODE_ENV=production vite build with cross-env NODE_ENV=production vite build in the build:client:flame target's command.
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json#L37-L37: Replace NODE_ENV=production node with cross-env NODE_ENV=production node in the test:flame target's command.
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json#L15-L15: Replace NODE_ENV=production vite build with cross-env NODE_ENV=production vite build in the build:client target's command.
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json#L28-L28: Replace NODE_ENV=production vite build with cross-env NODE_ENV=production vite build in the build:client:flame target's command.
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json#L37-L37: Replace NODE_ENV=production node with cross-env NODE_ENV=production node in the test:flame target's command.
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json#L15-L15: Replace NODE_ENV=production vite build with cross-env NODE_ENV=production vite build in the build:client target's command.
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json#L28-L28: Replace NODE_ENV=production vite build with cross-env NODE_ENV=production vite build in the build:client:flame target's command.
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json#L37-L37: Replace NODE_ENV=production node with cross-env NODE_ENV=production node in the test:flame target's command.
📍 Affects 3 files
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json#L15-L15 (this comment)
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json#L28-L28
  • benchmarks/memory/client/scenarios/mount-unmount/react/project.json#L37-L37
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json#L15-L15
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json#L28-L28
  • benchmarks/memory/client/scenarios/mount-unmount/vue/project.json#L37-L37
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json#L15-L15
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json#L28-L28
  • benchmarks/memory/client/scenarios/loader-data-retention/react/project.json#L37-L37
🤖 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 `@benchmarks/memory/client/scenarios/mount-unmount/react/project.json` at line
15, Replace the platform-dependent inline env assignments with cross-env in the
listed project.json targets: in
benchmarks/memory/client/scenarios/mount-unmount/react/project.json (15-15)
update the build:client command to use cross-env NODE_ENV=production vite build;
in the same file (28-28) update build:client:flame to use cross-env
NODE_ENV=production vite build; in the same file (37-37) update test:flame to
use cross-env NODE_ENV=production node; in
benchmarks/memory/client/scenarios/mount-unmount/vue/project.json (15-15) update
build:client to cross-env NODE_ENV=production vite build; (28-28) update
build:client:flame to cross-env NODE_ENV=production vite build; (37-37) update
test:flame to cross-env NODE_ENV=production node; in
benchmarks/memory/client/scenarios/loader-data-retention/react/project.json
(15-15) update build:client to cross-env NODE_ENV=production vite build; (28-28)
update build:client:flame to cross-env NODE_ENV=production vite build; (37-37)
update test:flame to cross-env NODE_ENV=production node so the commands work
cross-platform.

Comment on lines +3 to +13
type MountedApp = {
router: unknown
unmount: () => void
}

type MountTestApp = (container: HTMLDivElement) => MountedApp

type RenderRouter = {
load: () => Promise<void>
subscribe: (event: 'onRendered', listener: () => void) => () => void
}

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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Tighten router typing instead of casting from unknown.

Line 54 force-casts mounted.router to RenderRouter, which bypasses strict checks and can hide contract mismatches until runtime. Type MountedApp.router as RenderRouter directly and remove the assertion.

♻️ Suggested change
 type MountedApp = {
-  router: unknown
+  router: RenderRouter
   unmount: () => void
 }
@@
-      const router = mounted.router as RenderRouter
+      const router = mounted.router

As per coding guidelines, **/*.{ts,tsx}: Use TypeScript strict mode with extensive type safety.

Also applies to: 54-55

🤖 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 `@benchmarks/memory/client/scenarios/mount-unmount/shared.ts` around lines 3 -
13, The MountedApp type currently declares router as unknown which forces a
runtime assertion elsewhere; change MountedApp.router from unknown to
RenderRouter (type MountedApp = { router: RenderRouter; unmount: () => void })
and remove the explicit cast of mounted.router to RenderRouter where used so the
compiler enforces the contract; ensure MountTestApp still returns MountedApp and
update any affected usages to satisfy the stricter type if needed.

Source: Coding guidelines

Comment on lines +13 to +16
type MountedApp = {
router: unknown
unmount: () => void
}

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify there are no remaining weak router contracts/casts in this scenario.
rg -n --type=ts --type=tsx -C2 'router:\s*unknown|as\s+NavigationRouter' benchmarks/memory/client/scenarios/unique-location-churn

Repository: TanStack/router

Length of output: 87


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/unique-location-churn/shared.ts"

echo "== Matching router: unknown in target file =="
rg -n 'router:\s*unknown' "$FILE" || true

echo "== Matching 'as NavigationRouter' in target file =="
rg -n 'as\s+NavigationRouter' "$FILE" || true

echo "== Show relevant sections (lines 1-180) =="
nl -ba "$FILE" | sed -n '1,180p'

Repository: TanStack/router

Length of output: 341


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/unique-location-churn/shared.ts"

echo "== Matching router: unknown in target file =="
rg -n 'router:\s*unknown' "$FILE" || true

echo "== Matching 'as NavigationRouter' in target file =="
rg -n 'as\s+NavigationRouter' "$FILE" || true

echo "== Show relevant sections (lines 1-180) =="
nl -ba "$FILE" | sed -n '1,180p'

Repository: TanStack/router

Length of output: 341


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="benchmarks/memory/client/scenarios/unique-location-churn/shared.ts"

echo "== Matches =="
rg -n 'router:\s*unknown|as\s+NavigationRouter' "$FILE" || true

echo
echo "== Lines 1-60 =="
cat -n "$FILE" | sed -n '1,60p'

echo
echo "== Lines 90-130 =="
cat -n "$FILE" | sed -n '90,130p'

echo
echo "== Any other NavigationRouter casts in repo path =="
rg -n --type=ts --type=tsx 'as\s+NavigationRouter' benchmarks/memory/client/scenarios/unique-location-churn || true

Repository: TanStack/router

Length of output: 3440


Strengthen MountedApp.router typing to eliminate unknown + cast.

In benchmarks/memory/client/scenarios/unique-location-churn/shared.ts, MountedApp.router is unknown and is cast to NavigationRouter at lines ~103; typing the field as NavigationRouter directly removes the runtime-unsafe assertion.

♻️ Proposed change
 type MountedApp = {
-  router: unknown
+  router: NavigationRouter
   unmount: () => void
 }
@@
-    const router = mounted.router as NavigationRouter
+    const router = mounted.router
🤖 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 `@benchmarks/memory/client/scenarios/unique-location-churn/shared.ts` around
lines 13 - 16, MountedApp.router is typed as unknown which forces a runtime cast
to NavigationRouter; change the MountedApp type so router: NavigationRouter (and
add the necessary import for NavigationRouter), then remove the cast at the site
that currently casts to NavigationRouter (around the code that references router
at ~line 103) so callers use the typed property directly.

Source: Coding guidelines

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.

1 participant