import globalExternals from "@fal-works/esbuild-plugin-global-externals"; import { style } from "@hyrious/esbuild-plugin-style"; import { context } from "esbuild"; import { dirAsync, existsAsync, removeAsync, writeAsync } from "fs-jetpack"; import { DCode } from "../../../../../web/src/utils/types/root"; import { readDirectoryRecursively } from "../../../../api/site-export"; import { docs } from "../../entity/docs"; import { CodeMode, code } from "./util-code"; export const codeBuild = async (id_site: any, mode: CodeMode) => { const src_path = code.path(id_site, mode, "src"); if (!(await existsAsync(src_path))) return; const build_path = code.path(id_site, mode, "build"); await removeAsync(build_path); await dirAsync(build_path); const build_file = `${build_path}/index.js`; await writeAsync(build_file, ""); if (!code.esbuild[id_site]) { code.esbuild[id_site] = { site: null, ssr: null }; } if (!code.esbuild[id_site][mode]) { code.esbuild[id_site][mode] = await context({ absWorkingDir: src_path, entryPoints: ["index.tsx"], bundle: true, outfile: build_file, minify: true, treeShaking: true, format: "cjs", logLevel: "silent", sourcemap: true, plugins: [ style(), globalExternals({ react: { varName: "window.React", type: "cjs", }, "react-dom": { varName: "window.ReactDOM", type: "cjs", }, }), { name: "prasi", setup(setup) { setup.onEnd((res) => { const cdoc = docs.code[id_site]; if (cdoc) { const doc = cdoc.build[mode]; const build_dir = code.path(id_site, mode, "build"); console.log("done building", build_dir); if (doc) { codeApplyChanges(build_dir, doc); } } }); }, }, ], }); const esbuild = code.esbuild[id_site][mode]; esbuild?.watch(); } const esbuild = code.esbuild[id_site][mode]; if (esbuild) { try { await esbuild.rebuild(); } catch (e) { console.error(e); } } const out = Bun.file(build_file); const src = (await out.text()).replace( "//# sourceMappingURL=index.js.map", `//# sourceMappingURL=/nova-load/code/${id_site}/${mode}/index.js.map` ); await Bun.write(out, src); }; const codeApplyChanges = (path: string, doc: DCode) => { const map = doc.getMap("map"); const files = map.get("files"); const dirs = readDirectoryRecursively(path); doc.transact(() => { files?.forEach((v, k) => { if (!dirs[k]) { files?.delete(k); } }); for (const [k, v] of Object.entries(dirs)) { if (files) { files.set(k, v); } } }); return doc; };