Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/frontend/packages/dashboard/build.mjs
atlas 884fb3e08b dashboard: remove the L0GS page and its journal backend
Logs live at swarm level now (VictoriaLogs, read through Grafana
Explore). The hive dashboard's own journal viewer goes, with
everything that existed only to serve it:

- frontend: /logs.html, logs.js, logs.css, the H0M3 "Logs" tile and
  the per-agent menu's "journal logs ->" link. The build-log list
  rules BU1LDS used from logs.css move into builds.css.
- hive-c0re: GET /api/journal/{name} and GET /api/journal-host, and
  priv_client::read_container_journal.
- hive-priv / hive-priv-sock: the ReadContainerJournal request, its
  JournalQuery/JournalOutput wire types and the journalctl -M executor.
- nix: hive-c0re's systemd-journal supplementary group, whose only
  reader was the journal-host handler.
- docs: the L0GS section, the API entry and the security table row.

Closes #5113
Closes #3819
2026-10-12 01:26:33 +02:00

128 lines
4.9 KiB
JavaScript

// esbuild build for @hive/dashboard: one JS+CSS bundle per page (H0M3 at
// `/`, dashboard/flow/core/builds at their own
// `.html`), each named after its own entry point below — see the
// `entryPoints`/`for` lists for the exact map, not repeated here to
// avoid this comment drifting out of sync with the real build steps.
//
// Each JS entry bundles `./common.js` (DOM helpers, Panel singleton,
// NOTIF, path linkification) independently — esbuild inlines the shared
// module into each bundle rather than emitting a shared chunk (no
// `splitting: true`). The Rust binary mounts `dist/` as a
// `tower_http::ServeDir` fallback (`append_index_html_on_directories`
// serves index.html at /); the dashboard SPA lives at /dashboard.html
// (a plain file, not a /dashboard/ prefix) so it never shadows the
// exact-match /dashboard/stream + /dashboard/history SSE routes
// registered before the ServeDir fallback.
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 the 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/<name>.js` based on the entryPoint basename.
await build({
entryPoints: [
src("tabs.js"),
src("flow.js"),
src("home.js"),
src("stats.js"),
src("core.js"),
src("builds.js"),
],
outdir: staticDir(""),
bundle: true,
format: "esm",
platform: "browser",
target: ["es2022"],
sourcemap: true,
logLevel: "info",
// `@hive/shared/modal.js` and `hive-btn.js` import their shadow-DOM
// component CSS (hive-dialog.css, hive-toast.css, hive-btn.css) as raw
// text via a plain `import css from './foo.css'` — the `text` loader turns
// that into a string constant at bundle time instead of erroring on an
// unrecognised extension. None of these JS entries import a `.css`
// file any other way, so this doesn't collide with the separate
// page-stylesheet bundling below (`loader: { '.css': 'css' }`), which
// runs as its own esbuild invocation over different entry points.
loader: { ".css": "text" },
// `@hive/shared/jobq-graph.js` resolves to a real `.jsx` file
// (`JobqGraph.jsx`), pulled in transitively by `builds.js` — esbuild
// already picks the `jsx` loader for `.jsx` by extension, this just
// sets the transform mode to match swarm-ui's (which also authors
// this file). No other entry here uses JSX today; this doesn't turn
// any plain `.js` file into one, `.js` still parses as plain JS.
jsx: "automatic",
jsxImportSource: "preact",
});
// Stream-worker entry. 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 tabs.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's module SharedWorker support is
// patchy, so keeping the worker as a classic script + IIFE bundle is
// the compatible default. argus's own review nit here: 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 CSS — one entry per page. esbuild resolves @import including
// the package re-exports from @hive/shared. Each page loads colors.css
// (the standalone base16 palette — the theme swap contract, its own file
// so a swap replaces only it) + theme.css (the semantic derivation
// layer) + common.css (shared typography, badges, buttons, inbox, side
// panel) plus its own page-specific bundle.
for (const entry of [
"colors.css",
"theme.css",
"common.css",
"dashboard.css",
"flow.css",
"home.css",
"stats.css",
"core.css",
"builds.css",
]) {
await build({
entryPoints: [src(entry)],
outfile: staticDir(entry),
bundle: true,
loader: { ".css": "css" },
logLevel: "info",
});
}
for (const html of [
"index.html",
"dashboard.html",
"flow.html",
"stats.html",
"core.html",
"builds.html",
]) {
copyFileSync(src(html), dist(html));
}
console.log("dashboard build ok →", dist(""));