| @@ -44,13 +44,30 @@ function collectStaticRoutes(dir: string, prefix = ""): Record<string, ReturnTyp · 43 unmodified lines |
| 44 | return routes; | 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 | // Server | 62 | // Server |
| 49 | // --------------------------------------------------------------------------- | 63 | // --------------------------------------------------------------------------- |
| 50 | | 64 | |
| 51 | export interface StartServerOptions { | 65 | export interface StartServerOptions { |
| 52 | port?: number; | 66 | port?: number; |
| | 67 | /** Directory containing built client assets (for dev/disk serving). */ |
| 53 | clientDir?: string; | 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 | export interface ServerInstance { | 73 | export interface ServerInstance { |
| @@ -63,8 +80,18 @@ export async function startServer(opts: StartServerOptions = {}): Promise<Server · 6 unmodified lines |
| 63 | const clientDir = opts.clientDir ?? resolve(import.meta.dirname, "../dist"); | 80 | const clientDir = opts.clientDir ?? resolve(import.meta.dirname, "../dist"); |
| 64 | | 81 | |
| 65 | const handlers = await getServerHandlers(); | 82 | const handlers = await getServerHandlers(); |
| 66 | const staticRoutes = collectStaticRoutes(clientDir); | 83 | |
| 67 | const indexHtml = Bun.file(join(clientDir, "index.html")); | 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 | const server = Bun.serve({ | 96 | const server = Bun.serve({ |
| 70 | port, | 97 | port, |