diff --git a/dist/commands/dev/dev-spawn.d.ts b/dist/commands/dev/dev-spawn.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist/commands/dev/dev-spawn.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/dist/commands/dev/dev-spawn.js b/dist/commands/dev/dev-spawn.js new file mode 100644 index 0000000..1e195a1 --- /dev/null +++ b/dist/commands/dev/dev-spawn.js @@ -0,0 +1,14 @@ +import startServer from "../../functions/server/start-server"; +import { log } from "../../utils/log"; +import bunextInit from "../../functions/bunext-init"; +import grabDirNames from "../../utils/grab-dir-names"; +import { rmSync } from "fs"; +const { HYDRATION_DST_DIR, BUNX_CWD_PAGES_REWRITE_DIR } = grabDirNames(); +log.info("Running development server ..."); +try { + rmSync(HYDRATION_DST_DIR, { recursive: true }); + rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); +} +catch (error) { } +await bunextInit(); +await startServer(); diff --git a/dist/commands/dev/index.js b/dist/commands/dev/index.js index de878da..613a576 100644 --- a/dist/commands/dev/index.js +++ b/dist/commands/dev/index.js @@ -1,22 +1,30 @@ import { Command } from "commander"; -import startServer from "../../functions/server/start-server"; -import { log } from "../../utils/log"; -import bunextInit from "../../functions/bunext-init"; +import path from "path"; import grabDirNames from "../../utils/grab-dir-names"; -import { rmSync } from "fs"; -const { HYDRATION_DST_DIR, BUNX_CWD_PAGES_REWRITE_DIR, BUNX_CWD_MODULE_CACHE_DIR, } = grabDirNames(); +import writeErrorFile from "../../functions/write-error-file"; export default function () { return new Command("dev") .description("Run development server") .action(async () => { - process.env.NODE_ENV = "development"; - log.info("Running development server ..."); - try { - rmSync(HYDRATION_DST_DIR, { recursive: true }); - rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); - } - catch (error) { } - await bunextInit(); - await startServer(); + await dev(); }); } +async function dev() { + const dev_spawn_file = path.resolve(__dirname, "dev-spawn.ts"); + const spawn_options = { + cmd: ["bun", dev_spawn_file], + stdio: ["inherit", "inherit", "inherit"], + onExit(subprocess, exitCode, signalCode, error) { + writeErrorFile({ exitCode, error }); + }, + env: { + ...process.env, + NODE_ENV: "development", + }, + }; + let dev_process = Bun.spawn(spawn_options); + const exited = await dev_process.exited; + if (exited) { + return await dev(); + } +} diff --git a/dist/commands/start/index.js b/dist/commands/start/index.js index be8edc0..7ec81c3 100644 --- a/dist/commands/start/index.js +++ b/dist/commands/start/index.js @@ -1,14 +1,29 @@ import { Command } from "commander"; -import startServer from "../../functions/server/start-server"; -import { log } from "../../utils/log"; -import bunextInit from "../../functions/bunext-init"; +import path from "path"; +import writeErrorFile from "../../functions/write-error-file"; export default function () { return new Command("start") .description("Start production server") .action(async () => { - process.env.NODE_ENV = "production"; - log.info("Starting production server ..."); - await bunextInit(); - await startServer(); + await start(); }); } +async function start() { + const dev_spawn_file = path.resolve(__dirname, "prod-spawn.ts"); + const spawn_options = { + cmd: ["bun", dev_spawn_file], + stdio: ["inherit", "inherit", "inherit"], + onExit(subprocess, exitCode, signalCode, error) { + writeErrorFile({ exitCode, error }); + }, + env: { + ...process.env, + NODE_ENV: "production", + }, + }; + let dev_process = Bun.spawn(spawn_options); + const exited = await dev_process.exited; + if (exited) { + return await start(); + } +} diff --git a/dist/commands/start/prod-spawn.d.ts b/dist/commands/start/prod-spawn.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist/commands/start/prod-spawn.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/dist/commands/start/prod-spawn.js b/dist/commands/start/prod-spawn.js new file mode 100644 index 0000000..aa49658 --- /dev/null +++ b/dist/commands/start/prod-spawn.js @@ -0,0 +1,6 @@ +import bunextInit from "../../functions/bunext-init"; +import startServer from "../../functions/server/start-server"; +import { log } from "../../utils/log"; +log.info("Starting production server ..."); +await bunextInit(); +await startServer(); diff --git a/dist/data/app-data.d.ts b/dist/data/app-data.d.ts index 9efb307..e909922 100644 --- a/dist/data/app-data.d.ts +++ b/dist/data/app-data.d.ts @@ -6,4 +6,5 @@ export declare const AppData: { readonly BunextClientHydrationScriptID: "bunext-client-hydration-script"; readonly BunextTmpFileExt: ".bunext_tmp.tsx"; readonly BunextHMRRetryRoute: "/.bunext/hmr-retry"; + readonly DefaultMaxLogs: 50; }; diff --git a/dist/data/app-data.js b/dist/data/app-data.js index 5a6c1e0..3baa5d0 100644 --- a/dist/data/app-data.js +++ b/dist/data/app-data.js @@ -6,4 +6,5 @@ export const AppData = { BunextClientHydrationScriptID: "bunext-client-hydration-script", BunextTmpFileExt: ".bunext_tmp.tsx", BunextHMRRetryRoute: "/.bunext/hmr-retry", + DefaultMaxLogs: 50, }; diff --git a/dist/functions/bundler/all-pages-esbuild-context-bundler.js b/dist/functions/bundler/all-pages-esbuild-context-bundler.js index dbeed9e..6d934c0 100644 --- a/dist/functions/bundler/all-pages-esbuild-context-bundler.js +++ b/dist/functions/bundler/all-pages-esbuild-context-bundler.js @@ -7,9 +7,11 @@ import grabClientHydrationScript from "./grab-client-hydration-script"; import path from "path"; import virtualFilesPlugin from "./plugins/virtual-files-plugin"; import esbuildCTXArtifactTracker from "./plugins/esbuild-ctx-artifact-tracker"; -const { HYDRATION_DST_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames(); +import { existsSync } from "fs"; +const { HYDRATION_DST_DIR, BUNX_HYDRATION_SRC_DIR, BUNX_BUNDLER_ERROR_EXIT_FILE, } = grabDirNames(); export default async function allPagesESBuildContextBundler(params) { try { + const did_process_exit_because_of_bundler_error = existsSync(BUNX_BUNDLER_ERROR_EXIT_FILE); const pages = grabAllPages({ exclude_api: true }); global.PAGE_FILES = pages; const dev = isDevelopment(); @@ -59,6 +61,9 @@ export default async function allPagesESBuildContextBundler(params) { "react/jsx-runtime", "react/jsx-dev-runtime", ], + logLevel: did_process_exit_because_of_bundler_error + ? "silent" + : undefined, }); await global.BUNDLER_CTX.rebuild(); } diff --git a/dist/functions/bundler/plugins/esbuild-ctx-artifact-tracker.js b/dist/functions/bundler/plugins/esbuild-ctx-artifact-tracker.js index 426538b..87f41ab 100644 --- a/dist/functions/bundler/plugins/esbuild-ctx-artifact-tracker.js +++ b/dist/functions/bundler/plugins/esbuild-ctx-artifact-tracker.js @@ -4,9 +4,15 @@ import grabArtifactsFromBundledResults from "../grab-artifacts-from-bundled-resu import buildOnstartErrorHandler from "../build-on-start-error-handler"; import _ from "lodash"; import pagesSSRBundler from "../pages-ssr-bundler"; +import grabDirNames from "../../../utils/grab-dir-names"; +import { cpSync, existsSync, mkdirSync, rmSync } from "fs"; +import fullRebuild from "../../server/full-rebuild"; +import path from "path"; +import cleanupLogsDirs from "../../cleanup-logs-dir"; +const { BUNX_BUNDLER_ERROR_EXIT_FILE, BUNX_ERROR_LOGS_DIR } = grabDirNames(); let build_start = 0; let build_starts = 0; -const MAX_BUILD_STARTS = 5; +const MAX_BUILD_STARTS = 2; export default function esbuildCTXArtifactTracker({ entryToPage, post_build_fn, }) { const artifactTracker = { name: "artifact-tracker", @@ -14,8 +20,11 @@ export default function esbuildCTXArtifactTracker({ entryToPage, post_build_fn, build.onStart(async () => { build_starts++; build_start = performance.now(); - if (build_starts == MAX_BUILD_STARTS) { + const does_error_file_exist = existsSync(BUNX_BUNDLER_ERROR_EXIT_FILE); + if (build_starts == MAX_BUILD_STARTS && + !does_error_file_exist) { await buildOnstartErrorHandler(); + process.exit(1); } }); build.onEnd((result) => { @@ -41,7 +50,17 @@ export default function esbuildCTXArtifactTracker({ entryToPage, post_build_fn, global.RECOMPILING = false; global.IS_SERVER_COMPONENT = false; build_starts = 0; - pagesSSRBundler(); + const does_error_file_exist = existsSync(BUNX_BUNDLER_ERROR_EXIT_FILE); + if (does_error_file_exist) { + mkdirSync(BUNX_ERROR_LOGS_DIR, { recursive: true }); + cpSync(BUNX_BUNDLER_ERROR_EXIT_FILE, path.join(BUNX_ERROR_LOGS_DIR, `${Date.now()}.log`)); + rmSync(BUNX_BUNDLER_ERROR_EXIT_FILE, { force: true }); + cleanupLogsDirs(); + fullRebuild(); + } + else { + pagesSSRBundler(); + } // if (global.SSR_BUNDLER_CTX) { // global.SSR_BUNDLER_CTX.rebuild(); // } else { diff --git a/dist/functions/bunext-init.js b/dist/functions/bunext-init.js index 590bea4..dee0c8f 100644 --- a/dist/functions/bunext-init.js +++ b/dist/functions/bunext-init.js @@ -48,9 +48,9 @@ export default async function bunextInit() { cron(); } } -process.on("exit", (code) => { - Bun.spawn([process.execPath, ...process.argv.slice(1)], { - stdio: ["inherit", "inherit", "inherit"], - env: process.env, - }); -}); +// process.on("exit", (code) => { +// Bun.spawn([process.execPath, ...process.argv.slice(1)], { +// stdio: ["inherit", "inherit", "inherit"], +// env: process.env, +// }); +// }); diff --git a/dist/functions/cleanup-logs-dir.d.ts b/dist/functions/cleanup-logs-dir.d.ts new file mode 100644 index 0000000..b0ce98b --- /dev/null +++ b/dist/functions/cleanup-logs-dir.d.ts @@ -0,0 +1 @@ +export default function cleanupLogsDirs(): void; diff --git a/dist/functions/cleanup-logs-dir.js b/dist/functions/cleanup-logs-dir.js new file mode 100644 index 0000000..cbfcbd8 --- /dev/null +++ b/dist/functions/cleanup-logs-dir.js @@ -0,0 +1,48 @@ +import path from "path"; +import { mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from "fs"; +import grabDirNames from "../utils/grab-dir-names"; +import grabConstants from "../utils/grab-constants"; +import { AppData } from "../data/app-data"; +const { BUNX_LOGS_DIR } = grabDirNames(); +export default function cleanupLogsDirs() { + const logs_dirs = readdirSync(BUNX_LOGS_DIR); + const { config } = grabConstants(); + const MAX_LOGS = config.max_logs || AppData["DefaultMaxLogs"]; + for (let i = 0; i < logs_dirs.length; i++) { + const dir = logs_dirs[i]; + const full_path = path.join(BUNX_LOGS_DIR, dir); + const path_stats = statSync(full_path); + if (!path_stats.isDirectory()) { + continue; + } + const sub_dir_files = readdirSync(full_path).sort((a, b) => { + const timestamp_a = Number(a.split(".")[0]); + const timestamp_b = Number(b.split(".")[0]); + if (timestamp_a > timestamp_b) + return 1; + return -1; + }); + for (let j = 0; j < sub_dir_files.length; j++) { + const sub_dir_file = sub_dir_files[j]; + const sub_dir_file_full_path = path.join(full_path, sub_dir_file); + const sub_dir_file_Stats = statSync(sub_dir_file_full_path); + if (!sub_dir_file_Stats.isFile()) { + rmSync(sub_dir_file_full_path, { + force: true, + recursive: true, + }); + continue; + } + if (j > MAX_LOGS - 1) { + rmSync(sub_dir_file_full_path, { force: true }); + } + } + } +} +// log.info("Running development server ..."); +// try { +// rmSync(HYDRATION_DST_DIR, { recursive: true }); +// rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); +// } catch (error) {} +// await bunextInit(); +// await startServer(); diff --git a/dist/functions/process.d.ts b/dist/functions/process.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/dist/functions/process.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/dist/functions/process.js b/dist/functions/process.js new file mode 100644 index 0000000..ddf4cf4 --- /dev/null +++ b/dist/functions/process.js @@ -0,0 +1,46 @@ +import { spawn } from "bun"; +// Only the "supervisor" respawns. The child sets this env var so it won't respawn itself. +const IS_CHILD = process.env.__RESPAWN_CHILD === "1"; +let shuttingDown = false; +async function cleanup() { + // Put real cleanup here: close DB handles, servers, file descriptors, timers, etc. + // Must be awaitable — do NOT rely on process.on("exit") for this. +} +function respawn(code) { + const child = spawn({ + cmd: [process.execPath, ...process.argv.slice(1)], + stdio: ["inherit", "inherit", "inherit"], + env: { ...process.env, __RESPAWN_CHILD: "1" }, + // Detach so the child survives independently and gets its own process group. + // Without this, killing the parent's group can take the child with it. + }); + // Let the child live on its own. + child.unref?.(); +} +async function shutdown(code) { + if (shuttingDown) + return; + shuttingDown = true; + try { + await cleanup(); + } + catch (e) { + console.error("cleanup failed:", e); + } + // Only the supervisor respawns, and only on abnormal exit. + if (!IS_CHILD && code !== 0) { + respawn(code); + } + process.exit(code); +} +// Catch the things that actually fire *before* exit, where async works. +process.on("SIGINT", () => shutdown(130)); +process.on("SIGTERM", () => shutdown(143)); +process.on("uncaughtException", (err) => { + console.error(err); + shutdown(1); +}); +process.on("unhandledRejection", (err) => { + console.error(err); + shutdown(1); +}); diff --git a/dist/functions/server/full-rebuild.js b/dist/functions/server/full-rebuild.js index cead864..191199a 100644 --- a/dist/functions/server/full-rebuild.js +++ b/dist/functions/server/full-rebuild.js @@ -1,5 +1,6 @@ import { log } from "../../utils/log"; import allPagesESBuildContextBundler from "../bundler/all-pages-esbuild-context-bundler"; +import pagesSSRBundler from "../bundler/pages-ssr-bundler"; import serverPostBuildFn from "./server-post-build-fn"; import watcherEsbuildCTX from "./watcher-esbuild-ctx"; export default async function fullRebuild(params) { @@ -14,6 +15,7 @@ export default async function fullRebuild(params) { global.BUNDLER_CTX = undefined; await global.SSR_BUNDLER_CTX?.dispose(); global.SSR_BUNDLER_CTX = undefined; + await pagesSSRBundler(); allPagesESBuildContextBundler({ post_build_fn: () => { serverPostBuildFn(); diff --git a/dist/functions/server/watcher-esbuild-ctx.js b/dist/functions/server/watcher-esbuild-ctx.js index 8501165..ccd80d8 100644 --- a/dist/functions/server/watcher-esbuild-ctx.js +++ b/dist/functions/server/watcher-esbuild-ctx.js @@ -5,7 +5,7 @@ import fullRebuild from "./full-rebuild"; import { AppData } from "../../data/app-data"; import checkExcludedPatterns from "../../utils/check-excluded-patterns"; import pagesSSRBundler from "../bundler/pages-ssr-bundler"; -const { ROOT_DIR } = grabDirNames(); +const { ROOT_DIR, BUNX_BUNDLER_ERROR_EXIT_FILE } = grabDirNames(); export default async function watcherEsbuildCTX() { const pages_src_watcher = watch(ROOT_DIR, { recursive: true, @@ -13,6 +13,10 @@ export default async function watcherEsbuildCTX() { }, async (event, filename) => { if (!filename) return; + if (existsSync(BUNX_BUNDLER_ERROR_EXIT_FILE)) { + await fullRebuild(); + return; + } if (filename.match(/^\.\w+/)) { return; } diff --git a/dist/functions/write-error-file.d.ts b/dist/functions/write-error-file.d.ts new file mode 100644 index 0000000..858488c --- /dev/null +++ b/dist/functions/write-error-file.d.ts @@ -0,0 +1,4 @@ +export default function writeErrorFile({ exitCode, error, }: { + error?: Bun.ErrorLike; + exitCode: number | null; +}): void; diff --git a/dist/functions/write-error-file.js b/dist/functions/write-error-file.js new file mode 100644 index 0000000..5b80e15 --- /dev/null +++ b/dist/functions/write-error-file.js @@ -0,0 +1,21 @@ +import path from "path"; +import { mkdirSync, writeFileSync } from "fs"; +import grabDirNames from "../utils/grab-dir-names"; +const { BUNX_BUNDLER_ERROR_EXIT_FILE } = grabDirNames(); +export default function writeErrorFile({ exitCode, error, }) { + let txt = ``; + txt += `Bunext Error\n`; + txt += `============================================\n`; + txt += `ERROR: ${error?.message}\n`; + txt += `EXIT_CODE: ${exitCode || 0}\n`; + txt += `CALL_STACK: ${error?.stack}\n`; + mkdirSync(path.dirname(BUNX_BUNDLER_ERROR_EXIT_FILE), { recursive: true }); + writeFileSync(BUNX_BUNDLER_ERROR_EXIT_FILE, txt); +} +// log.info("Running development server ..."); +// try { +// rmSync(HYDRATION_DST_DIR, { recursive: true }); +// rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); +// } catch (error) {} +// await bunextInit(); +// await startServer(); diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts index ac26dfa..2e7d47d 100644 --- a/dist/types/index.d.ts +++ b/dist/types/index.d.ts @@ -53,6 +53,7 @@ export type BunextConfig = { * from the router */ pages_exclude_patterns?: RegExp[]; + max_logs?: number; }; export type BunextConfigMiddlewareParams = { req: Request; @@ -314,3 +315,6 @@ export type BunextAPIRouteHandlerObjectReturn = Response | (T & Pick = (params: BunxRouteParams) => Promise> | Response | BunextAPIRouteHandlerObjectReturn; +export type BunSpawnOptions = Bun.SpawnOptions.SpawnOptions<"inherit", "inherit", "inherit"> & { + cmd: string[]; +}; diff --git a/dist/utils/grab-dir-names.d.ts b/dist/utils/grab-dir-names.d.ts index 71f53de..b35b411 100644 --- a/dist/utils/grab-dir-names.d.ts +++ b/dist/utils/grab-dir-names.d.ts @@ -23,4 +23,7 @@ export default function grabDirNames(): { HYDRATION_DST_DIR_MAP_JSON_FILE_NAME: string; BUNEXT_VENDOR_DIR: string; BUNEXT_PUBLIC_DIR: string; + BUNX_BUNDLER_ERROR_EXIT_FILE: string; + BUNX_ERROR_LOGS_DIR: string; + BUNX_LOGS_DIR: string; }; diff --git a/dist/utils/grab-dir-names.js b/dist/utils/grab-dir-names.js index 6c2c092..faf22f5 100644 --- a/dist/utils/grab-dir-names.js +++ b/dist/utils/grab-dir-names.js @@ -10,7 +10,10 @@ export default function grabDirNames() { const BUNX_CWD_MODULE_CACHE_DIR = path.resolve(BUNX_CWD_DIR, "module-cache"); const BUNX_CWD_PAGES_REWRITE_DIR = path.resolve(BUNX_CWD_DIR, "pages"); const BUNX_TMP_DIR = path.resolve(BUNX_CWD_DIR, ".tmp"); + const BUNX_BUNDLER_ERROR_EXIT_FILE = path.resolve(BUNX_TMP_DIR, "BUNDLER_EXIT.txt"); const BUNX_HYDRATION_SRC_DIR = path.resolve(BUNX_CWD_DIR, "client", "hydration-src"); + const BUNX_LOGS_DIR = path.resolve(BUNX_CWD_DIR, "logs"); + const BUNX_ERROR_LOGS_DIR = path.resolve(BUNX_LOGS_DIR, "error"); const BUNEXT_PUBLIC_DIR = path.join(BUNX_CWD_DIR, "public"); const HYDRATION_DST_DIR = path.join(BUNEXT_PUBLIC_DIR, "pages"); const BUNEXT_VENDOR_DIR = path.join(BUNEXT_PUBLIC_DIR, "vendor"); @@ -24,64 +27,6 @@ export default function grabDirNames() { const BUNX_ROOT_500_PRESET_COMPONENT = path.join(BUNX_ROOT_PRESETS_DIR, `${BUNX_ROOT_500_FILE_NAME}.tsx`); const BUNX_ROOT_404_FILE_NAME = `not-found`; const BUNX_ROOT_404_PRESET_COMPONENT = path.join(BUNX_ROOT_PRESETS_DIR, `${BUNX_ROOT_404_FILE_NAME}.tsx`); - // const NODE_MODULES_DIR = path.resolve( - // existsSync(path.join(BUNX_ROOT_DIR, "source.md")) - // ? BUNX_ROOT_DIR - // : ROOT_DIR, - // "node_modules", - // ); - // const REACT_MODULE_DIR = path.join(NODE_MODULES_DIR, "react"); - // const REACT_DOM_MODULE_DIR = path.join(NODE_MODULES_DIR, "react-dom"); - // const REACT_PRODUCTION_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react.production.js", - // ); - // const REACT_DEVELOPMENT_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react.development.js", - // ); - // const REACT_JSX_RUNTIME_PRODUCTION_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-runtime.production.js", - // ); - // const REACT_JSX_RUNTIME_DEVELOPMENT_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-runtime.development.js", - // ); - // const REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-dev-runtime.production.js", - // ); - // const REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-dev-runtime.development.js", - // ); - // const REACT_DOM_PRODUCTION_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom.production.js", - // ); - // const REACT_DOM_DEVELOPMENT_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom.development.js", - // ); - // const REACT_DOM_CLIENT_PRODUCTION_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom-client.production.js", - // ); - // const REACT_DOM_CLIENT_DEVELOPMENT_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom-client.development.js", - // ); return { ROOT_DIR, SRC_DIR, @@ -107,18 +52,79 @@ export default function grabDirNames() { HYDRATION_DST_DIR_MAP_JSON_FILE_NAME, BUNEXT_VENDOR_DIR, BUNEXT_PUBLIC_DIR, - // NODE_MODULES_DIR, - // REACT_MODULE_DIR, - // REACT_DOM_MODULE_DIR, - // REACT_PRODUCTION_MODULE, - // REACT_DEVELOPMENT_MODULE, - // REACT_JSX_RUNTIME_PRODUCTION_MODULE, - // REACT_JSX_RUNTIME_DEVELOPMENT_MODULE, - // REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE, - // REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE, - // REACT_DOM_PRODUCTION_MODULE, - // REACT_DOM_DEVELOPMENT_MODULE, - // REACT_DOM_CLIENT_PRODUCTION_MODULE, - // REACT_DOM_CLIENT_DEVELOPMENT_MODULE, + BUNX_BUNDLER_ERROR_EXIT_FILE, + BUNX_ERROR_LOGS_DIR, + BUNX_LOGS_DIR, }; } +// const NODE_MODULES_DIR = path.resolve( +// existsSync(path.join(BUNX_ROOT_DIR, "source.md")) +// ? BUNX_ROOT_DIR +// : ROOT_DIR, +// "node_modules", +// ); +// const REACT_MODULE_DIR = path.join(NODE_MODULES_DIR, "react"); +// const REACT_DOM_MODULE_DIR = path.join(NODE_MODULES_DIR, "react-dom"); +// const REACT_PRODUCTION_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react.production.js", +// ); +// const REACT_DEVELOPMENT_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react.development.js", +// ); +// const REACT_JSX_RUNTIME_PRODUCTION_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-runtime.production.js", +// ); +// const REACT_JSX_RUNTIME_DEVELOPMENT_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-runtime.development.js", +// ); +// const REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-dev-runtime.production.js", +// ); +// const REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-dev-runtime.development.js", +// ); +// const REACT_DOM_PRODUCTION_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom.production.js", +// ); +// const REACT_DOM_DEVELOPMENT_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom.development.js", +// ); +// const REACT_DOM_CLIENT_PRODUCTION_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom-client.production.js", +// ); +// const REACT_DOM_CLIENT_DEVELOPMENT_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom-client.development.js", +// ); +// NODE_MODULES_DIR, +// REACT_MODULE_DIR, +// REACT_DOM_MODULE_DIR, +// REACT_PRODUCTION_MODULE, +// REACT_DEVELOPMENT_MODULE, +// REACT_JSX_RUNTIME_PRODUCTION_MODULE, +// REACT_JSX_RUNTIME_DEVELOPMENT_MODULE, +// REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE, +// REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE, +// REACT_DOM_PRODUCTION_MODULE, +// REACT_DOM_DEVELOPMENT_MODULE, +// REACT_DOM_CLIENT_PRODUCTION_MODULE, +// REACT_DOM_CLIENT_DEVELOPMENT_MODULE, diff --git a/package.json b/package.json index 460aced..2f0b189 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@moduletrace/bunext", - "version": "1.0.81", + "version": "1.0.82", "main": "dist/index.js", "module": "index.ts", "dependencies": { diff --git a/src/commands/dev/dev-spawn.ts b/src/commands/dev/dev-spawn.ts new file mode 100644 index 0000000..79ad16d --- /dev/null +++ b/src/commands/dev/dev-spawn.ts @@ -0,0 +1,18 @@ +import startServer from "../../functions/server/start-server"; +import { log } from "../../utils/log"; +import bunextInit from "../../functions/bunext-init"; +import grabDirNames from "../../utils/grab-dir-names"; +import { rmSync } from "fs"; + +const { HYDRATION_DST_DIR, BUNX_CWD_PAGES_REWRITE_DIR } = grabDirNames(); + +log.info("Running development server ..."); + +try { + rmSync(HYDRATION_DST_DIR, { recursive: true }); + rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); +} catch (error) {} + +await bunextInit(); + +await startServer(); diff --git a/src/commands/dev/index.ts b/src/commands/dev/index.ts index 9f24dc6..7b8f49a 100644 --- a/src/commands/dev/index.ts +++ b/src/commands/dev/index.ts @@ -1,31 +1,36 @@ import { Command } from "commander"; -import startServer from "../../functions/server/start-server"; -import { log } from "../../utils/log"; -import bunextInit from "../../functions/bunext-init"; +import path from "path"; +import type { BunSpawnOptions } from "../../types"; import grabDirNames from "../../utils/grab-dir-names"; -import { rmSync } from "fs"; - -const { - HYDRATION_DST_DIR, - BUNX_CWD_PAGES_REWRITE_DIR, - BUNX_CWD_MODULE_CACHE_DIR, -} = grabDirNames(); +import writeErrorFile from "../../functions/write-error-file"; export default function () { return new Command("dev") .description("Run development server") .action(async () => { - process.env.NODE_ENV = "development"; - - log.info("Running development server ..."); - - try { - rmSync(HYDRATION_DST_DIR, { recursive: true }); - rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); - } catch (error) {} - - await bunextInit(); - - await startServer(); + await dev(); }); } + +async function dev() { + const dev_spawn_file = path.resolve(__dirname, "dev-spawn.ts"); + + const spawn_options: BunSpawnOptions = { + cmd: ["bun", dev_spawn_file], + stdio: ["inherit", "inherit", "inherit"], + onExit(subprocess, exitCode, signalCode, error) { + writeErrorFile({ exitCode, error }); + }, + env: { + ...process.env, + NODE_ENV: "development", + }, + }; + + let dev_process = Bun.spawn(spawn_options); + + const exited = await dev_process.exited; + if (exited) { + return await dev(); + } +} diff --git a/src/commands/start/index.ts b/src/commands/start/index.ts index bf11427..130118d 100644 --- a/src/commands/start/index.ts +++ b/src/commands/start/index.ts @@ -1,17 +1,36 @@ import { Command } from "commander"; -import startServer from "../../functions/server/start-server"; -import { log } from "../../utils/log"; -import bunextInit from "../../functions/bunext-init"; +import path from "path"; +import type { BunSpawnOptions } from "../../types"; +import writeErrorFile from "../../functions/write-error-file"; export default function () { return new Command("start") .description("Start production server") .action(async () => { - process.env.NODE_ENV = "production"; - log.info("Starting production server ..."); - - await bunextInit(); - - await startServer(); + await start(); }); } + +async function start() { + const dev_spawn_file = path.resolve(__dirname, "prod-spawn.ts"); + + const spawn_options: BunSpawnOptions = { + cmd: ["bun", dev_spawn_file], + stdio: ["inherit", "inherit", "inherit"], + onExit(subprocess, exitCode, signalCode, error) { + writeErrorFile({ exitCode, error }); + }, + env: { + ...process.env, + NODE_ENV: "production", + }, + }; + + let dev_process = Bun.spawn(spawn_options); + + const exited = await dev_process.exited; + + if (exited) { + return await start(); + } +} diff --git a/src/commands/start/prod-spawn.ts b/src/commands/start/prod-spawn.ts new file mode 100644 index 0000000..fa9dd35 --- /dev/null +++ b/src/commands/start/prod-spawn.ts @@ -0,0 +1,9 @@ +import bunextInit from "../../functions/bunext-init"; +import startServer from "../../functions/server/start-server"; +import { log } from "../../utils/log"; + +log.info("Starting production server ..."); + +await bunextInit(); + +await startServer(); diff --git a/src/data/app-data.ts b/src/data/app-data.ts index 424374a..5e285f4 100644 --- a/src/data/app-data.ts +++ b/src/data/app-data.ts @@ -6,4 +6,5 @@ export const AppData = { BunextClientHydrationScriptID: "bunext-client-hydration-script", BunextTmpFileExt: ".bunext_tmp.tsx", BunextHMRRetryRoute: "/.bunext/hmr-retry", + DefaultMaxLogs: 50, } as const; diff --git a/src/functions/bundler/all-pages-esbuild-context-bundler.ts b/src/functions/bundler/all-pages-esbuild-context-bundler.ts index effaf0f..7e90369 100644 --- a/src/functions/bundler/all-pages-esbuild-context-bundler.ts +++ b/src/functions/bundler/all-pages-esbuild-context-bundler.ts @@ -8,8 +8,13 @@ import type { BundlerCTXMap, PageFiles } from "../../types"; import path from "path"; import virtualFilesPlugin from "./plugins/virtual-files-plugin"; import esbuildCTXArtifactTracker from "./plugins/esbuild-ctx-artifact-tracker"; +import { existsSync } from "fs"; -const { HYDRATION_DST_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames(); +const { + HYDRATION_DST_DIR, + BUNX_HYDRATION_SRC_DIR, + BUNX_BUNDLER_ERROR_EXIT_FILE, +} = grabDirNames(); type Params = { post_build_fn?: (params: { @@ -19,6 +24,10 @@ type Params = { export default async function allPagesESBuildContextBundler(params?: Params) { try { + const did_process_exit_because_of_bundler_error = existsSync( + BUNX_BUNDLER_ERROR_EXIT_FILE, + ); + const pages = grabAllPages({ exclude_api: true }); global.PAGE_FILES = pages; @@ -83,6 +92,9 @@ export default async function allPagesESBuildContextBundler(params?: Params) { "react/jsx-runtime", "react/jsx-dev-runtime", ], + logLevel: did_process_exit_because_of_bundler_error + ? "silent" + : undefined, }); await global.BUNDLER_CTX.rebuild(); diff --git a/src/functions/bundler/plugins/esbuild-ctx-artifact-tracker.ts b/src/functions/bundler/plugins/esbuild-ctx-artifact-tracker.ts index 6f46ee8..e0b2f5d 100644 --- a/src/functions/bundler/plugins/esbuild-ctx-artifact-tracker.ts +++ b/src/functions/bundler/plugins/esbuild-ctx-artifact-tracker.ts @@ -5,10 +5,17 @@ import grabArtifactsFromBundledResults from "../grab-artifacts-from-bundled-resu import buildOnstartErrorHandler from "../build-on-start-error-handler"; import _ from "lodash"; import pagesSSRBundler from "../pages-ssr-bundler"; +import grabDirNames from "../../../utils/grab-dir-names"; +import { cpSync, existsSync, mkdirSync, rmSync } from "fs"; +import fullRebuild from "../../server/full-rebuild"; +import path from "path"; +import cleanupLogsDirs from "../../cleanup-logs-dir"; + +const { BUNX_BUNDLER_ERROR_EXIT_FILE, BUNX_ERROR_LOGS_DIR } = grabDirNames(); let build_start = 0; let build_starts = 0; -const MAX_BUILD_STARTS = 5; +const MAX_BUILD_STARTS = 2; type Params = { entryToPage: Map< @@ -31,8 +38,16 @@ export default function esbuildCTXArtifactTracker({ build_starts++; build_start = performance.now(); - if (build_starts == MAX_BUILD_STARTS) { + const does_error_file_exist = existsSync( + BUNX_BUNDLER_ERROR_EXIT_FILE, + ); + + if ( + build_starts == MAX_BUILD_STARTS && + !does_error_file_exist + ) { await buildOnstartErrorHandler(); + process.exit(1); } }); @@ -69,7 +84,22 @@ export default function esbuildCTXArtifactTracker({ build_starts = 0; - pagesSSRBundler(); + const does_error_file_exist = existsSync( + BUNX_BUNDLER_ERROR_EXIT_FILE, + ); + + if (does_error_file_exist) { + mkdirSync(BUNX_ERROR_LOGS_DIR, { recursive: true }); + cpSync( + BUNX_BUNDLER_ERROR_EXIT_FILE, + path.join(BUNX_ERROR_LOGS_DIR, `${Date.now()}.log`), + ); + rmSync(BUNX_BUNDLER_ERROR_EXIT_FILE, { force: true }); + cleanupLogsDirs(); + fullRebuild(); + } else { + pagesSSRBundler(); + } // if (global.SSR_BUNDLER_CTX) { // global.SSR_BUNDLER_CTX.rebuild(); diff --git a/src/functions/bunext-init.ts b/src/functions/bunext-init.ts index 3eeaa85..0bff623 100644 --- a/src/functions/bunext-init.ts +++ b/src/functions/bunext-init.ts @@ -102,9 +102,9 @@ export default async function bunextInit() { } } -process.on("exit", (code) => { - Bun.spawn([process.execPath, ...process.argv.slice(1)], { - stdio: ["inherit", "inherit", "inherit"], - env: process.env, - }); -}); +// process.on("exit", (code) => { +// Bun.spawn([process.execPath, ...process.argv.slice(1)], { +// stdio: ["inherit", "inherit", "inherit"], +// env: process.env, +// }); +// }); diff --git a/src/functions/cleanup-logs-dir.ts b/src/functions/cleanup-logs-dir.ts new file mode 100644 index 0000000..d03326e --- /dev/null +++ b/src/functions/cleanup-logs-dir.ts @@ -0,0 +1,63 @@ +import path from "path"; +import { mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from "fs"; +import grabDirNames from "../utils/grab-dir-names"; +import grabConstants from "../utils/grab-constants"; +import { AppData } from "../data/app-data"; + +const { BUNX_LOGS_DIR } = grabDirNames(); + +export default function cleanupLogsDirs() { + const logs_dirs = readdirSync(BUNX_LOGS_DIR); + const { config } = grabConstants(); + + const MAX_LOGS = config.max_logs || AppData["DefaultMaxLogs"]; + + for (let i = 0; i < logs_dirs.length; i++) { + const dir = logs_dirs[i]; + const full_path = path.join(BUNX_LOGS_DIR, dir); + + const path_stats = statSync(full_path); + + if (!path_stats.isDirectory()) { + continue; + } + + const sub_dir_files = readdirSync(full_path).sort((a, b) => { + const timestamp_a = Number(a.split(".")[0]); + const timestamp_b = Number(b.split(".")[0]); + + if (timestamp_a > timestamp_b) return 1; + return -1; + }); + + for (let j = 0; j < sub_dir_files.length; j++) { + const sub_dir_file = sub_dir_files[j]; + const sub_dir_file_full_path = path.join(full_path, sub_dir_file); + + const sub_dir_file_Stats = statSync(sub_dir_file_full_path); + + if (!sub_dir_file_Stats.isFile()) { + rmSync(sub_dir_file_full_path, { + force: true, + recursive: true, + }); + continue; + } + + if (j > MAX_LOGS - 1) { + rmSync(sub_dir_file_full_path, { force: true }); + } + } + } +} + +// log.info("Running development server ..."); + +// try { +// rmSync(HYDRATION_DST_DIR, { recursive: true }); +// rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); +// } catch (error) {} + +// await bunextInit(); + +// await startServer(); diff --git a/src/functions/process.ts b/src/functions/process.ts new file mode 100644 index 0000000..4f45913 --- /dev/null +++ b/src/functions/process.ts @@ -0,0 +1,53 @@ +import { spawn } from "bun"; + +// Only the "supervisor" respawns. The child sets this env var so it won't respawn itself. +const IS_CHILD = process.env.__RESPAWN_CHILD === "1"; + +let shuttingDown = false; + +async function cleanup() { + // Put real cleanup here: close DB handles, servers, file descriptors, timers, etc. + // Must be awaitable — do NOT rely on process.on("exit") for this. +} + +function respawn(code: number) { + const child = spawn({ + cmd: [process.execPath, ...process.argv.slice(1)], + stdio: ["inherit", "inherit", "inherit"], + env: { ...process.env, __RESPAWN_CHILD: "1" }, + // Detach so the child survives independently and gets its own process group. + // Without this, killing the parent's group can take the child with it. + }); + // Let the child live on its own. + child.unref?.(); +} + +async function shutdown(code: number) { + if (shuttingDown) return; + shuttingDown = true; + + try { + await cleanup(); + } catch (e) { + console.error("cleanup failed:", e); + } + + // Only the supervisor respawns, and only on abnormal exit. + if (!IS_CHILD && code !== 0) { + respawn(code); + } + + process.exit(code); +} + +// Catch the things that actually fire *before* exit, where async works. +process.on("SIGINT", () => shutdown(130)); +process.on("SIGTERM", () => shutdown(143)); +process.on("uncaughtException", (err) => { + console.error(err); + shutdown(1); +}); +process.on("unhandledRejection", (err) => { + console.error(err); + shutdown(1); +}); diff --git a/src/functions/server/full-rebuild.ts b/src/functions/server/full-rebuild.ts index 0d26d5f..902b64f 100644 --- a/src/functions/server/full-rebuild.ts +++ b/src/functions/server/full-rebuild.ts @@ -1,5 +1,6 @@ import { log } from "../../utils/log"; import allPagesESBuildContextBundler from "../bundler/all-pages-esbuild-context-bundler"; +import pagesSSRBundler from "../bundler/pages-ssr-bundler"; import serverPostBuildFn from "./server-post-build-fn"; import watcherEsbuildCTX from "./watcher-esbuild-ctx"; @@ -21,6 +22,8 @@ export default async function fullRebuild(params?: { msg?: string }) { await global.SSR_BUNDLER_CTX?.dispose(); global.SSR_BUNDLER_CTX = undefined; + await pagesSSRBundler(); + allPagesESBuildContextBundler({ post_build_fn: () => { serverPostBuildFn(); diff --git a/src/functions/server/watcher-esbuild-ctx.ts b/src/functions/server/watcher-esbuild-ctx.ts index d445342..2862739 100644 --- a/src/functions/server/watcher-esbuild-ctx.ts +++ b/src/functions/server/watcher-esbuild-ctx.ts @@ -6,7 +6,7 @@ import { AppData } from "../../data/app-data"; import checkExcludedPatterns from "../../utils/check-excluded-patterns"; import pagesSSRBundler from "../bundler/pages-ssr-bundler"; -const { ROOT_DIR } = grabDirNames(); +const { ROOT_DIR, BUNX_BUNDLER_ERROR_EXIT_FILE } = grabDirNames(); export default async function watcherEsbuildCTX() { const pages_src_watcher = watch( @@ -18,6 +18,11 @@ export default async function watcherEsbuildCTX() { async (event, filename) => { if (!filename) return; + if (existsSync(BUNX_BUNDLER_ERROR_EXIT_FILE)) { + await fullRebuild(); + return; + } + if (filename.match(/^\.\w+/)) { return; } diff --git a/src/functions/write-error-file.ts b/src/functions/write-error-file.ts new file mode 100644 index 0000000..20e48e3 --- /dev/null +++ b/src/functions/write-error-file.ts @@ -0,0 +1,34 @@ +import path from "path"; +import { mkdirSync, writeFileSync } from "fs"; +import grabDirNames from "../utils/grab-dir-names"; + +const { BUNX_BUNDLER_ERROR_EXIT_FILE } = grabDirNames(); + +export default function writeErrorFile({ + exitCode, + error, +}: { + error?: Bun.ErrorLike; + exitCode: number | null; +}) { + let txt = ``; + txt += `Bunext Error\n`; + txt += `============================================\n`; + txt += `ERROR: ${error?.message}\n`; + txt += `EXIT_CODE: ${exitCode || 0}\n`; + txt += `CALL_STACK: ${error?.stack}\n`; + + mkdirSync(path.dirname(BUNX_BUNDLER_ERROR_EXIT_FILE), { recursive: true }); + writeFileSync(BUNX_BUNDLER_ERROR_EXIT_FILE, txt); +} + +// log.info("Running development server ..."); + +// try { +// rmSync(HYDRATION_DST_DIR, { recursive: true }); +// rmSync(BUNX_CWD_PAGES_REWRITE_DIR, { recursive: true }); +// } catch (error) {} + +// await bunextInit(); + +// await startServer(); diff --git a/src/types/index.ts b/src/types/index.ts index 7f46aa7..5a2e709 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -70,6 +70,7 @@ export type BunextConfig = { * from the router */ pages_exclude_patterns?: RegExp[]; + max_logs?: number; }; export type BunextConfigMiddlewareParams = { @@ -377,3 +378,11 @@ export type BunextAPIRouteHandler< | Promise> | Response | BunextAPIRouteHandlerObjectReturn; + +export type BunSpawnOptions = Bun.SpawnOptions.SpawnOptions< + "inherit", + "inherit", + "inherit" +> & { + cmd: string[]; +}; diff --git a/src/utils/grab-dir-names.ts b/src/utils/grab-dir-names.ts index 1f2a0b6..2f42024 100644 --- a/src/utils/grab-dir-names.ts +++ b/src/utils/grab-dir-names.ts @@ -15,11 +15,17 @@ export default function grabDirNames() { ); const BUNX_CWD_PAGES_REWRITE_DIR = path.resolve(BUNX_CWD_DIR, "pages"); const BUNX_TMP_DIR = path.resolve(BUNX_CWD_DIR, ".tmp"); + const BUNX_BUNDLER_ERROR_EXIT_FILE = path.resolve( + BUNX_TMP_DIR, + "BUNDLER_EXIT.txt", + ); const BUNX_HYDRATION_SRC_DIR = path.resolve( BUNX_CWD_DIR, "client", "hydration-src", ); + const BUNX_LOGS_DIR = path.resolve(BUNX_CWD_DIR, "logs"); + const BUNX_ERROR_LOGS_DIR = path.resolve(BUNX_LOGS_DIR, "error"); const BUNEXT_PUBLIC_DIR = path.join(BUNX_CWD_DIR, "public"); const HYDRATION_DST_DIR = path.join(BUNEXT_PUBLIC_DIR, "pages"); @@ -46,71 +52,6 @@ export default function grabDirNames() { `${BUNX_ROOT_404_FILE_NAME}.tsx`, ); - // const NODE_MODULES_DIR = path.resolve( - // existsSync(path.join(BUNX_ROOT_DIR, "source.md")) - // ? BUNX_ROOT_DIR - // : ROOT_DIR, - // "node_modules", - // ); - - // const REACT_MODULE_DIR = path.join(NODE_MODULES_DIR, "react"); - // const REACT_DOM_MODULE_DIR = path.join(NODE_MODULES_DIR, "react-dom"); - - // const REACT_PRODUCTION_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react.production.js", - // ); - // const REACT_DEVELOPMENT_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react.development.js", - // ); - - // const REACT_JSX_RUNTIME_PRODUCTION_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-runtime.production.js", - // ); - // const REACT_JSX_RUNTIME_DEVELOPMENT_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-runtime.development.js", - // ); - - // const REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-dev-runtime.production.js", - // ); - // const REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE = path.join( - // REACT_MODULE_DIR, - // "cjs", - // "react-jsx-dev-runtime.development.js", - // ); - - // const REACT_DOM_PRODUCTION_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom.production.js", - // ); - // const REACT_DOM_DEVELOPMENT_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom.development.js", - // ); - - // const REACT_DOM_CLIENT_PRODUCTION_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom-client.production.js", - // ); - // const REACT_DOM_CLIENT_DEVELOPMENT_MODULE = path.join( - // REACT_DOM_MODULE_DIR, - // "cjs", - // "react-dom-client.development.js", - // ); - return { ROOT_DIR, SRC_DIR, @@ -136,18 +77,87 @@ export default function grabDirNames() { HYDRATION_DST_DIR_MAP_JSON_FILE_NAME, BUNEXT_VENDOR_DIR, BUNEXT_PUBLIC_DIR, - // NODE_MODULES_DIR, - // REACT_MODULE_DIR, - // REACT_DOM_MODULE_DIR, - // REACT_PRODUCTION_MODULE, - // REACT_DEVELOPMENT_MODULE, - // REACT_JSX_RUNTIME_PRODUCTION_MODULE, - // REACT_JSX_RUNTIME_DEVELOPMENT_MODULE, - // REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE, - // REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE, - // REACT_DOM_PRODUCTION_MODULE, - // REACT_DOM_DEVELOPMENT_MODULE, - // REACT_DOM_CLIENT_PRODUCTION_MODULE, - // REACT_DOM_CLIENT_DEVELOPMENT_MODULE, + BUNX_BUNDLER_ERROR_EXIT_FILE, + BUNX_ERROR_LOGS_DIR, + BUNX_LOGS_DIR, }; } + +// const NODE_MODULES_DIR = path.resolve( +// existsSync(path.join(BUNX_ROOT_DIR, "source.md")) +// ? BUNX_ROOT_DIR +// : ROOT_DIR, +// "node_modules", +// ); + +// const REACT_MODULE_DIR = path.join(NODE_MODULES_DIR, "react"); +// const REACT_DOM_MODULE_DIR = path.join(NODE_MODULES_DIR, "react-dom"); + +// const REACT_PRODUCTION_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react.production.js", +// ); +// const REACT_DEVELOPMENT_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react.development.js", +// ); + +// const REACT_JSX_RUNTIME_PRODUCTION_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-runtime.production.js", +// ); +// const REACT_JSX_RUNTIME_DEVELOPMENT_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-runtime.development.js", +// ); + +// const REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-dev-runtime.production.js", +// ); +// const REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE = path.join( +// REACT_MODULE_DIR, +// "cjs", +// "react-jsx-dev-runtime.development.js", +// ); + +// const REACT_DOM_PRODUCTION_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom.production.js", +// ); +// const REACT_DOM_DEVELOPMENT_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom.development.js", +// ); + +// const REACT_DOM_CLIENT_PRODUCTION_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom-client.production.js", +// ); +// const REACT_DOM_CLIENT_DEVELOPMENT_MODULE = path.join( +// REACT_DOM_MODULE_DIR, +// "cjs", +// "react-dom-client.development.js", +// ); + +// NODE_MODULES_DIR, +// REACT_MODULE_DIR, +// REACT_DOM_MODULE_DIR, +// REACT_PRODUCTION_MODULE, +// REACT_DEVELOPMENT_MODULE, +// REACT_JSX_RUNTIME_PRODUCTION_MODULE, +// REACT_JSX_RUNTIME_DEVELOPMENT_MODULE, +// REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE, +// REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE, +// REACT_DOM_PRODUCTION_MODULE, +// REACT_DOM_DEVELOPMENT_MODULE, +// REACT_DOM_CLIENT_PRODUCTION_MODULE, +// REACT_DOM_CLIENT_DEVELOPMENT_MODULE,