sourceMapHandler
uses node:fs
tcm dev's answer to Flight asking where a server stack frame's code is (/__parcel_source_map?filename=…, as
the browser's React DevTools and console show server components' stacks): a source map of the cache's module, by
the name of the codebase's definition in it, with its code, so a frame opens as that code. Only the cache's
modules of definitions.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; import type { Middleware } from "#codebase/tcmts/cli/web"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; export function sourceMapHandler(cb: Codebase): Middleware { const cache = fs.realpathSync(cb.lay.cacheDir); return (req, res, next) => { const url = new URL(req.url ?? "/", "http://x"); if (url.pathname !== "/__parcel_source_map") return next(); let file: string | undefined; try { file = fileURLToPath(url.searchParams.get("filename") ?? ""); } catch { file = undefined; } const m = file && path.dirname(file) === cache ? /^([a-z2-7]{52})\.tsx?$/.exec(path.basename(file)) : null; if (!file || !m || !fs.existsSync(file)) { res.statusCode = 404; return res.end(); } const text = fs.readFileSync(file, "utf8"); const member = cb.store.componentMembers(m[1]!)[0]; const name = member ? cb.displayRef(`#${member.hash}`).replace(/^#/, "") : m[1]!; // (line for line: the module is what Node ran, its types blanked out where they were) const lines = text.split("\n").length; res.setHeader("content-type", "application/json"); res.end( JSON.stringify({ version: 3, file: path.basename(file), sources: [`codebase/${name}${path.extname(file)}`], sourcesContent: [text], names: [], mappings: ["AAAA", ...Array.from({ length: lines - 1 }, () => "AACA")].join(";"), }), ); }; }