diff options
| author | Adam Malczewski <[email protected]> | 2026-06-21 20:26:39 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-21 20:26:39 +0900 |
| commit | 4434fbf951d06a721597e805094069477851178e (patch) | |
| tree | 4d3103ccb0512ff77d9d472d7b4178c11c8b73b3 /packages | |
| parent | ac69e5f8bea9377887a6f89ff362c6be0db1c874 (diff) | |
| download | dispatch-4434fbf951d06a721597e805094069477851178e.tar.gz dispatch-4434fbf951d06a721597e805094069477851178e.zip | |
feat: standalone build + systemd install (Arch Linux)
bin/build: compiles standalone binaries (dispatch-server + dispatch CLI)
via bun build --compile, builds the frontend static bundle with
VITE_HTTP_PORT=24991 + VITE_WS_PORT=24990, copies to dist/web/.
bin/install: installs binaries to /usr/bin/, frontend to
/usr/share/dispatch/web/, systemd service to /etc/systemd/system/,
config to /etc/dispatch/env, data dirs to /var/lib/dispatch/ +
/var/log/dispatch/. Enables + starts the dispatch systemd service.
Supports --uninstall and --no-build flags.
systemd/dispatch.service: Type=simple, reads /etc/dispatch/env,
restarts on failure, logs to journald.
systemd/dispatch.env: template config (ports 24991 HTTP + 24990 WS,
DISPATCH_WEB_DIR, API key, data paths).
transport-http: optional webDir static file serving — unmatched GET
requests fall through to Bun.file() serving with SPA index.html
fallback. Gated on DISPATCH_WEB_DIR env var (backward compatible).
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/transport-http/src/app.ts | 27 | ||||
| -rw-r--r-- | packages/transport-http/src/extension.ts | 3 |
2 files changed, 30 insertions, 0 deletions
diff --git a/packages/transport-http/src/app.ts b/packages/transport-http/src/app.ts index 86bac0d..9e4fc8a 100644 --- a/packages/transport-http/src/app.ts +++ b/packages/transport-http/src/app.ts @@ -64,6 +64,12 @@ export interface CreateServerOptions { * that endpoint responds `500 { error: "not available" }`. */ readonly emit?: HostAPI["emit"]; + /** + * Directory containing built frontend static files. When set, unmatched GET + * requests fall through to static file serving (SPA fallback to index.html). + * When absent, no static serving (API-only — backward compatible). + */ + readonly webDir?: string; } const noopLogger: Logger = { @@ -669,5 +675,26 @@ export function createApp(opts: CreateServerOptions): Hono { } }); + // ─── Static frontend serving (catch-all, API routes take precedence) ────── + if (opts.webDir !== undefined) { + const webDir = opts.webDir; + app.get("*", async (c) => { + const urlPath = new URL(c.req.url).pathname; + const filePath = `${webDir}${urlPath}`; + const file = Bun.file(filePath); + if (await file.exists()) { + return new Response(file); + } + // SPA fallback: serve index.html for client-side routing + const indexFile = Bun.file(`${webDir}/index.html`); + if (await indexFile.exists()) { + return new Response(indexFile, { + headers: { "Content-Type": "text/html; charset=utf-8" }, + }); + } + return c.json({ error: "Not found" }, 404); + }); + } + return app; } diff --git a/packages/transport-http/src/extension.ts b/packages/transport-http/src/extension.ts index e402213..3555f8e 100644 --- a/packages/transport-http/src/extension.ts +++ b/packages/transport-http/src/extension.ts @@ -73,6 +73,9 @@ export function createTransportHttpExtension(): Extension & { lspService, logger, emit: host.emit.bind(host), + ...(process.env.DISPATCH_WEB_DIR !== undefined + ? { webDir: process.env.DISPATCH_WEB_DIR } + : {}), }); const port = host.config.get<number>("httpPort") ?? 24203; |
