Files
bunext/dist/functions/server/full-rebuild.js
T
2026-10-02 07:04:22 +01:00

58 lines
2.1 KiB
JavaScript

import { log } from "../../utils/log";
import allPagesESBuildContextBundler from "../bundler/all-pages-esbuild-context-bundler";
import serverPostBuildFn from "./server-post-build-fn";
import { restartWatcher } from "./watcher-esbuild-ctx";
import { logBuildErrorsOnce } from "../../utils/build-error-log";
// Single-flight: error recovery paths (grab-page-component retries, the
// watcher, post-build HMR pushes) all call fullRebuild, and each rebuild
// triggers serverPostBuildFn which can re-enter error handling. Without this
// guard one broken page could fan out into cascading, overlapping rebuilds
// that leave the dev server unresponsive. Concurrent callers await the same
// in-flight rebuild instead of starting a new one.
let rebuild_in_progress;
export default async function fullRebuild(params) {
if (rebuild_in_progress) {
if (params?.msg) {
log.watch(`Rebuild already in progress, skipping: ${params.msg}`);
}
return rebuild_in_progress;
}
const run = doFullRebuild(params).finally(() => {
if (rebuild_in_progress === run) {
rebuild_in_progress = undefined;
}
});
rebuild_in_progress = run;
return run;
}
async function doFullRebuild(params) {
try {
const { msg } = params || {};
global.BUNEXT_RECOMPILING = true;
if (msg) {
log.watch(msg);
}
global.BUNEXT_ROUTER.reload();
try {
await global.BUNEXT_BUNDLER_CTX?.dispose();
global.BUNEXT_BUNDLER_CTX = undefined;
await global.BUNEXT_SSR_BUNDLER_CTX?.dispose();
global.BUNEXT_SSR_BUNDLER_CTX = undefined;
}
catch (error) { }
await allPagesESBuildContextBundler({
post_build_fn: async () => {
await serverPostBuildFn();
},
});
}
catch (error) {
logBuildErrorsOnce([{ text: error?.message || String(error) }], (line) => log.error(line));
}
finally {
global.BUNEXT_RECOMPILING = false;
global.BUNEXT_IS_SERVER_COMPONENT = false;
}
restartWatcher();
}