import {createRequire} from "node:module"; import path from "node:path"; // Resolve build dependencies from the package's locked node_modules, not from // the helper's own Nix-store location. This program runs only during the build. const require = createRequire(path.join(process.cwd(), "package.json")); const {build} = require("esbuild"); const options = JSON.parse(process.argv[2]); const platform = new Map([ ["react", "/__quixos/platform/react/v18.mjs"], ["react/jsx-runtime", "/__quixos/platform/react-jsx-runtime/v18.mjs"], ["react/jsx-dev-runtime", "/__quixos/platform/react-jsx-dev-runtime/v18.mjs"], ["@quixos/web-studio-react-runtime", "/__quixos/platform/web-studio-react-runtime/v1.mjs"], ]); await build({...options, plugins: [{name: "quixos-browser-source", setup(api) { api.onResolve({filter: /\?browser-source$/}, async ({path: specifier, resolveDir}) => { if (!specifier.startsWith("./") && !specifier.startsWith("../")) throw new Error("Browser source imports must name a relative compiled module"); const resolved = await api.resolve(specifier.slice(0, -"?browser-source".length), {resolveDir, kind: "import-statement"}); if (resolved.errors.length) return {errors: resolved.errors}; return {path: resolved.path, namespace: "browser-source"}; }); api.onLoad({filter: /.*/, namespace: "browser-source"}, async ({path: entry}) => { const browser = await build({entryPoints: [entry], bundle: true, write: false, outfile: "component.mjs", format: "esm", platform: "browser", target: "es2022", metafile: true, plugins: [{name: "quixos-platform", setup(browserApi) { browserApi.onResolve({filter: /.*/}, ({path: name}) => platform.has(name) ? {path: platform.get(name), external: true} : undefined); }}]}); const js = browser.outputFiles.find(file => file.path.endsWith(".mjs")); if (!js) throw new Error("Browser source build produced no JavaScript"); const css = browser.outputFiles.find(file => file.path.endsWith(".css")); if (css && Object.values(browser.metafile.outputs).some(output => output.exports?.includes("styles"))) throw new Error("Use either imported CSS or an explicit styles export, not both"); if (browser.outputFiles.some(file => !file.path.endsWith(".mjs") && !file.path.endsWith(".css"))) throw new Error("Browser assets must be embedded, not emitted as unserved files"); const source = js.text + (css ? `\nexport const styles = ${JSON.stringify(css.text)};\n` : ""); return {contents: `export default ${JSON.stringify(source)};`, loader: "js", watchFiles: Object.keys(browser.metafile.inputs)}; }); }}]});