feat: add script hot-reload and compile-on-save

This commit is contained in:
plenarius
2026-04-20 19:50:39 -04:00
parent 59909a7b48
commit 5c840e324b
2 changed files with 77 additions and 1 deletions
+25 -1
View File
@@ -1,5 +1,9 @@
import { Router } from "express"; import { Router } from "express";
import { buildModule } from "../services/build.service.js"; import {
buildModule,
hotReloadScripts,
compileSingle,
} from "../services/build.service.js";
const router = Router(); const router = Router();
@@ -23,4 +27,24 @@ router.post("/module/pack", async (req, res) => {
} }
}); });
router.post("/deploy", async (_req, res) => {
try {
const result = await hotReloadScripts();
res.json(result);
} catch (err: any) {
res.status(500).json({ error: err.message });
}
});
router.post("/compile-single", async (req, res) => {
const { filePath } = req.body;
if (!filePath) return res.status(400).json({ error: "filePath required" });
try {
const result = await compileSingle(filePath);
res.json(result);
} catch (err: any) {
res.status(500).json({ error: err.message });
}
});
export default router; export default router;
@@ -1,3 +1,5 @@
import fs from "fs/promises";
import path from "path";
import { runEphemeralContainer } from "./docker.service.js"; import { runEphemeralContainer } from "./docker.service.js";
import { import {
getWorkspacePath, getWorkspacePath,
@@ -41,3 +43,53 @@ export async function buildModule(
return { success, output: result.output }; return { success, output: result.output };
} }
export async function hotReloadScripts(): Promise<{
success: boolean;
output: string;
scripts: string[];
}> {
const workspacePath = getWorkspacePath();
broadcast("build", "start", { type: "hot-reload" });
const result = await buildModule("bare", "compile");
if (!result.success) {
return { success: false, output: result.output, scripts: [] };
}
const cacheDir = path.join(
workspacePath,
"repos/nwn-module/.nasher/cache/bare",
);
const devDir = getServerPath("development");
let scripts: string[] = [];
try {
const files = await fs.readdir(cacheDir);
const ncsFiles = files.filter((f) => f.endsWith(".ncs"));
await fs.mkdir(devDir, { recursive: true });
for (const ncs of ncsFiles) {
await fs.copyFile(path.join(cacheDir, ncs), path.join(devDir, ncs));
scripts.push(ncs);
}
} catch {
// cache dir may not exist yet
}
broadcast("build", "complete", { type: "hot-reload", scripts });
return { success: true, output: result.output, scripts };
}
export async function compileSingle(
filePath: string,
): Promise<{ success: boolean; errors: string[] }> {
const result = await buildModule("bare", "compile");
const errors = result.output
.split("\n")
.filter((line) => line.toLowerCase().includes("error"))
.map((line) => line.trim());
return { success: result.success, errors };
}