mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
45c83dedb5
Replace the hand-rolled dashboard with a Svelte component tree (App + Sessions / StatsTable / LatestPng / RecentRequests / StatsHeader / Cleanup / CompressionToggle / ToastTray), move the API layer into lib/, and split state into stores/. Add a dedicated dashboard build (`build:dashboard-ui` + a separate tsconfig.dashboard.json) so dashboard sources typecheck independently of the proxy core, which previously broke the root `tsc` build.
69 lines
2.5 KiB
JavaScript
69 lines
2.5 KiB
JavaScript
// Build the Svelte dashboard UI into a single JS bundle string.
|
|
//
|
|
// Writes `src/dashboard-bundle.ts` with an exported `DASHBOARD_JS` constant
|
|
// containing the compiled IIFE bundle. `src/dashboard.ts` embeds this in the
|
|
// HTML template it serves; no runtime deps on the Node host.
|
|
//
|
|
// CSS is compiled inline (each component injects its own <style> on mount via
|
|
// the svelte compiler's `css: 'injected'` mode), so we ship ONE string.
|
|
|
|
import { build } from 'esbuild';
|
|
import sveltePlugin from 'esbuild-svelte';
|
|
import { sveltePreprocess } from 'svelte-preprocess';
|
|
import { writeFile, mkdir } from 'node:fs/promises';
|
|
import { dirname } from 'node:path';
|
|
|
|
const ENTRY = 'src/dashboard/main.ts';
|
|
const OUT_FILE = 'src/dashboard-bundle.ts';
|
|
|
|
const result = await build({
|
|
entryPoints: [ENTRY],
|
|
bundle: true,
|
|
format: 'iife',
|
|
platform: 'browser',
|
|
target: 'es2022',
|
|
// Svelte 5 ships ESM; we IIFE-wrap so the bundle is a single self-contained
|
|
// script tag in the dashboard HTML. No globals leak — the IIFE returns void.
|
|
minify: true,
|
|
write: false,
|
|
sourcemap: false,
|
|
// The dashboard runs in the operator's browser, not Workers — `console` is fine.
|
|
// We keep the bundle small by stripping debug logs but leaving warn/error.
|
|
drop: ['debugger'],
|
|
plugins: [
|
|
sveltePlugin({
|
|
preprocess: sveltePreprocess(),
|
|
compilerOptions: {
|
|
// Inject CSS via JS so we ship ONE artifact, not a separate stylesheet.
|
|
css: 'injected',
|
|
// Legacy reactivity (`$:`, `export let`) — Svelte 5 still supports it.
|
|
// Runes mode would require rewriting every component to `$state`/`$derived`/
|
|
// `$props`. Worth doing eventually; not blocking this rewrite.
|
|
runes: false,
|
|
},
|
|
}),
|
|
],
|
|
});
|
|
|
|
const js = result.outputFiles[0].text;
|
|
|
|
await mkdir(dirname(OUT_FILE), { recursive: true });
|
|
|
|
// Embed as a backtick string. JS bundle output is safe inside backticks EXCEPT
|
|
// for `${`, `` ` ``, and `\`. Escape all three. The compiled IIFE can contain
|
|
// any of these inside string literals (e.g. an HTML template).
|
|
const escaped = js
|
|
.replace(/\\/g, '\\\\')
|
|
.replace(/`/g, '\\`')
|
|
.replace(/\$\{/g, '\\${');
|
|
|
|
const header = `// AUTO-GENERATED by scripts/build-dashboard-ui.mjs — do not edit by hand.
|
|
// Source: src/dashboard/ (Svelte). Run \`pnpm run build:dashboard-ui\` to regenerate.
|
|
// Size: ${js.length} chars (${(js.length / 1024).toFixed(1)} KB).
|
|
|
|
export const DASHBOARD_JS = \`${escaped}\`;
|
|
`;
|
|
|
|
await writeFile(OUT_FILE, header);
|
|
console.log(`✓ built ${OUT_FILE} (${(js.length / 1024).toFixed(1)} KB)`);
|