UNPKG

winterspec

Version:

Write Winter-CG compatible routes with filesystem routing and tons of features

69 lines (68 loc) 2.49 kB
import { once } from "node:events"; import { createServer } from "node:http"; import kleur from "kleur"; import { transformToNodeBuilder } from "../../edge/transform-to-node.js"; import { RequestHandlerController } from "./request-handler-controller.js"; import { createBirpc } from "birpc"; /** * Start a headless WinterSpec dev server. It receives a bundle from the headless dev bundler and serves it. * * This must be run within a native context (Node.js, Bun, or Deno). */ export const startHeadlessDevServer = async ({ port, config, rpcChannel, middleware = [], onListening, onBuildStart, onBuildEnd, }) => { const birpc = createBirpc({ onBuildStart: () => { onBuildStart?.(); }, onBuildEnd: (result) => { onBuildEnd?.(result); }, }, rpcChannel); const controller = new RequestHandlerController(birpc, middleware); const server = createServer(transformToNodeBuilder({ defaultOrigin: `http://localhost:${port}`, })(async (req) => { try { if (config.platform === "wintercg-minimal") { const runtime = await controller.getWinterCGRuntime(); const response = await runtime.dispatchFetch(req.url, req); await response.waitUntil(); return response; } const nodeHandler = await controller.getNodeHandler(); return await nodeHandler(req); } catch (error) { if (error instanceof Error) { process.stderr.write(kleur.bgRed("\nUnhandled exception:\n") + (error.stack ?? error.message) + "\n"); } else { process.stderr.write("Unhandled exception:\n" + (error.stack ? error.stack : JSON.stringify(error)) + "\n"); } return new Response("Internal server error", { status: 500, }); } })); const listeningPromise = once(server, "listening"); server.listen(port); await listeningPromise; onListening?.(port); return { server, stop: async () => { const closePromise = once(server, "close"); server.close(); await closePromise; }, getBuildResult: async () => { return birpc.waitForAvailableBuild(); }, }; };