From fd4a599ae095c70aaff6a47e5fb9aa8e2885fc7d Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Tue, 24 Feb 2026 00:52:08 +0100 Subject: [PATCH] Add human-style explanatory comments in main runtime flow --- src/main/config/runtime-config.ts | 2 ++ src/main/main.ts | 3 +++ src/main/nodecg/process-manager.ts | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/main/config/runtime-config.ts b/src/main/config/runtime-config.ts index 6074e20..260895d 100644 --- a/src/main/config/runtime-config.ts +++ b/src/main/config/runtime-config.ts @@ -15,6 +15,7 @@ const MIN_TCP_PORT = 1; const MAX_TCP_PORT = 65535; export function getRuntimeConfig(): AppRuntimeConfig { + // Centralized defaults keep local development and packaged builds consistent. return { title: getEnv("SCOREKO_APP_TITLE", "Scoreko"), userModelId: getEnv("SCOREKO_APP_USER_MODEL_ID", "com.scoreko.desktop"), @@ -49,6 +50,7 @@ export function parseEnvInt(name: string, fallback: number): number { } export function parseEnvIntInRange(name: string, fallback: number, min: number, max: number): number { + // We throw here instead of silently coercing to avoid hidden misconfiguration in production. const rawValue = process.env[name]; if (!rawValue) { return fallback; diff --git a/src/main/main.ts b/src/main/main.ts index a14bf8d..09ae77e 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -31,6 +31,7 @@ let loadingWindow: BrowserWindow | null = null; let shutdownState: AppShutdownState = "running"; async function launchApplication(): Promise { + // We create both windows early so startup feels instant while NodeCG is booting in the background. mainWindow = createMainWindow({ appConfig, rootPath, mainDashboardUrl }); loadingWindow = createLoadingWindow({ appConfig, rootPath }); @@ -53,6 +54,7 @@ async function launchApplication(): Promise { await mainWindow.loadURL(mainDashboardUrl); + // Keep the loading overlay visible for a minimum amount of time to avoid abrupt flashes. const remainingLoadingDelay = getRemainingDelayMs(appConfig.loadDelayMs, loadingShownAt); if (remainingLoadingDelay > 0) { await sleep(remainingLoadingDelay); @@ -126,6 +128,7 @@ app.on("before-quit", (event) => { return; } + // Block the default quit flow until we ask NodeCG to stop cleanly. event.preventDefault(); stopNodecgGracefully().finally(() => { diff --git a/src/main/nodecg/process-manager.ts b/src/main/nodecg/process-manager.ts index b8064ea..94bc3ed 100644 --- a/src/main/nodecg/process-manager.ts +++ b/src/main/nodecg/process-manager.ts @@ -53,6 +53,7 @@ export function createNodecgProcessManager({ let lastStderrLine: string | null = null; const startNodecgProcess = async (): Promise => { + // Fail fast with actionable errors before spawning child processes. validateNodecgInstall( nodecgRootPath, appConfig.bundleName, @@ -107,6 +108,7 @@ export function createNodecgProcessManager({ }; const waitForNodecgReady = async (startTime: number): Promise => { + // Poll the local NodeCG URL until it answers or we hit the configured timeout. while (Date.now() - startTime < appConfig.startupTimeoutMs) { if (!nodecgProcess) { const exitDetails = lastExit @@ -140,6 +142,7 @@ export function createNodecgProcessManager({ }; const stopNodecgProcessGracefully = (): Promise => { + // Reuse the same stop promise to avoid sending multiple kill signals during app shutdown. if (stopNodecgPromise) { return stopNodecgPromise; } @@ -267,6 +270,7 @@ function hasReadWriteAccess(candidatePath: string): boolean { function probePortAvailable(port: number): Promise { return new Promise((resolve) => { + // A successful TCP connection means some process is already listening on the port. const socket = net.createConnection({ host: "127.0.0.1", port }); let resolved = false;