UNPKG

winterspec

Version:

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

66 lines (65 loc) 2.66 kB
import fs from "node:fs/promises"; import { EdgeRuntime } from "edge-runtime"; import { loadBundle } from "../../helpers.js"; const BUILD_ERROR_MESSAGE = "Could not build your app. Check your terminal for more information."; export class RequestHandlerController { constructor(bundlerRpc, middleware) { this.bundlerRpc = bundlerRpc; this.middleware = middleware; this.buildLastUpdatedAt = 0; } /** * You **should not** cache the result of this function. Call it every time you want to use the runtime. */ async getWinterCGRuntime() { const { buildUpdatedAtMs, ...build } = await this.bundlerRpc.waitForAvailableBuild(); if (this.buildLastUpdatedAt === buildUpdatedAtMs && this.cachedWinterCGRuntime) { return this.cachedWinterCGRuntime; } if (build.type === "failure") { this.cachedWinterCGRuntime = new EdgeRuntime({ initialCode: ` addEventListener("fetch", (event) => { event.respondWith(new Response("${BUILD_ERROR_MESSAGE}", { status: 500 })) }) `, }); } else { const contents = await fs.readFile(build.bundlePath, "utf-8"); const { middleware } = this; this.cachedWinterCGRuntime = new EdgeRuntime({ initialCode: contents, extend(context) { context._injectedWinterSpecMiddleware = middleware; return context; }, }); } this.buildLastUpdatedAt = buildUpdatedAtMs; return this.cachedWinterCGRuntime; } /** * You **should not** cache the result of this function. Call it every time you want to use the handler. */ async getNodeHandler() { const { buildUpdatedAtMs, ...build } = await this.bundlerRpc.waitForAvailableBuild(); if (this.buildLastUpdatedAt === buildUpdatedAtMs && this.cachedNodeHandler) { return this.cachedNodeHandler; } if (build.type === "failure") { this.cachedNodeHandler = async () => new Response(BUILD_ERROR_MESSAGE, { status: 500 }); } else { // We append the timestamp to the path to bust the cache const winterSpecModule = await loadBundle(`file:${build.bundlePath}#${Date.now()}`); this.cachedNodeHandler = async (req) => winterSpecModule.makeRequest(req, { middleware: this.middleware, }); } this.buildLastUpdatedAt = buildUpdatedAtMs; return this.cachedNodeHandler; } }