Braden Evans

bradene0bradenevans.dev

private

The code behind this site, with my notes.

main10 hand-picked files

Files

Braden EvansTrim obvious lines, fix grammar, call Bank Job featured043e325
  • raw13 of 42 lines, from line 14TypeScript
    // 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.

  • raw16 of 58 lines, from line 25TypeScript
    // 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.

  • raw23 of 105 lines, from line 83TypeScript
    // 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.

  • raw4 of 4 lines, from line 1SQL
    -- 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.

  • raw22 of 72 lines, from line 40TypeScript
    // 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.

  • raw20 of 40 lines, from line 17JavaScript
    // 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.

  • raw25 of 385 lines, from line 351TypeScript
    // 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.

  • raw20 of 126 lines, from line 78TypeScript
    // 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.

  • raw19 of 67 lines, from line 43TypeScript
    // 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.

  • raw21 of 75 lines, from line 55YAML
    # 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.

README.md

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 dark
  • tape-green#127A4B light, #7EDBAA dark
  • stamp#B42C7C light, #FF8FCB dark
  • tape-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.