bradene0bradenevans.dev
privateThe code behind this site, with my notes.
Files
// Reads the traceparent header your browser sends when you trace a request. // It checks the version, trace id, parent id and flags against the W3C // spec, and anything malformed comes back null. If it's valid, the Worker's // spans join your trace. export function parseTraceparent(header: string | null): TraceParent | null { if (!header) return null; const value = header.trim(); const [version, traceId, parentId, flags] = value.split("-"); if (!version || !traceId || !parentId || !flags) return null; if (version.length !== 2 || !HEX.test(version) || version === "ff") return null; // Version 00 has exactly four fields; later versions may append more, which we ignore. if (version === "00" ? value.length !== 55 : value.length > 55 && value[55] !== "-") return null; if (traceId.length !== 32 || !HEX.test(traceId) || /^0+$/.test(traceId)) return null; if (parentId.length !== 16 || !HEX.test(parentId) || /^0+$/.test(parentId)) return null; if (flags.length !== 2 || !HEX.test(flags)) return null; return { version, traceId, parentId, flags }; } (the file goes on)✎ lines are my notes. Numbered lines are the real file.
// Turns the hourly latency buckets in D1 into a p95. It walks from the // fastest bucket up until it passes 95% of requests, then reports that // bucket's top edge. That's why the status panel shows "≤ 50 ms". export function p95(counts: readonly BucketCount[]): P95 | null { const samples = counts.reduce((sum, c) => sum + c.count, 0); if (samples === 0) return null; const rank = Math.ceil(samples * 0.95); let seen = 0; for (const { bucket, count } of [...counts].sort((a, b) => a.bucket - b.bucket)) { seen += count; if (seen >= rank) { const edge = LATENCY_BUCKETS_MS[bucket]; return edge === undefined ? { samples, aboveMs: LATENCY_BUCKETS_MS.at(-1) as number } : { samples, atMostMs: edge }; } } return null; } (the file goes on)✎ lines are my notes. Numbered lines are the real file.
// Each five-minute check writes one row per target and bumps a daily tally. // That way 30-day uptime adds up about 30 rows, not thousands. purgeOld // clears out anything past 35 days. export async function saveChecks(db: D1Database, results: readonly CheckResult[]): Promise<void> { const statements = results.flatMap((r) => [ db .prepare("INSERT INTO checks (at, target, ok, http_status, duration_ms, detail) VALUES (?, ?, ?, ?, ?, ?)") .bind(r.at, r.target, r.ok ? 1 : 0, r.httpStatus, r.durationMs, r.detail), db .prepare( "INSERT INTO check_days (day, target, total, ok) VALUES (?, ?, 1, ?) ON CONFLICT(day, target) DO UPDATE SET total = total + 1, ok = ok + excluded.ok", ) .bind(dayKey(r.at), r.target, r.ok ? 1 : 0), ]); await db.batch(statements); } /** Deletes checks, daily totals and latency rows older than RETENTION_DAYS. */ export async function purgeOld(db: D1Database, now: number): Promise<void> { const cutoff = now - RETENTION_DAYS * DAY; await db.batch([ db.prepare("DELETE FROM checks WHERE at < ?").bind(cutoff), db.prepare("DELETE FROM check_days WHERE day < ?").bind(dayKey(cutoff)), db.prepare("DELETE FROM latency_hist WHERE hour < ?").bind(hourKey(cutoff)), ]); }✎ lines are my notes. Numbered lines are the real file.
-- It's one line. The purge and the newest-check lookup used to read the -- whole checks table every few minutes, and D1's free plan counts every row -- read. With this index both are quick lookups. -- Without this, the 35-day purge (DELETE ... WHERE at < ?) scans the whole table -- every 5 minutes, and MAX(at) walks the whole (target, at) index. D1 bills rows -- read, and since Sep 1, 2026 free-plan queries fail past 5 million a day. CREATE INDEX checks_at ON checks (at);✎ lines are my notes. Numbered lines are the real file.
// Runs after every build. Each inline <script> and <style> gets hashed, and // the build fails if the Content-Security-Policy doesn't list that hash. // Style attributes fail it too. If an Astro upgrade changes its inline // code, I find out here. "astro:build:done": async ({ dir, logger }) => { const root = fileURLToPath(dir); const all = await files(root); const headers = await readFile(join(root, "_headers"), "utf8"); const allowed = { script: directive(headers, "script-src"), style: directive(headers, "style-src") }; const problems: string[] = []; for (const file of all.filter((f) => f.endsWith(".html"))) { const html = await readFile(file, "utf8"); const page = file.slice(root.length); for (const tag of ["script", "style"] as const) { for (const hash of inlineHashes(html, tag)) { if (!allowed[tag].includes(hash)) problems.push(`${page}: inline ${tag} needs ${hash} in ${tag}-src`); } } if (/<[^>]+\sstyle=/.test(html)) problems.push(`${page}: has a style attribute`); } for (const file of all.filter((f) => IMAGE_EXTENSIONS.test(f))) { const { size } = await stat(file); if (size > IMAGE_BUDGET_BYTES) problems.push(`${file.slice(root.length)}: ${size} bytes, over the image budget`); (the file goes on)✎ lines are my notes. Numbered lines are the real file.
// The last step of every deploy. It loads the live pages with a browser // user agent, since that's when Cloudflare would inject its beacon. Any // script from another site fails the deploy. So does a stray noindex. const problems = []; for (const path of pages) { const res = await fetch(`${origin}${path}`, { headers: browser, cache: "no-store" }); if (!res.ok) { problems.push(`${path}: HTTP ${res.status}`); continue; } const html = await res.text(); for (const [, src] of html.matchAll(/<script\b[^>]*\bsrc=["']?([^"'\s>]+)/gi)) { const url = new URL(src, `${origin}${path}`); if (url.origin !== origin) problems.push(`${path}: third-party script ${url.origin}${url.pathname}`); } if (/cloudflareinsights|data-cf-beacon/i.test(html)) problems.push(`${path}: Cloudflare Web Analytics beacon injected`); // Launched: pages must be indexable. if (/noindex/i.test(res.headers.get("x-robots-tag") ?? "")) problems.push(`${path}: still sends X-Robots-Tag noindex`); } if (problems.length > 0) { (the file goes on)✎ lines are my notes. Numbered lines are the real file.
// Splitting a pair in the blackjack demo. One hand becomes two, each with // the original bet and a new second card. Split aces get one card each and // stop. The game is a pure reducer, so every rule like this has a test. case "split": { if (!can.split || !hand) return state; d.bankroll -= hand.bet; const [a, b] = hand.cards as [DealtCard, DealtCard]; const aces = a.rank === "A"; const left: Hand = { cards: [a], bet: hand.bet, doubled: false, split: true, done: false, outcome: null }; const right: Hand = { ...left, cards: [b] }; left.cards.push(draw(d, true)); right.cards.push(draw(d, true)); d.hands = [left, right]; d.active = 0; d.notes.push( `You split ${aces ? "aces: one card each" : "the pair"}. Hand 1: ${describeTotal(left.cards)}, hand 2: ${describeTotal(right.cards)}.`, ); if (aces) { left.done = true; right.done = true; settle(d); } else { // A two-card 21 after a split can't take more cards. if (handValue(left.cards).total === 21) left.done = true; if (handValue(right.cards).total === 21) right.done = true; if (left.done) { d.active = 0; advance(d); (the file goes on)✎ lines are my notes. Numbered lines are the real file.
// The pressure washer. A spray hits every grime cell in a circle, hardest // in the middle. Splatter, grease and burnt-on crust each take a different // amount of blasting, so the pan cleans up unevenly, like a real one. export function spray(state: SinkState, x: number, y: number, radius: number, power: number): number { let removed = 0; const x0 = Math.max(0, Math.floor(x - radius)); const x1 = Math.min(state.cols - 1, Math.ceil(x + radius)); const y0 = Math.max(0, Math.floor(y - radius)); const y1 = Math.min(state.rows - 1, Math.ceil(y + radius)); for (let cy = y0; cy <= y1; cy++) { for (let cx = x0; cx <= x1; cx++) { const i = cy * state.cols + cx; const left = state.hp[i] ?? 0; if (left <= 0) continue; const distance = Math.hypot(cx + 0.5 - x, cy + 0.5 - y); if (distance > radius) continue; const hit = Math.min(left, power * (1 - distance / radius)); state.hp[i] = left - hit; removed += hit; } } return removed; } (the file goes on)✎ lines are my notes. Numbered lines are the real file.
// Every color, size and timing on the site lives in design/tokens.json. // This turns it into CSS variables, light theme on :root and dark under // data-theme="dark". Change a color there and the whole site follows. export async function buildTokensCss(): Promise<string> { const { color, $description: _, ...rest } = JSON.parse(await readFile(TOKENS_PATH, "utf8")) as { color: Record<keyof typeof THEME_SELECTORS, TokenTree>; $description?: string; } & TokenTree; const parts = [ "/* Generated from design/tokens.json by packages/tokens. Do not edit. */", await toCss(rest, ":root"), ]; for (const [theme, selector] of Object.entries(THEME_SELECTORS)) { parts.push(await toCss({ color: color[theme as keyof typeof THEME_SELECTORS] }, selector)); } return parts.join("\n"); } (the file goes on)✎ lines are my notes. Numbered lines are the real file.
# Every push to main runs this once the tests and Lighthouse pass. It writes # /deploy.json for the status panel, migrates the database and deploys the # Worker. Then it checks the live site for third-party scripts. - name: Write /deploy.json run: node scripts/write-deploy-json.mjs - name: Apply D1 migrations uses: cloudflare/wrangler-action@v4 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: d1 migrations apply DB --remote - name: Deploy uses: cloudflare/wrangler-action@v4 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: deploy # Fetch the live pages as a browser would. Fails if anything (such as # Cloudflare's automatic analytics beacon) injected a third-party script. - name: Check the live site for third-party scripts run: node scripts/check-live.mjs✎ lines are my notes. Numbered lines are the real file.
What's under the hood
Stack
Astro builds every page ahead of time. Pages ship no JavaScript unless they have a widget, and widgets load when you scroll to them.
One Cloudflare Worker serves the static files and handles /api/*. Page views never run it. D1 stores what the cron checks find, and the whole backend is set up in one wrangler.jsonc.
The live parts
Every five minutes a cron job loads the homepage, the status API and Bank Job's status endpoint. The results go into D1.
API latency comes from real visitor requests, sorted into fixed time buckets. That's why the p95 reads "at most" a number. Want to see your own request? Here's how this page was served.
Design
Colors, spacing and type all come from one tokens file.
tape-blue#1F5FD6 light, #8DB8FF darktape-green#127A4B light, #7EDBAA darkstamp#B42C7C light, #FF8FCB darktape-blue (tape-purple on hover)#1F5FD6 light, #8DB8FF dark
Accessibility
Every page is held to WCAG 2.2 AA in both themes. Axe and keyboard tests run on every page before anything deploys. Motion follows your reduced-motion setting, and every target is at least 24 by 24 pixels.
Performance budgets
Every build gets a mobile Lighthouse run, and fails if a page goes over budget.
- Performance 90 or better, accessibility 100, best practices 95 or better.
- Largest contentful paint within 2.5 seconds.
- Layout shift under 0.05.
- At most 20 KB of JavaScript (gzipped) before a widget loads.
- At most 250 KB of fonts per page. No image over 200 KB.
Cost
It runs on Cloudflare's free Workers and D1 plans. The domain is the only bill. Page views are static files, so only API calls and the five-minute checks count as Worker requests.
Privacy
No cookies and no third-party scripts. Your visit is only counted if you say yes in the footer, and then it's just one more tally for the day. Your theme choice stays in your browser. The Worker never logs or stores IP addresses.
Credits
IBM Plex Sans and IBM Plex Mono, under the SIL Open Font License, self-hosted from Fontsource.