Skip to content

fix(pit): stop /pit rendering the entire namespace at once - #167

Merged
ralyodio merged 1 commit into
mainfrom
fix/pit-page-weight
Aug 1, 2026
Merged

fix(pit): stop /pit rendering the entire namespace at once#167
ralyodio merged 1 commit into
mainfrom
fix/pit-page-weight

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

/pit lags and locks up the browser. There is no JavaScript on the page to blame — the only script it ships is the service-worker registration. It's the DOM.

What was happening

The page rendered every ending the account holds, and under each one a <form> per name (CSRF field, two inputs, two buttons), with no limit at either end. This registry already holds 200 endings under a single account.

Measured against a seeded 50 endings × 100 names:

before after
HTML 3,106 KiB 173 KiB
DOM elements 36,082 1,926
<form> 5,153 263
server render 237 ms 86 ms

Nothing has to be slow for that to jam — and the sticky backdrop-filter: blur(10px) app bar repaints over the whole thing on every scroll frame, which is the part that feels like a lockup.

What changed

  • 20 endings a page, 10 names each, with the totals stated (10 of 100 shown, page 1 of 3 · 50 endings) so a window is never mistaken for the whole list. Silent truncation reads as data loss.
  • ?tld= opens one ending in full — where the "show all N" links go, and where TronBrowser's mosh.<tld> console link already pointed, at a page that ignored the parameter and drew everything anyway. Guarded so it can't focus an ending another account holds.
  • Only the endings on screen are queried. This used to run one listNames per ending held, whatever it was about to render.
  • Stable paging order. ORDER BY created_at DESC, tld instead of created_at alone: a bulk claim writes one timestamp across every ending in it, so the old sort wasn't a total order and a page boundary inside a tie would repeat one ending and drop another.

Testing

  • New apps/pwa/test/moshpit-pit-page.test.mjs — 6 tests: page stays bounded at 5,000 names, totals are stated, paging covers every ending exactly once with every timestamp deliberately tied, ?tld= focus works and can't be used to read someone else's ending, and an unreadable ?page= lands on page 1.
  • apps/pwa: 307 pass, 0 fail. Repo root: 714 pass, 0 fail, 2 skipped.

🤖 Generated with Claude Code

The page locks browsers up and there is no script on it to blame. It drew
every ending the account holds, and under each one a form per name — CSRF
field, two inputs, two buttons — with no limit on either end. This registry
already holds 200 endings under one account. Measured at 50 endings x 100
names: 3.1 MiB of HTML and 36,082 elements. Nothing has to be slow for that
to jam; it is the DOM, and the sticky blurred app bar repaints over all of it
on every scroll frame.

Same data now renders 173 KiB and 1,926 elements — 20 endings a page, 10
names each, with the totals stated so a window is never mistaken for the
whole. `?tld=` opens one ending in full, which is where the "show all N"
links go, and where TronBrowser's mosh.<tld> console link already pointed at
a page that ignored the parameter and drew everything anyway.

Paging orders by `created_at DESC, tld` rather than `created_at` alone. A
bulk claim writes one timestamp across every ending in it, so the old sort
was not a total order: a page boundary inside a tie would repeat one ending
and lose another. Covered by a test that ties every timestamp on purpose.

Only the endings on screen are queried now — this used to run one listNames
per ending held, regardless of what it was about to render.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio marked this pull request as ready for review August 1, 2026 02:32
@ralyodio
ralyodio merged commit 3d14a60 into main Aug 1, 2026
3 checks passed
@ralyodio ralyodio mentioned this pull request Aug 1, 2026
ralyodio added a commit that referenced this pull request Aug 1, 2026
install.sh resolves releases/latest, so the sixteen commits merged since
v0.13.3 have been sitting on main unreachable — including a fix for a page
that locks browsers up.

The headline is the pit. /pit rendered every ending an account held and a form
per name under each, with no bound on either: at 50 endings x 100 names that
was 3.1 MiB of HTML and 36,082 DOM elements, and it managed to jam a browser
with no script on the page at all (#167). It now draws a window and says what
it is not drawing — 173 KiB, 1,926 elements — with a filter box over the top
that takes `eggs` as a substring and `def*` as a glob, debounced against the
API (#168).

The namespace also stopped being the one part of the product a script could
not touch: /api/moshpit/* now accepts the same API key /api/me and
/api/sessions already did (#169), and /pit/dns finally documents the
TronBrowser route for machines whose DNS is not theirs to change (#165).

  moshcode: foreign keys are enforced, and the licence package.json
  claims actually ships (#154)
  cli: help aliases exit 0 (#157), invalid integration commands fail (#160),
  `--` is honoured (#159), a BOM before a shebang no longer breaks (#158)
  skills: engines with no skills primitive are reported, not dropped (#166);
  `--name` requires a value (#156)
  mcp: an unsupported flag is rejected rather than registered as the server
  name (#164)
  pit: the namespace rules are vendored again with a drift test holding them
  to the published package (#161, #162, #163)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant