| @@ -44,13 +44,30 @@ function collectStaticRoutes(dir: string, prefix = ""): Record<string, ReturnTyp · 43 unmodified lines |
| 44 | 44 | return routes; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | +/** |
| 48 | + * Convert an embedded web UI map (path → bunfs path) into Bun.serve routes. |
| 49 | + * The embedded map is generated by the CLI build step using `with { type: "file" }`. |
| 50 | + */ |
| 51 | +function embeddedToStaticRoutes( |
| 52 | + embedded: Record<string, string>, |
| 53 | +): Record<string, ReturnType<typeof Bun.file>> { |
| 54 | + const routes: Record<string, ReturnType<typeof Bun.file>> = {}; |
| 55 | + for (const [key, bunfsPath] of Object.entries(embedded)) { |
| 56 | + routes[`/${key}`] = Bun.file(bunfsPath); |
| 57 | + } |
| 58 | + return routes; |
| 59 | +} |
| 60 | + |
| 47 | 61 | // --------------------------------------------------------------------------- |
| 48 | 62 | // Server |
| 49 | 63 | // --------------------------------------------------------------------------- |
| 50 | 64 | |
| 51 | 65 | export interface StartServerOptions { |
| 52 | 66 | port?: number; |
| 67 | + /** Directory containing built client assets (for dev/disk serving). */ |
| 53 | 68 | clientDir?: string; |
| 69 | + /** Embedded web UI map from compiled binary (path → bunfs path). Overrides clientDir. */ |
| 70 | + embeddedWebUI?: Record<string, string> | null; |
| 54 | 71 | } |
| 55 | 72 | |
| 56 | 73 | export interface ServerInstance { |
| @@ -63,8 +80,18 @@ export async function startServer(opts: StartServerOptions = {}): Promise<Server · 6 unmodified lines |
| 63 | 80 | const clientDir = opts.clientDir ?? resolve(import.meta.dirname, "../dist"); |
| 64 | 81 | |
| 65 | 82 | const handlers = await getServerHandlers(); |
| 66 | | − const staticRoutes = collectStaticRoutes(clientDir); |
| 67 | | − const indexHtml = Bun.file(join(clientDir, "index.html")); |
| 83 | + |
| 84 | + // Build static routes from either embedded assets or disk |
| 85 | + let staticRoutes: Record<string, ReturnType<typeof Bun.file>>; |
| 86 | + let indexHtml: ReturnType<typeof Bun.file>; |
| 87 | + |
| 88 | + if (opts.embeddedWebUI) { |
| 89 | + staticRoutes = embeddedToStaticRoutes(opts.embeddedWebUI); |
| 90 | + indexHtml = staticRoutes["/index.html"] ?? Bun.file(join(clientDir, "index.html")); |
| 91 | + } else { |
| 92 | + staticRoutes = collectStaticRoutes(clientDir); |
| 93 | + indexHtml = Bun.file(join(clientDir, "index.html")); |
| 94 | + } |
| 68 | 95 | |
| 69 | 96 | const server = Bun.serve({ |
| 70 | 97 | port, |