refactor(cleanup): completar fase 5 con renombrados semánticos

This commit is contained in:
Pandipipas
2026-02-21 18:55:30 +01:00
parent 8047c99946
commit 710fea38c0
7 changed files with 114 additions and 113 deletions
+4 -4
View File
@@ -4,8 +4,8 @@ export type AppRuntimeConfig = {
iconPathOverride?: string; iconPathOverride?: string;
nodecgPort: string; nodecgPort: string;
bundleName: string; bundleName: string;
dashboardRoute: string; mainDashboardRoute: string;
loadingRoute: string; loadingDashboardRoute: string;
loadDelayMs: number; loadDelayMs: number;
startupTimeoutMs: number; startupTimeoutMs: number;
nodecgKillTimeoutMs: number; nodecgKillTimeoutMs: number;
@@ -21,8 +21,8 @@ export function getRuntimeConfig(): AppRuntimeConfig {
iconPathOverride: getOptionalEnv("SCOREKO_APP_ICON_PATH"), iconPathOverride: getOptionalEnv("SCOREKO_APP_ICON_PATH"),
nodecgPort: parseEnvPort("NODECG_PORT", "9090"), nodecgPort: parseEnvPort("NODECG_PORT", "9090"),
bundleName: getEnv("NODECG_BUNDLE_NAME", "scoreko-dev"), bundleName: getEnv("NODECG_BUNDLE_NAME", "scoreko-dev"),
dashboardRoute: getEnv("SCOREKO_DASHBOARD_ROUTE", "dashboard/scoreko-dev/main.html?standalone=true"), mainDashboardRoute: getEnv("SCOREKO_DASHBOARD_ROUTE", "dashboard/scoreko-dev/main.html?standalone=true"),
loadingRoute: getEnv("SCOREKO_LOADING_ROUTE", "dashboard/loading/main.html?standalone=true"), loadingDashboardRoute: getEnv("SCOREKO_LOADING_ROUTE", "dashboard/loading/main.html?standalone=true"),
loadDelayMs: parseEnvIntInRange("ELECTRON_LOAD_DELAY_MS", 10000, 0, 600000), loadDelayMs: parseEnvIntInRange("ELECTRON_LOAD_DELAY_MS", 10000, 0, 600000),
startupTimeoutMs: parseEnvIntInRange("NODECG_STARTUP_TIMEOUT_MS", 30000, 1000, 600000), startupTimeoutMs: parseEnvIntInRange("NODECG_STARTUP_TIMEOUT_MS", 30000, 1000, 600000),
nodecgKillTimeoutMs: parseEnvIntInRange("NODECG_KILL_TIMEOUT_MS", 2500, 0, 120000), nodecgKillTimeoutMs: parseEnvIntInRange("NODECG_KILL_TIMEOUT_MS", 2500, 0, 120000),
+23 -23
View File
@@ -7,20 +7,20 @@ import { createNodecgProcessManager } from "./nodecg/process-manager";
import { getRemainingDelayMs } from "./utils/timing"; import { getRemainingDelayMs } from "./utils/timing";
import { createLoadingWindow, createMainWindow } from "./windows/window-factory"; import { createLoadingWindow, createMainWindow } from "./windows/window-factory";
const runtimeConfig = getRuntimeConfig(); const appConfig = getRuntimeConfig();
const isDev = !app.isPackaged; const isDev = !app.isPackaged;
const rootPath = isDev ? path.resolve(__dirname, "../..") : process.resourcesPath; const rootPath = isDev ? path.resolve(__dirname, "../..") : process.resourcesPath;
const nodecgPath = path.resolve(rootPath, "lib", "nodecg"); const nodecgRootPath = path.resolve(rootPath, "lib", "nodecg");
const dashboardUrl = `http://localhost:${runtimeConfig.nodecgPort}/bundles/${runtimeConfig.bundleName}/${runtimeConfig.dashboardRoute}`; const mainDashboardUrl = `http://localhost:${appConfig.nodecgPort}/bundles/${appConfig.bundleName}/${appConfig.mainDashboardRoute}`;
const loadingUrl = `http://localhost:${runtimeConfig.nodecgPort}/bundles/${runtimeConfig.bundleName}/${runtimeConfig.loadingRoute}`; const loadingDashboardUrl = `http://localhost:${appConfig.nodecgPort}/bundles/${appConfig.bundleName}/${appConfig.loadingDashboardRoute}`;
const baseUrl = `http://127.0.0.1:${runtimeConfig.nodecgPort}`; const nodecgBaseUrl = `http://127.0.0.1:${appConfig.nodecgPort}`;
const nodecgManager = createNodecgProcessManager({ const nodecgManager = createNodecgProcessManager({
isDev, isDev,
nodecgPath, nodecgRootPath,
baseUrl, nodecgBaseUrl,
runtimeConfig, appConfig,
log, log,
}); });
@@ -30,19 +30,19 @@ let mainWindow: BrowserWindow | null = null;
let loadingWindow: BrowserWindow | null = null; let loadingWindow: BrowserWindow | null = null;
let shutdownState: AppShutdownState = "running"; let shutdownState: AppShutdownState = "running";
async function launch(): Promise<void> { async function launchApplication(): Promise<void> {
mainWindow = createMainWindow({ runtimeConfig, rootPath, dashboardUrl }); mainWindow = createMainWindow({ appConfig, rootPath, mainDashboardUrl });
loadingWindow = createLoadingWindow({ runtimeConfig, rootPath }); loadingWindow = createLoadingWindow({ appConfig, rootPath });
nodecgManager.startNodeCG(); nodecgManager.startNodecgProcess();
await nodecgManager.waitForNodeCGReady(Date.now()); await nodecgManager.waitForNodecgReady(Date.now());
if (!loadingWindow || loadingWindow.isDestroyed()) { if (!loadingWindow || loadingWindow.isDestroyed()) {
return; return;
} }
await loadingWindow.loadURL(loadingUrl); await loadingWindow.loadURL(loadingDashboardUrl);
loadingWindow.show(); loadingWindow.show();
const loadingShownAt = Date.now(); const loadingShownAt = Date.now();
@@ -51,9 +51,9 @@ async function launch(): Promise<void> {
return; return;
} }
await mainWindow.loadURL(dashboardUrl); await mainWindow.loadURL(mainDashboardUrl);
const remainingLoadingDelay = getRemainingDelayMs(runtimeConfig.loadDelayMs, loadingShownAt); const remainingLoadingDelay = getRemainingDelayMs(appConfig.loadDelayMs, loadingShownAt);
if (remainingLoadingDelay > 0) { if (remainingLoadingDelay > 0) {
await sleep(remainingLoadingDelay); await sleep(remainingLoadingDelay);
} }
@@ -83,24 +83,24 @@ function stopNodecgGracefully(): Promise<void> {
} }
if (shutdownState === "stopping") { if (shutdownState === "stopping") {
return nodecgManager.stopNodeCG(); return nodecgManager.stopNodecgProcessGracefully();
} }
shutdownState = "stopping"; shutdownState = "stopping";
return nodecgManager.stopNodeCG().finally(() => { return nodecgManager.stopNodecgProcessGracefully().finally(() => {
shutdownState = "stopped"; shutdownState = "stopped";
}); });
} }
app.on("ready", () => { app.on("ready", () => {
app.setName(runtimeConfig.title); app.setName(appConfig.title);
if (process.platform === "win32") { if (process.platform === "win32") {
app.setAppUserModelId(runtimeConfig.userModelId); app.setAppUserModelId(appConfig.userModelId);
} }
launch().catch((error: unknown) => { launchApplication().catch((error: unknown) => {
showFatalError("No se pudo iniciar Scoreko.", error); showFatalError("No se pudo iniciar Scoreko.", error);
closeLoadingWindow(); closeLoadingWindow();
app.exit(1); app.exit(1);
@@ -109,8 +109,8 @@ app.on("ready", () => {
app.on("activate", async () => { app.on("activate", async () => {
if (BrowserWindow.getAllWindows().length === 0) { if (BrowserWindow.getAllWindows().length === 0) {
mainWindow = createMainWindow({ runtimeConfig, rootPath, dashboardUrl }); mainWindow = createMainWindow({ appConfig, rootPath, mainDashboardUrl });
await mainWindow.loadURL(dashboardUrl); await mainWindow.loadURL(mainDashboardUrl);
mainWindow.show(); mainWindow.show();
} }
}); });
+39 -38
View File
@@ -7,9 +7,9 @@ import { NODE_RUNTIME_NAME } from "../constants";
type NodecgProcessManagerConfig = { type NodecgProcessManagerConfig = {
isDev: boolean; isDev: boolean;
nodecgPath: string; nodecgRootPath: string;
baseUrl: string; nodecgBaseUrl: string;
runtimeConfig: AppRuntimeConfig; appConfig: AppRuntimeConfig;
log: (...args: unknown[]) => void; log: (...args: unknown[]) => void;
deps?: Partial<NodecgProcessManagerDeps>; deps?: Partial<NodecgProcessManagerDeps>;
}; };
@@ -28,35 +28,35 @@ type NodecgProcessManagerDeps = {
}; };
export type NodecgProcessManager = { export type NodecgProcessManager = {
startNodeCG: () => ChildProcess; startNodecgProcess: () => ChildProcess;
waitForNodeCGReady: (startTime: number) => Promise<void>; waitForNodecgReady: (startTime: number) => Promise<void>;
stopNodeCG: () => Promise<void>; stopNodecgProcessGracefully: () => Promise<void>;
getProcess: () => ChildProcess | null; getProcess: () => ChildProcess | null;
}; };
export function createNodecgProcessManager({ export function createNodecgProcessManager({
isDev, isDev,
nodecgPath, nodecgRootPath,
baseUrl, nodecgBaseUrl,
runtimeConfig, appConfig,
log, log,
deps, deps,
}: NodecgProcessManagerConfig): NodecgProcessManager { }: NodecgProcessManagerConfig): NodecgProcessManager {
const resolvedDeps = resolveDeps(deps); const resolvedDeps = resolveDeps(deps);
let nodecgProcess: ChildProcess | null = null; let nodecgProcess: ChildProcess | null = null;
let stopNodeCGPromise: Promise<void> | null = null; let stopNodecgPromise: Promise<void> | null = null;
const startNodeCG = (): ChildProcess => { const startNodecgProcess = (): ChildProcess => {
validateNodeCGInstall(nodecgPath, runtimeConfig.bundleName, resolvedDeps.pathExists); validateNodecgInstall(nodecgRootPath, appConfig.bundleName, resolvedDeps.pathExists);
const indexPath = path.join(nodecgPath, "index.js"); const indexPath = path.join(nodecgRootPath, "index.js");
const child = resolvedDeps.spawnProcess(resolvedDeps.execPath, [indexPath], { const child = resolvedDeps.spawnProcess(resolvedDeps.execPath, [indexPath], {
cwd: nodecgPath, cwd: nodecgRootPath,
env: { env: {
...resolvedDeps.env, ...resolvedDeps.env,
NODE_ENV: isDev ? "development" : "production", NODE_ENV: isDev ? "development" : "production",
NODECG_PORT: runtimeConfig.nodecgPort, NODECG_PORT: appConfig.nodecgPort,
ELECTRON_RUN_AS_NODE: "1", ELECTRON_RUN_AS_NODE: "1",
}, },
stdio: ["ignore", "pipe", "pipe"], stdio: ["ignore", "pipe", "pipe"],
@@ -83,14 +83,14 @@ export function createNodecgProcessManager({
return child; return child;
}; };
const waitForNodeCGReady = async (startTime: number): Promise<void> => { const waitForNodecgReady = async (startTime: number): Promise<void> => {
while (Date.now() - startTime < runtimeConfig.startupTimeoutMs) { while (Date.now() - startTime < appConfig.startupTimeoutMs) {
if (!nodecgProcess) { if (!nodecgProcess) {
throw new Error("NodeCG terminó antes de estar listo."); throw new Error("NodeCG terminó antes de estar listo.");
} }
try { try {
const response = await resolvedDeps.fetchUrl(baseUrl, { method: "GET" }); const response = await resolvedDeps.fetchUrl(nodecgBaseUrl, { method: "GET" });
if (response.ok || response.status === 404) { if (response.ok || response.status === 404) {
return; return;
} }
@@ -101,12 +101,12 @@ export function createNodecgProcessManager({
await sleep(500, resolvedDeps.setTimer); await sleep(500, resolvedDeps.setTimer);
} }
throw new Error(`Timeout esperando NodeCG en ${baseUrl} (${runtimeConfig.startupTimeoutMs}ms).`); throw new Error(`Timeout esperando NodeCG en ${nodecgBaseUrl} (${appConfig.startupTimeoutMs}ms).`);
}; };
const stopNodeCG = (): Promise<void> => { const stopNodecgProcessGracefully = (): Promise<void> => {
if (stopNodeCGPromise) { if (stopNodecgPromise) {
return stopNodeCGPromise; return stopNodecgPromise;
} }
if (!nodecgProcess || nodecgProcess.killed) { if (!nodecgProcess || nodecgProcess.killed) {
@@ -122,14 +122,15 @@ export function createNodecgProcessManager({
} }
log(`Stopping NodeCG pid=${pid}`); log(`Stopping NodeCG pid=${pid}`);
killNodeCGProcessTree(pid, "SIGTERM", log, resolvedDeps); killNodecgProcessTree(pid, "SIGTERM", log, resolvedDeps);
stopNodeCGPromise = new Promise((resolve) => { stopNodecgPromise = new Promise((resolve) => {
const complete = () => { const complete = () => {
if (nodecgProcess === processToStop) { if (nodecgProcess === processToStop) {
nodecgProcess = null; nodecgProcess = null;
} }
stopNodeCGPromise = null;
stopNodecgPromise = null;
resolve(); resolve();
}; };
@@ -140,18 +141,18 @@ export function createNodecgProcessManager({
resolvedDeps.setTimer(() => { resolvedDeps.setTimer(() => {
if (processToStop.exitCode === null && processToStop.signalCode === null) { if (processToStop.exitCode === null && processToStop.signalCode === null) {
log(`NodeCG did not exit after SIGTERM, forcing SIGKILL pid=${pid}`); log(`NodeCG did not exit after SIGTERM, forcing SIGKILL pid=${pid}`);
killNodeCGProcessTree(pid, "SIGKILL", log, resolvedDeps); killNodecgProcessTree(pid, "SIGKILL", log, resolvedDeps);
} }
}, Math.max(0, runtimeConfig.nodecgKillTimeoutMs)); }, Math.max(0, appConfig.nodecgKillTimeoutMs));
}); });
return stopNodeCGPromise; return stopNodecgPromise;
}; };
return { return {
startNodeCG, startNodecgProcess,
waitForNodeCGReady, waitForNodecgReady,
stopNodeCG, stopNodecgProcessGracefully,
getProcess: () => nodecgProcess, getProcess: () => nodecgProcess,
}; };
} }
@@ -171,13 +172,13 @@ function resolveDeps(deps?: Partial<NodecgProcessManagerDeps>): NodecgProcessMan
}; };
} }
function validateNodeCGInstall(nodecgPath: string, bundleName: string, pathExists: (candidatePath: string) => boolean): void { function validateNodecgInstall(nodecgRootPath: string, bundleName: string, pathExists: (candidatePath: string) => boolean): void {
const indexPath = path.join(nodecgPath, "index.js"); const indexPath = path.join(nodecgRootPath, "index.js");
const nodecgBootstrapPath = path.join(nodecgPath, "node_modules", "nodecg", "dist", "server", "bootstrap.js"); const nodecgBootstrapPath = path.join(nodecgRootPath, "node_modules", "nodecg", "dist", "server", "bootstrap.js");
const bundlePath = path.join(nodecgPath, "bundles", bundleName); const bundlePath = path.join(nodecgRootPath, "bundles", bundleName);
if (!pathExists(nodecgPath)) { if (!pathExists(nodecgRootPath)) {
throw new Error(`No existe la carpeta NodeCG: ${nodecgPath}`); throw new Error(`No existe la carpeta NodeCG: ${nodecgRootPath}`);
} }
if (!pathExists(indexPath)) { if (!pathExists(indexPath)) {
@@ -206,7 +207,7 @@ function validateNodeCGInstall(nodecgPath: string, bundleName: string, pathExist
} }
} }
function killNodeCGProcessTree( function killNodecgProcessTree(
pid: number, pid: number,
signal: NodeJS.Signals, signal: NodeJS.Signals,
log: (...args: unknown[]) => void, log: (...args: unknown[]) => void,
+2 -2
View File
@@ -4,12 +4,12 @@ import path from "node:path";
import { AppRuntimeConfig } from "../config/runtime-config"; import { AppRuntimeConfig } from "../config/runtime-config";
export function resolveAppIconPath( export function resolveAppIconPath(
runtimeConfig: AppRuntimeConfig, appConfig: AppRuntimeConfig,
rootPath: string, rootPath: string,
pathExists: (candidatePath: string) => boolean = fs.existsSync, pathExists: (candidatePath: string) => boolean = fs.existsSync,
): string | undefined { ): string | undefined {
const iconCandidates = [ const iconCandidates = [
runtimeConfig.iconPathOverride, appConfig.iconPathOverride,
path.join(rootPath, "static", "icons", "icon.ico"), path.join(rootPath, "static", "icons", "icon.ico"),
path.join(rootPath, "static", "icons", "icon.png"), path.join(rootPath, "static", "icons", "icon.png"),
path.join(rootPath, "static", "icon.ico"), path.join(rootPath, "static", "icon.ico"),
+11 -11
View File
@@ -5,13 +5,13 @@ import { resolveAppIconPath } from "./icon-path";
import { shouldAllowInternalNavigation, shouldOpenExternalNavigation } from "./navigation-security"; import { shouldAllowInternalNavigation, shouldOpenExternalNavigation } from "./navigation-security";
type WindowFactoryDependencies = { type WindowFactoryDependencies = {
runtimeConfig: AppRuntimeConfig; appConfig: AppRuntimeConfig;
rootPath: string; rootPath: string;
dashboardUrl: string; mainDashboardUrl: string;
}; };
export function createMainWindow({ runtimeConfig, rootPath, dashboardUrl }: WindowFactoryDependencies): BrowserWindow { export function createMainWindow({ appConfig, rootPath, mainDashboardUrl }: WindowFactoryDependencies): BrowserWindow {
const windowOptions = createWindowOptions({ runtimeConfig, rootPath, isLoadingWindow: false }); const windowOptions = createWindowOptions({ appConfig, rootPath, isLoadingWindow: false });
const window = new BrowserWindow(windowOptions); const window = new BrowserWindow(windowOptions);
window.setMenuBarVisibility(false); window.setMenuBarVisibility(false);
@@ -25,7 +25,7 @@ export function createMainWindow({ runtimeConfig, rootPath, dashboardUrl }: Wind
}); });
window.webContents.on("will-navigate", (event, url) => { window.webContents.on("will-navigate", (event, url) => {
if (shouldAllowInternalNavigation(url, dashboardUrl)) { if (shouldAllowInternalNavigation(url, mainDashboardUrl)) {
return; return;
} }
@@ -43,8 +43,8 @@ export function createMainWindow({ runtimeConfig, rootPath, dashboardUrl }: Wind
return window; return window;
} }
export function createLoadingWindow({ runtimeConfig, rootPath }: Omit<WindowFactoryDependencies, "dashboardUrl">): BrowserWindow { export function createLoadingWindow({ appConfig, rootPath }: Omit<WindowFactoryDependencies, "mainDashboardUrl">): BrowserWindow {
const window = new BrowserWindow(createWindowOptions({ runtimeConfig, rootPath, isLoadingWindow: true })); const window = new BrowserWindow(createWindowOptions({ appConfig, rootPath, isLoadingWindow: true }));
window.on("page-title-updated", (event) => { window.on("page-title-updated", (event) => {
event.preventDefault(); event.preventDefault();
@@ -54,19 +54,19 @@ export function createLoadingWindow({ runtimeConfig, rootPath }: Omit<WindowFact
} }
function createWindowOptions({ function createWindowOptions({
runtimeConfig, appConfig,
rootPath, rootPath,
isLoadingWindow, isLoadingWindow,
}: { }: {
runtimeConfig: AppRuntimeConfig; appConfig: AppRuntimeConfig;
rootPath: string; rootPath: string;
isLoadingWindow: boolean; isLoadingWindow: boolean;
}): BrowserWindowConstructorOptions { }): BrowserWindowConstructorOptions {
const iconPath = resolveAppIconPath(runtimeConfig, rootPath); const iconPath = resolveAppIconPath(appConfig, rootPath);
const baseOptions: BrowserWindowConstructorOptions = { const baseOptions: BrowserWindowConstructorOptions = {
show: false, show: false,
title: runtimeConfig.title, title: appConfig.title,
...(iconPath ? { icon: iconPath } : {}), ...(iconPath ? { icon: iconPath } : {}),
backgroundColor: DEFAULT_WINDOW_BACKGROUND, backgroundColor: DEFAULT_WINDOW_BACKGROUND,
webPreferences: { webPreferences: {
+8 -8
View File
@@ -10,8 +10,8 @@ function getBaseConfig(): AppRuntimeConfig {
userModelId: "com.scoreko.desktop", userModelId: "com.scoreko.desktop",
nodecgPort: "9090", nodecgPort: "9090",
bundleName: "scoreko-dev", bundleName: "scoreko-dev",
dashboardRoute: "dashboard/scoreko-dev/main.html?standalone=true", mainDashboardRoute: "dashboard/scoreko-dev/main.html?standalone=true",
loadingRoute: "dashboard/loading/main.html?standalone=true", loadingDashboardRoute: "dashboard/loading/main.html?standalone=true",
loadDelayMs: 10000, loadDelayMs: 10000,
startupTimeoutMs: 30000, startupTimeoutMs: 30000,
nodecgKillTimeoutMs: 2500, nodecgKillTimeoutMs: 2500,
@@ -19,28 +19,28 @@ function getBaseConfig(): AppRuntimeConfig {
} }
test("resolveAppIconPath prioriza iconPathOverride cuando existe", () => { test("resolveAppIconPath prioriza iconPathOverride cuando existe", () => {
const runtimeConfig: AppRuntimeConfig = { const appConfig: AppRuntimeConfig = {
...getBaseConfig(), ...getBaseConfig(),
iconPathOverride: "/custom/icon.ico", iconPathOverride: "/custom/icon.ico",
}; };
const iconPath = resolveAppIconPath(runtimeConfig, "/app", (candidate) => candidate === "/custom/icon.ico"); const iconPath = resolveAppIconPath(appConfig, "/app", (candidate) => candidate === "/custom/icon.ico");
assert.equal(iconPath, "/custom/icon.ico"); assert.equal(iconPath, "/custom/icon.ico");
}); });
test("resolveAppIconPath cae al primer icono por defecto existente", () => { test("resolveAppIconPath cae al primer icono por defecto existente", () => {
const runtimeConfig = getBaseConfig(); const appConfig = getBaseConfig();
const iconPath = resolveAppIconPath(runtimeConfig, "/app", (candidate) => candidate === "/app/static/icons/icon.png"); const iconPath = resolveAppIconPath(appConfig, "/app", (candidate) => candidate === "/app/static/icons/icon.png");
assert.equal(iconPath, "/app/static/icons/icon.png"); assert.equal(iconPath, "/app/static/icons/icon.png");
}); });
test("resolveAppIconPath devuelve undefined cuando no hay iconos", () => { test("resolveAppIconPath devuelve undefined cuando no hay iconos", () => {
const runtimeConfig = getBaseConfig(); const appConfig = getBaseConfig();
const iconPath = resolveAppIconPath(runtimeConfig, "/app", () => false); const iconPath = resolveAppIconPath(appConfig, "/app", () => false);
assert.equal(iconPath, undefined); assert.equal(iconPath, undefined);
}); });
+27 -27
View File
@@ -23,8 +23,8 @@ function getBaseConfig(): AppRuntimeConfig {
userModelId: "com.scoreko.desktop", userModelId: "com.scoreko.desktop",
nodecgPort: "9090", nodecgPort: "9090",
bundleName: "scoreko-dev", bundleName: "scoreko-dev",
dashboardRoute: "dashboard/scoreko-dev/main.html?standalone=true", mainDashboardRoute: "dashboard/scoreko-dev/main.html?standalone=true",
loadingRoute: "dashboard/loading/main.html?standalone=true", loadingDashboardRoute: "dashboard/loading/main.html?standalone=true",
loadDelayMs: 10000, loadDelayMs: 10000,
startupTimeoutMs: 100, startupTimeoutMs: 100,
nodecgKillTimeoutMs: 10, nodecgKillTimeoutMs: 10,
@@ -34,9 +34,9 @@ function getBaseConfig(): AppRuntimeConfig {
test("startNodeCG valida instalación de NodeCG antes de arrancar", () => { test("startNodeCG valida instalación de NodeCG antes de arrancar", () => {
const manager = createNodecgProcessManager({ const manager = createNodecgProcessManager({
isDev: true, isDev: true,
nodecgPath: "/fake/nodecg", nodecgRootPath: "/fake/nodecg",
baseUrl: "http://127.0.0.1:9090", nodecgBaseUrl: "http://127.0.0.1:9090",
runtimeConfig: getBaseConfig(), appConfig: getBaseConfig(),
log: () => undefined, log: () => undefined,
deps: { deps: {
pathExists: () => false, pathExists: () => false,
@@ -47,7 +47,7 @@ test("startNodeCG valida instalación de NodeCG antes de arrancar", () => {
}); });
assert.throws(() => { assert.throws(() => {
manager.startNodeCG(); manager.startNodecgProcess();
}, /No existe la carpeta NodeCG/); }, /No existe la carpeta NodeCG/);
}); });
@@ -55,9 +55,9 @@ test("waitForNodeCGReady resuelve cuando el endpoint responde 404", async () =>
const child = new MockChildProcess(4321); const child = new MockChildProcess(4321);
const manager = createNodecgProcessManager({ const manager = createNodecgProcessManager({
isDev: true, isDev: true,
nodecgPath: "/fake/nodecg", nodecgRootPath: "/fake/nodecg",
baseUrl: "http://127.0.0.1:9090", nodecgBaseUrl: "http://127.0.0.1:9090",
runtimeConfig: getBaseConfig(), appConfig: getBaseConfig(),
log: () => undefined, log: () => undefined,
deps: { deps: {
pathExists: () => true, pathExists: () => true,
@@ -72,9 +72,9 @@ test("waitForNodeCGReady resuelve cuando el endpoint responde 404", async () =>
}, },
}); });
manager.startNodeCG(); manager.startNodecgProcess();
await assert.doesNotReject(async () => { await assert.doesNotReject(async () => {
await manager.waitForNodeCGReady(Date.now()); await manager.waitForNodecgReady(Date.now());
}); });
}); });
@@ -85,9 +85,9 @@ test("stopNodeCG envía SIGTERM y luego SIGKILL si el proceso no sale", async ()
const manager = createNodecgProcessManager({ const manager = createNodecgProcessManager({
isDev: true, isDev: true,
nodecgPath: "/fake/nodecg", nodecgRootPath: "/fake/nodecg",
baseUrl: "http://127.0.0.1:9090", nodecgBaseUrl: "http://127.0.0.1:9090",
runtimeConfig: getBaseConfig(), appConfig: getBaseConfig(),
log: () => undefined, log: () => undefined,
deps: { deps: {
pathExists: () => true, pathExists: () => true,
@@ -105,8 +105,8 @@ test("stopNodeCG envía SIGTERM y luego SIGKILL si el proceso no sale", async ()
}, },
}); });
manager.startNodeCG(); manager.startNodecgProcess();
const stopPromise = manager.stopNodeCG(); const stopPromise = manager.stopNodecgProcessGracefully();
assert.deepEqual(killSignals, [{ pid: -9999, signal: "SIGTERM" }]); assert.deepEqual(killSignals, [{ pid: -9999, signal: "SIGTERM" }]);
@@ -129,9 +129,9 @@ test("stopNodeCG reutiliza la misma promesa cuando se invoca en paralelo", async
const manager = createNodecgProcessManager({ const manager = createNodecgProcessManager({
isDev: true, isDev: true,
nodecgPath: "/fake/nodecg", nodecgRootPath: "/fake/nodecg",
baseUrl: "http://127.0.0.1:9090", nodecgBaseUrl: "http://127.0.0.1:9090",
runtimeConfig: getBaseConfig(), appConfig: getBaseConfig(),
log: () => undefined, log: () => undefined,
deps: { deps: {
pathExists: () => true, pathExists: () => true,
@@ -144,9 +144,9 @@ test("stopNodeCG reutiliza la misma promesa cuando se invoca en paralelo", async
}, },
}); });
manager.startNodeCG(); manager.startNodecgProcess();
const firstStop = manager.stopNodeCG(); const firstStop = manager.stopNodecgProcessGracefully();
const secondStop = manager.stopNodeCG(); const secondStop = manager.stopNodecgProcessGracefully();
assert.equal(firstStop, secondStop); assert.equal(firstStop, secondStop);
@@ -160,9 +160,9 @@ test("stopNodeCG normaliza timeout negativo a cero", async () => {
const manager = createNodecgProcessManager({ const manager = createNodecgProcessManager({
isDev: true, isDev: true,
nodecgPath: "/fake/nodecg", nodecgRootPath: "/fake/nodecg",
baseUrl: "http://127.0.0.1:9090", nodecgBaseUrl: "http://127.0.0.1:9090",
runtimeConfig: { appConfig: {
...getBaseConfig(), ...getBaseConfig(),
nodecgKillTimeoutMs: -10, nodecgKillTimeoutMs: -10,
}, },
@@ -182,8 +182,8 @@ test("stopNodeCG normaliza timeout negativo a cero", async () => {
}, },
}); });
manager.startNodeCG(); manager.startNodecgProcess();
const stopPromise = manager.stopNodeCG(); const stopPromise = manager.stopNodecgProcessGracefully();
assert.ok(timeouts.includes(0)); assert.ok(timeouts.includes(0));