Measured first: the "25k lines" was devtools pretty-printing compact JSON; the real cost was ~597 KB per frame, pushed once per second (~583 KB/s per subscriber). 99.8% of it was packages: all 1,521 rows ever created — terminal packages (expired/delivered/ignored/abandoned) are never deleted from the DB while only ~12 were open at a time.
Fix: new pure sseFrame(snapshot) in lib/game/state.ts projects each frame to the package statuses any component actually renders (open, loaded, expired). Used by both SSE paths — the engine broadcast and the initial connect frame, so connecting never costs one full-history frame. Live payload: ~597 KB → ~10 KB per frame (≈60× cut), bounded forever by fleet/market size instead of growing with play time.
Deliberately unchanged:/api/state and action responses keep the FULL package set, so every e2e oracle asserting delivered/abandoned transitions via state lookups still works; the polling fallback stays a strict superset of what SSE pushes. No hash-skip (the snapshot's clock advances every tick — frames are never equal), no throttling (already 1 Hz), no diff/patch engine.
Tests: +3 unit tests in lib/game/state.test.ts; e2e/events.spec.ts now asserts no terminal status ever appears in a frame and frames stay < 200 KB.
Fixed in **v0.59.0** (PR #134, merge `1d9e9ade`), deployed to https://flight.dev.kkhost.pl — verified `/api/version` = 0.59.0.
**Measured first:** the "25k lines" was devtools pretty-printing compact JSON; the real cost was **~597 KB per frame, pushed once per second** (~583 KB/s per subscriber). 99.8% of it was `packages`: all **1,521 rows ever created** — terminal packages (expired/delivered/ignored/abandoned) are never deleted from the DB while only ~12 were open at a time.
**Fix:** new pure `sseFrame(snapshot)` in `lib/game/state.ts` projects each frame to the package statuses any component actually renders (`open`, `loaded`, `expired`). Used by both SSE paths — the engine broadcast and the initial connect frame, so connecting never costs one full-history frame. Live payload: **~597 KB → ~10 KB per frame (≈60× cut)**, bounded forever by fleet/market size instead of growing with play time.
**Deliberately unchanged:** `/api/state` and action responses keep the FULL package set, so every e2e oracle asserting `delivered`/`abandoned` transitions via state lookups still works; the polling fallback stays a strict superset of what SSE pushes. No hash-skip (the snapshot's clock advances every tick — frames are never equal), no throttling (already 1 Hz), no diff/patch engine.
**Tests:** +3 unit tests in `lib/game/state.test.ts`; `e2e/events.spec.ts` now asserts no terminal status ever appears in a frame and frames stay < 200 KB.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixed in v0.59.0 (PR #134, merge
1d9e9ade), deployed to https://flight.dev.kkhost.pl — verified/api/version= 0.59.0.Measured first: the "25k lines" was devtools pretty-printing compact JSON; the real cost was ~597 KB per frame, pushed once per second (~583 KB/s per subscriber). 99.8% of it was
packages: all 1,521 rows ever created — terminal packages (expired/delivered/ignored/abandoned) are never deleted from the DB while only ~12 were open at a time.Fix: new pure
sseFrame(snapshot)inlib/game/state.tsprojects each frame to the package statuses any component actually renders (open,loaded,expired). Used by both SSE paths — the engine broadcast and the initial connect frame, so connecting never costs one full-history frame. Live payload: ~597 KB → ~10 KB per frame (≈60× cut), bounded forever by fleet/market size instead of growing with play time.Deliberately unchanged:
/api/stateand action responses keep the FULL package set, so every e2e oracle assertingdelivered/abandonedtransitions via state lookups still works; the polling fallback stays a strict superset of what SSE pushes. No hash-skip (the snapshot's clock advances every tick — frames are never equal), no throttling (already 1 Hz), no diff/patch engine.Tests: +3 unit tests in
lib/game/state.test.ts;e2e/events.spec.tsnow asserts no terminal status ever appears in a frame and frames stay < 200 KB.