// esbuild build for @hive/dashboard. Output layout (`dist/`): // // dist/index.html served by the Rust router at GET / // dist/flow.html served at GET /flow.html // dist/static/app.js /index.html entry — tab renderers + // tab routing + refreshState // dist/static/flow.js /flow.html entry — broker terminal + // operator inbox + @-mention composer // dist/static/{app,flow}.js.map source map siblings // dist/static/dashboard.css served at /static/dashboard.css // (@import resolved from @hive/shared) // // Both JS entries inline `./common.js` (DOM helpers, Panel singleton, // NOTIF, path linkification) — esbuild dedupes the shared module // between bundles. The Rust binary mounts `dist/` as a // `tower_http::ServeDir` fallback; the layout above keeps every URL // the HTML files reference reachable without rewriting paths in the // HTML. import { build } from 'esbuild'; import { mkdirSync, copyFileSync, rmSync } from 'node:fs'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; const here = dirname(fileURLToPath(import.meta.url)); const src = (p) => resolve(here, 'src', p); const dist = (p) => resolve(here, 'dist', p); const staticDir = (p) => resolve(here, 'dist', 'static', p); rmSync(dist(''), { recursive: true, force: true }); mkdirSync(staticDir(''), { recursive: true }); // Bundle both JS entries. ES-module output, browser target, no minify // (line-aligned source aids debugging; minification belongs in a later // follow-up once asset sizes warrant it). esbuild writes each entry // to `static/.js` based on the entryPoint basename. await build({ entryPoints: [src('app.js'), src('flow.js')], outdir: staticDir(''), bundle: true, format: 'esm', platform: 'browser', target: ['es2022'], sourcemap: true, logLevel: 'info', }); // Stream-worker entry (#448). Lives in a separate bundle: SharedWorker // scripts run in a different global (`self` is the worker scope, no // `window`) so they can't be inlined into app.js / flow.js. Output is // at `static/stream-worker.js`; common.js's `openStream` references // `/static/stream-worker.js` as the SharedWorker URL. `format: 'iife'` // matches the classic-script load (`new SharedWorker(url, name)` with // no `{ type: 'module' }`); Firefox is the #448 target and module // SharedWorker support there is patchy, so keeping the worker as a // classic script + IIFE bundle is the compatible default. argus nit // on #453: if a future contributor adds an `import` to this bundle, // the IIFE format will surface it as a build error rather than // silently shipping broken code. await build({ entryPoints: [src('stream-worker.js')], outdir: staticDir(''), bundle: true, format: 'iife', platform: 'browser', target: ['es2022'], sourcemap: true, logLevel: 'info', }); // Bundle the CSS — esbuild resolves @import including the package // re-exports from @hive/shared. await build({ entryPoints: [src('dashboard.css')], outfile: staticDir('dashboard.css'), bundle: true, loader: { '.css': 'css' }, logLevel: 'info', }); for (const html of ['index.html', 'flow.html']) { copyFileSync(src(html), dist(html)); } console.log('dashboard build ok →', dist(''));