Files
teamchong cb522a70fe feat(dashboard): replace Svelte bundle with AHA stack (htmx + Alpine, server-rendered fragments)
- src/dashboard/fragments.ts: server-side HTML fragment renderers reusing the
  same JSON payloads (HTML and JSON surfaces can't drift)
- node.ts/dashboard.ts: /fragments/<name> routes (header, session-summary,
  recent, latest, sessions, stats, toggle) with htmx polling + Alpine for
  local state; toggle is a POST-returning-fragment htmx swap
- vendored htmx 2.0.4 + Alpine 3.14.9 in src/dashboard/vendor.ts (offline,
  single-file npm package, no CDN)
- deleted Svelte components/stores/bundle build step; dropped svelte/vite
  devDeps; build is now just tsc + esbuild
- tests: +5 fragment contract tests (routing, toggle state, HTML escaping of
  source text, 404) - 339 total
2026-06-09 22:17:53 -04:00

24 lines
942 B
JavaScript

#!/usr/bin/env node
// Regenerates src/dashboard/vendor.ts from pinned htmx + Alpine releases.
// Run manually when bumping versions; the output is checked in so the
// build has no network dependency.
import { writeFileSync } from 'node:fs';
const PINS = [
['HTMX_JS', 'https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js'],
['ALPINE_JS', 'https://unpkg.com/alpinejs@3.14.9/dist/cdn.min.js'],
];
let out =
'// GENERATED by scripts/vendor-ui.mjs - do not edit by hand.\n' +
'// htmx 2.0.4 (BSD-2) + Alpine.js 3.14.9 (MIT), inlined so the dashboard\n' +
'// works offline and ships inside the single-file npm package.\n';
for (const [name, url] of PINS) {
const res = await fetch(url);
if (!res.ok) throw new Error(`${url}: ${res.status}`);
const js = await res.text();
out += `\nexport const ${name} = ${JSON.stringify(js)};\n`;
}
writeFileSync('src/dashboard/vendor.ts', out);
console.log('wrote src/dashboard/vendor.ts');