Skip to content

perf(router): add a __proto__ param with a computed key, not defineProperty - #194

Merged
dinwwwh merged 1 commit into
mainfrom
claude/project-thread-m32ra9
Oct 29, 2026
Merged

dinwwwh merged 1 commit into
mainfrom
claude/project-thread-m32ra9

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 29, 2026

Copy link
Copy Markdown
Member

Requested by dinwwwh · project thread

Summary

toParams added a param named __proto__ with Object.defineProperty, since assigning it would set the prototype instead. A computed key in an object literal defines an own property too, so params = { ...params, [name]: value } does the same in much less code. The result is the same: a plain object with Object.prototype, and __proto__ as an own, writable, enumerable, configurable key in its place among the params. A later param of the same name still overwrites it in place.

The spread runs only for a param named __proto__, so oxlint's no-accumulating-spread (which guards against spreading on every pass of a loop) is turned off around toParams with a comment saying why. A next-line directive does not cover it, because the rule reports from the let to the spread.

Measurements

  • Size (esbuild --minify, gzip -9): 5128 B to 5068 B minified, 2151 B to 2112 B gzip (-39 B).
  • Cold start (callgrind, --single-threaded, fixed hash seeds): router import -6k instructions, REST add -9k, REST cold + 10 requests -16k. RPC unchanged.
  • Steady state: unchanged (the branch is only taken for __proto__).

Checks

  • pnpm run check green; router tests 73/73 with 100% statement, branch, function and line coverage.
  • All fuzzers (fuzz, fuzz-big, fuzz-brace, fuzz-prefix, fuzz-inter*, fuzz-late k3/k7) at 3 seeds: 0 diffs.
  • Stryker: 61 survivors (62 before). The one survivor in this code is if (true) for the __proto__ check, which only makes every param take the slower spread.

Generated by Claude Code

…Property

A computed key in an object literal defines an own property, so spreading
the params into a new object with the `__proto__` key keeps it off the
prototype, as `Object.defineProperty` did, in less code. It runs only for
a param named `__proto__`, so the spread is not repeated per param.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VVaw7Sutbw6xMTMyDFeNfw
@dinwwwh dinwwwh self-assigned this Oct 29, 2026
@codecov

codecov Bot commented Oct 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Oct 29, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

1 warning

⚠️ 1 benchmark is dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

✅ 29 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing claude/project-thread-m32ra9 (2547932) with main (8bd0e36)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

  • toParams __proto__ branch — the Object.defineProperty(params, name, {…}) call is replaced by a computed-key spread, params = { ...params, [name]: value }. An object-literal computed key defines an own data property, so this is behavior-equivalent to the old path: an own, enumerable, writable, configurable __proto__ key on a plain Object.prototype-backed object, same insertion position, and a later same-named param still overwrites in place. Only the __proto__ branch spreads, so steady-state cost is unaffected. params moves from const to let accordingly.
  • Lint suppression — oxc/no-accumulating-spread is enabled (deny) and is genuinely tripped by the in-loop spread. The function-level oxlint-disable / oxlint-enable pair is required rather than a next-line directive: the rule anchors its diagnostic to the let params declaration, not the spread element, so a next-line on the spread line leaves it reported. The comment explains this accurately.

Verified locally: oxlint --print-config confirms the rule is deny; the router suite passes 73/73; uncheck packages/router/src/index.ts is green (oxlint, oxfmt, tsc). Existing tests already pin the exact semantics — router.test.ts's "keeps a param named proto as an own key of a plain object" (prototype, Object.keys, full descriptor) and encoding.test.ts's "names that objects inherit".

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit b2a5f7d into main Oct 29, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants