@pact-toolbox/unplugin
Version:
124 lines (122 loc) • 4.18 kB
JavaScript
import { getNetworkConfig, getSerializableNetworkConfig, resolveConfig } from "@pact-toolbox/config";
import { PactToolboxClient } from "@pact-toolbox/runtime";
import { logger, spinner } from "@pact-toolbox/utils";
import path from "node:path";
import { fork } from "node:child_process";
import { fileURLToPath } from "node:url";
//#region src/next.ts
const GLOBAL_STATE_KEY = Symbol.for("__PACT_TOOLBOX_GLOBAL_STATE__");
function getGlobalState() {
if (!globalThis[GLOBAL_STATE_KEY]) globalThis[GLOBAL_STATE_KEY] = {
isInitialized: false,
isInitializing: false,
initPromise: null,
resolvedConfig: null,
networkConfig: null,
network: null,
client: null,
networkProcess: null,
error: null,
isCleaningUp: false
};
return globalThis[GLOBAL_STATE_KEY];
}
async function initializePactToolbox(options = {}) {
const isDev = process.argv.includes("dev");
const state = getGlobalState();
if (state.isInitialized && !state.error) return;
if (state.isInitializing && state.initPromise) {
await state.initPromise;
return;
}
state.isInitializing = true;
state.error = null;
const initPromise = (async () => {
try {
const { client: passedClient, startNetwork: _startNetwork = true } = options;
const isTest = process.env.NODE_ENV === "test";
if (!state.resolvedConfig) state.resolvedConfig = await resolveConfig();
if (!state.networkConfig) state.networkConfig = getNetworkConfig(state.resolvedConfig);
if (!state.client) state.client = passedClient ?? new PactToolboxClient(state.resolvedConfig);
if (isDev && !isTest) try {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const workerPath = path.resolve(__dirname, "network-worker.js");
state.networkProcess = fork(workerPath, [], {
detached: true,
stdio: "inherit"
});
state.networkProcess.on("error", (err) => {
logger.error("Network worker process error:", err);
});
} catch (error) {
logger.error("[withPactToolbox] Error starting network:", error);
state.error = error instanceof Error ? error : new Error(String(error));
}
state.isInitialized = true;
} catch (error) {
state.error = error instanceof Error ? error : new Error(String(error));
logger.error("[withPactToolbox] Initialization failed:", state.error);
throw state.error;
} finally {
state.isInitializing = false;
state.initPromise = null;
}
})();
state.initPromise = initPromise;
await initPromise;
}
function withPactToolbox(options = {}) {
return async (nextConfig = {}) => {
try {
await initializePactToolbox(options);
const state = getGlobalState();
if (!state.resolvedConfig) throw new Error("Failed to resolve Pact Toolbox configuration");
const rules = { "*.pact": {
loaders: ["@pact-toolbox/unplugin/loader"],
as: "*.js"
} };
const enhancedConfig = {
...nextConfig,
compiler: {
...nextConfig.compiler,
define: {
...nextConfig.compiler?.define,
"globalThis.__PACT_TOOLBOX_NETWORK_CONFIG__": JSON.stringify(getSerializableNetworkConfig(state.resolvedConfig))
}
},
turbopack: {
...nextConfig.turbopack,
rules: {
...nextConfig.turbopack?.rules,
...rules
}
}
};
const handleShutdown = async (signal) => {
const state$1 = getGlobalState();
if (state$1.isCleaningUp) return;
state$1.isCleaningUp = true;
const shutdownSpinner = spinner({ indicator: "timer" });
shutdownSpinner.start(`\n${signal} received. Shutting down network...`);
try {
if (state$1.networkProcess) state$1.networkProcess.kill();
await state$1.network?.stop();
} catch (error) {
console.error(`Error during graceful shutdown:`, error);
}
process.exit(0);
};
process.on("SIGINT", () => handleShutdown("SIGINT"));
process.on("SIGTERM", () => handleShutdown("SIGTERM"));
return enhancedConfig;
} catch (error) {
logger.error("[withPactToolbox] Failed to enhance Next.js configuration:", error);
return nextConfig;
}
};
}
var next_default = withPactToolbox;
//#endregion
export { next_default as default };
//# sourceMappingURL=next.js.map