Public: anyone can read this; the crew can change it.
Each first-opened page's warm median reads beside its budget as plain rows, in one pure function with its test #11579
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/11577-each-first-opened-page-s-warm-median-rea → main 1 commit fork
3 files
changed +72
−0
scripts/unreached-allow.json +1
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | [ |
| 2 | 2 | "src/perf/page_budget.ts", |
| 3 | "src/perf/page_budget_read.ts", | |
| 3 | 4 | "src/spawn/pod.ts", |
| 4 | 5 | "src/tui/ui/qr.ts", |
| 5 | 6 | "src/web/studio/held_posts.ts" |
src/perf/page_budget_read.ts added +36
| @@ -0,0 +1,36 @@ | ||
| 1 | /** | |
| 2 | * Each first-opened page's warm median beside its budget (#11577), as plain | |
| 3 | * rows. Pure: route stats in, rows out, in `PAGE_BUDGETS` order. A page with | |
| 4 | * no samples reads `medianMs: null`, never 0, so "not measured" is not "fast". | |
| 5 | */ | |
| 6 | import { PAGE_BUDGETS } from "./page_budget.ts"; | |
| 7 | import type { RouteStat } from "./record.ts"; | |
| 8 | ||
| 9 | export interface PageBudgetRow { | |
| 10 | readonly page: string; | |
| 11 | readonly pattern: string; | |
| 12 | readonly budgetMs: number; | |
| 13 | readonly statements: number; | |
| 14 | /** The warm median (p50) in ms, or null when the page has no samples. */ | |
| 15 | readonly medianMs: number | null; | |
| 16 | readonly n: number; | |
| 17 | /** True only when the median is strictly past the budget. */ | |
| 18 | readonly over: boolean; | |
| 19 | } | |
| 20 | ||
| 21 | /** One row per budgeted page, in budget order; `stats` is keyed by router pattern. */ | |
| 22 | export function pageBudgetRows(stats: Readonly<Record<string, RouteStat | null | undefined>>): PageBudgetRow[] { | |
| 23 | return PAGE_BUDGETS.map((b) => { | |
| 24 | const s = Object.hasOwn(stats, b.pattern) ? stats[b.pattern] : undefined; | |
| 25 | const sampled = s != null && s.n > 0; | |
| 26 | return { | |
| 27 | page: b.page, | |
| 28 | pattern: b.pattern, | |
| 29 | budgetMs: b.medianMs, | |
| 30 | statements: b.statements, | |
| 31 | medianMs: sampled ? s.p50 : null, | |
| 32 | n: sampled ? s.n : 0, | |
| 33 | over: sampled && s.p50 > b.medianMs, | |
| 34 | }; | |
| 35 | }); | |
| 36 | } |
test/page-budget-read.test.ts added +35
| @@ -0,0 +1,35 @@ | ||
| 1 | import { expect, test } from "bun:test"; | |
| 2 | import { PAGE_BUDGETS } from "../src/perf/page_budget.ts"; | |
| 3 | import { pageBudgetRows } from "../src/perf/page_budget_read.ts"; | |
| 4 | import type { RouteStat } from "../src/perf/record.ts"; | |
| 5 | ||
| 6 | const stat = (p50: number, n = 20): RouteStat => ({ n, p50, p95: p50, p99: p50, phases: [] }); | |
| 7 | ||
| 8 | test("rows follow PAGE_BUDGETS one for one", () => { | |
| 9 | const rows = pageBudgetRows({}); | |
| 10 | expect(rows.map((r) => r.pattern)).toEqual(PAGE_BUDGETS.map((b) => b.pattern)); | |
| 11 | expect(rows.map((r) => [r.page, r.budgetMs, r.statements])).toEqual( | |
| 12 | PAGE_BUDGETS.map((b) => [b.page, b.medianMs, b.statements]), | |
| 13 | ); | |
| 14 | }); | |
| 15 | ||
| 16 | test("a page with no samples reads null, 0 samples, not over", () => { | |
| 17 | for (const r of pageBudgetRows({ "/explore": null })) expect(r).toMatchObject({ medianMs: null, n: 0, over: false }); | |
| 18 | }); | |
| 19 | ||
| 20 | test("a page with an empty-count stat is unsampled, not 0 ms", () => { | |
| 21 | const r = pageBudgetRows({ "/map": stat(0, 0) }).find((x) => x.pattern === "/map")!; | |
| 22 | expect(r.medianMs).toBeNull(); | |
| 23 | }); | |
| 24 | ||
| 25 | test("over only when the median is strictly past the budget", () => { | |
| 26 | const b = PAGE_BUDGETS[0]!.medianMs; | |
| 27 | const at = (ms: number) => pageBudgetRows({ [PAGE_BUDGETS[0]!.pattern]: stat(ms, 7) })[0]!; | |
| 28 | expect(at(b - 1)).toMatchObject({ medianMs: b - 1, n: 7, over: false }); | |
| 29 | expect(at(b).over).toBe(false); | |
| 30 | expect(at(b + 0.1).over).toBe(true); | |
| 31 | }); | |
| 32 | ||
| 33 | test("stats for other patterns are ignored", () => { | |
| 34 | expect(pageBudgetRows({ "/nope": stat(999) }).some((r) => r.over)).toBe(false); | |
| 35 | }); |