import ContextCache from "./ContextCache.js"; import path from "path"; function formatTimeSinceInSeconds(start) { return Math.ceil((performance.now() - start) / 100) / 10; } function serveResult(result, fileName, res, next) { let bundle, error; try { for (const out of result.outputFiles) { if (path.basename(out.path) === fileName) { bundle = out.text; } } } catch (e) { error = e; } if (!bundle) { next( new Error(`Failed to generate bundle: ${fileName}`, { cause: error, }), ); return; } res.append("Cache-Control", "max-age=0"); res.append("Content-Type", "application/javascript"); res.send(bundle); } function createRoute(app, name, route, context, dependantCaches) { const cache = new ContextCache(context); app.get(route, async function (req, res, next) { const fileName = path.basename(req.originalUrl); // Multiple files may be requested at this path, calling this function in quick succession. // Await the previous build before re-building again. try { await cache.promise; } catch { // Error is reported upstream } if (!cache.isBuilt()) { try { const start = performance.now(); if (dependantCaches) { await Promise.all( dependantCaches.map((dependantCache) => { if (!dependantCache.isBuilt()) { return dependantCache.rebuild(); } }), ); } await cache.rebuild(); console.log( `Built ${name} in ${formatTimeSinceInSeconds(start)} seconds.`, ); } catch (e) { next(e); } } return serveResult(cache.result, fileName, res, next); }); return cache; } export default createRoute;