// write-server.js - Manage the Write (Next.js) and Hugo processes const { spawn, execSync } = require("child_process"); const config = require("./config"); const { waitForReady } = require("./helpers"); let writeProcess = null; let writeReady = false; let hugoProcess = null; function startWriteServer() { if (writeProcess) { return { started: false, reason: writeReady ? "already_running" : "starting" }; } writeReady = false; const isWin = process.platform === "win32"; writeProcess = spawn( isWin ? "npm.cmd" : "npm", ["run", "dev", "--", "-p", String(config.WRITE_PORT), "-H", "0.0.0.0"], { cwd: config.WRITE_DIR, shell: isWin, stdio: "pipe", windowsHide: true } ); writeProcess.stdout?.on("data", (d) => process.stdout.write(d)); writeProcess.stderr?.on("data", (d) => process.stderr.write(d)); writeProcess.on("exit", (code) => { console.log("[write] exited " + code); writeProcess = null; writeReady = false; }); return { started: true }; } function stopWriteServer() { if (hugoProcess) { try { const hpid = hugoProcess.pid; if (process.platform === "win32" && hpid) { execSync("taskkill /PID " + hpid + " /T /F", { stdio: "ignore" }); } else { hugoProcess.kill(); } } catch {} hugoProcess = null; } if (!writeProcess) return false; const pid = writeProcess.pid; try { if (process.platform === "win32" && pid) { execSync("taskkill /PID " + pid + " /T /F", { stdio: "ignore" }); } else { writeProcess.kill(); } } catch {} writeProcess = null; writeReady = false; return true; } function startHugoIfNeeded() { if (hugoProcess) return; try { hugoProcess = spawn("hugo", ["server", "--bind", "0.0.0.0", "--port", "1313", "--disableFastRender"], { cwd: config.WRITE_DIR + "/..", shell: true, stdio: "pipe", windowsHide: true, }); hugoProcess.on("exit", (code) => { console.log("[hugo] exited " + code); hugoProcess = null; }); console.log("[hugo] started on 0.0.0.0:1313"); } catch (e) { console.error("[hugo]", e.message); } } function getWriteStatus() { return { running: !!(writeProcess && writeReady), starting: !!(writeProcess && !writeReady), }; } async function ensureWriteReady(chatId, sendMessage) { if (writeProcess && writeReady) { startHugoIfNeeded(); return true; } if (writeProcess && !writeReady) { await sendMessage(chatId, "\\u231B Write \\u6B63\\u5728\\u542F\\u52A8\\u4E2D..."); const ready = await waitForReady(config.WRITE_PORT); if (ready) { writeReady = true; startHugoIfNeeded(); return true; } return false; } const result = startWriteServer(); if (!result.started) return false; await sendMessage(chatId, "\\u231B \\u6B63\\u5728\\u542F\\u52A8 Write..."); const ready = await waitForReady(config.WRITE_PORT); if (ready) { writeReady = true; startHugoIfNeeded(); return true; } return false; } module.exports = { get writeReady() { return writeReady; }, get writePort() { return config.WRITE_PORT; }, startWriteServer, stopWriteServer, startHugoIfNeeded, getWriteStatus, ensureWriteReady, };