Repository navigation
Parse what the browser receives (TS20) - #30
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Finesssee
force-pushed
the
ts/ts20-browser-parsers
branch
from
October 11, 2026 20:13
fc439a5 to
a122193
Compare
…ers where they arrive
…us as the pages always did, and document the edge tests/browser-parse.test.ts covers each parser with a fitting value, a wrong type, a missing field and kept extra fields, plus parseAnswer, the stored draft, dropped list entries and warnOnce. A profile without dollars, an admin answer without overlays and a null botStatus read again, as the pages read them loosely before. docs/CONTRACTS.md §3 and §8 and docs/DEVELOPMENT.md describe the parsers and the new strict test.
…er's shape doesn't freeze it
Finesssee
force-pushed
the
ts/ts20-browser-parsers
branch
from
October 11, 2026 20:30
e2cb237 to
9539c78
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TS20: browser code now parses untrusted input once, where it arrives, into typed values. Parsers follow
server/parse.ts({ ok, value } | { ok: false, error }), and the change adds no dependencies.What changes for viewers and streamers
Nothing changes for valid data. When the server or a stored value sends something malformed:
console.warn("PixFray dropped ...") per page load.Parsers and what each does on a failure
Served (
src/served/parse.ts, served as/parse.js):parseArenaSnapshot,parseArenaPlayer,parseArenaDuel,parseArenaEvent,parseLook(the /api/live socket in arena-client): a frame that isn't JSON, or has a bad top-level field, is dropped whole. Bad entries are dropped throughkeepGood.parseLooksMessage(the looks push): dropped whole if it's bad.parseCosmeticSettings(saved chat looks in localStorage): bad entries are dropped. Unreadable JSON reads as empty.parseDemoMessage(postMessage from /start to the demo overlay): ignored if it's bad.parseIRCLinein chat.ts: a line that doesn't parse is skipped.warnOnceandkeepGoodare the shared helpers.Pages (
src/parse.ts, bundled by Vite):parseAnswer(r, parse, kind)wrapsapi(). A non-ok answer keeps its error body. An ok answer that fails its parser becomes{ ok: false, data: { error: UNREADABLE } }, after one warn.parseSession,parseAccess: used on every page that reads them.parseProfile,parseProfileOrNone,parseProfileSaved,parseBought,parseShop(also the /api/pets fallback),parseStateConfig,parseLeaderboard.parseDraft(the sessionStorage draft): bad JSON, or a badd, reads as no draft, with one warn.parseAdmin(/api/admin) andparseAdminSnapshot(its live socket). A bad snapshot is dropped, and the page keeps its last state.parseRuns,parseVersions,parseSettings,parseChannels(GET and POST),parseProgress,parseLogs. Bad rows are dropped.Other notes:
event.idonly. The legacyeventIdfallback is gone, because the server sendsidon every event.{ demoPaused }, whichparseDemoMessagechecks on the receiving side.Left unparsed, and why
These are rarely used or small, and are read where they're used:
/api/stateread.intro/back.tslocalStorage, the off-told and reload flags, andKNOWN_KEY.Typing fixes and strictness corrections
Shop prices can be null, and a pending duel has no
startedAt. These were typed wrong before. Runtime behavior is unchanged.During testing, ui.mjs caught three fields where my parser was stricter than the data. These were strictness fixes in the parser, not production bugs:
dollarsis absent on a fighter who never earned any.overlaysmay be missing.botStatusmay be null.All three are now optional, with tests.
No production bugs needed a fix.
Docs
docs/CONTRACTS.md§3 now says that clients parse every frame and describes the drop behavior.docs/DEVELOPMENT.mdhas the strict-web note and adds the new test to the strict-tests list.Checks
bun run checkon the head rebased onto b46170f: 371/371 tests pass.bun run test:allon the rebased head a122193: every step passed. I diffed the TS19 producers (auth, channels, developer) and found no change to any answer shape these parsers read.bun run test:allbefore the rebase: every step passed (check, port-check, cf build normal and test, module versions, workerd upload, smoke, ui, dev-ui, arena browser, e2e local). During that run I temporarily logged every "PixFray dropped" warning in the browser tests against the real dev Worker. There were 0 drops, and that logging is not in the commits.node scripts/port-check.ts --strict-list: the strict lists cover every TypeScript file.tests/browser-parse.test.tsis ontsconfig.strict-tests.json.bunx cf build: OK.node tests/build-versions.mjs: "PASS: 11 served module references carry ...".node tests/ui.mjs(headed): "PASS: viewer + admin UI at 1280/390, signed-out (real server), signed-in viewer save, mod gate, admin actions, config save/409/revert; no page errors."node tests/arena-browser.mjs(headed): "PASS: authoritative profiles, health snapshots, event deduplication, stale revisions, reconnect, transparent drawing, local-only demo duel, hit effects, fighter-only shake, no stage filter, fx=off and bubbles=0."tests/browser-parse.test.ts(10 tests), plus a malformed-frame case intests/arena-client.test.ts.