MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / startServer

Function startServer

apps/host-selfhost/src/serve.ts:94–132  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

92 );
93
94export const startServer = async (): Promise<void> => {
95 const config = loadConfig();
96 const { AppLayer, betterAuth } = await makeSelfHostApp();
97
98 // Serve the built SPA, split by cacheability so a redeploy is picked up at
99 // once instead of stranding browsers on a stale shell:
100 // - `/assets/*` are Vite content-hashed (a new build emits new filenames),
101 // so they're safe to cache forever.
102 // - index.html (and the SPA fallback for client routes) is the mutable
103 // entry point that references those hashes; it must always revalidate, or
104 // a browser keeps an old index.html plus its old hashed bundles (still in
105 // cache) and renders a stale UI until a hard refresh.
106 // Without explicit headers `HttpStaticServer` sends no Cache-Control at all,
107 // so browsers heuristically cache index.html across deploys. The hashed
108 // `/assets` route is the more specific match, so it wins over the SPA
109 // catch-all. Other built-in API/docs/auth/mcp routes still take precedence;
110 // `spa: true` falls back to index.html for any remaining path (client routing).
111 const AssetsLive = HttpStaticServer.layer({
112 root: assetsDir,
113 prefix: "/assets",
114 cacheControl: "public, max-age=31536000, immutable",
115 }).pipe(Layer.provide(BunFileSystem.layer), Layer.provide(BunPath.layer));
116
117 const SpaLive = HttpStaticServer.layer({
118 root: distDir,
119 spa: true,
120 cacheControl: "no-cache",
121 }).pipe(Layer.provide(BunFileSystem.layer), Layer.provide(BunPath.layer));
122
123 const ServerLive = HttpRouter.serve(Layer.mergeAll(AppLayer, AssetsLive, SpaLive), {
124 middleware: selfHostHttpMiddleware(betterAuth),
125 }).pipe(
126 Layer.provide(
127 BunHttpServer.layer({ hostname: config.host, port: config.port, idleTimeout: 0 }),
128 ),
129 );
130
131 await BunRuntime.runMain(Layer.launch(ServerLive));
132};
133
134if (import.meta.main) {
135 // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: process entry point; turn a pre-runtime startup failure (config/DB open) into a diagnosable log + non-zero exit instead of an opaque unhandled rejection

Callers 1

serve.tsFile · 0.70

Calls 3

loadConfigFunction · 0.90
makeSelfHostAppFunction · 0.90
selfHostHttpMiddlewareFunction · 0.85

Tested by

no test coverage detected