import { Hono } from 'hono'; import { serveStatic } from 'hono/bun'; import { spawn } from 'bun'; import fs from 'fs'; // Configuration const MODES_DIR = '/home/admin/Job-Info-Test'; const MODE_CONFIG_FILE = `${MODES_DIR}/ModeSwitch/activeMode.txt`; const SHARED_PORT = 3005; const ORCHESTRATOR_PORT = 3006; // Mode folder mappings const MODE_FOLDERS: Record = { 'Mode1Test': 'Mode1Test', 'Mode2Test': 'Mode2Test', 'Mode3Test': 'Mode3Test', }; let currentMode: string = 'Mode1Test'; let currentProcess: any = null; // Helper: Read active mode from config file function readActiveMode(): string { try { if (fs.existsSync(MODE_CONFIG_FILE)) { const content = fs.readFileSync(MODE_CONFIG_FILE, 'utf-8').trim(); return content || 'Test1Mode'; } } catch (err) { console.error('Failed to read mode config:', err); } return 'Mode1Test'; } // Helper: Write active mode to config file function writeActiveMode(mode: string): void { try { fs.writeFileSync(MODE_CONFIG_FILE, mode, 'utf-8'); } catch (err) { console.error('Failed to write mode config:', err); } } // Helper: Kill process on shared port async function killProcessOnPort(port: number): Promise { try { await Bun.spawn({ cmd: ['pkill', '-f', `bun.*:${port}`], stdout: 'ignore', stderr: 'ignore', }); // Fallback: Try to kill any Bun process we spawned if (currentProcess) { currentProcess.kill(); currentProcess = null; } // Give OS time to release the port await new Promise(resolve => setTimeout(resolve, 500)); } catch (err) { console.error(`Failed to kill process on port ${port}:`, err); } } // Helper: Start a mode async function startMode(mode: string): Promise { try { // Kill any existing process await killProcessOnPort(SHARED_PORT); const folderName = MODE_FOLDERS[mode]; if (!folderName) { console.error(`Unknown mode: ${mode}`); return false; } const modePath = `${MODES_DIR}/${folderName}`; if (!fs.existsSync(modePath)) { console.error(`Mode folder not found: ${modePath}`); return false; } console.log(`[ModeSwitch] Starting ${mode} (${folderName}/) on port ${SHARED_PORT}...`); // Determine server path based on mode // Mode2Test uses AuthAndToken/backend/server.ts // Mode1Test and Mode3Test use backend/server.ts let serverPath = 'backend/server.ts'; if (mode === 'Mode2Test') { serverPath = 'AuthAndToken/backend/server.ts'; } // Start the mode's backend server currentProcess = Bun.spawn({ cmd: ['bun', 'run', serverPath], cwd: modePath, stdout: 'pipe', stderr: 'pipe', }); currentMode = mode; writeActiveMode(mode); // Read and log output from the spawned process if (currentProcess.stdout) { (async () => { const reader = currentProcess.stdout.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; console.log(`[${mode}]`, new TextDecoder().decode(value)); } })(); } console.log(`✓ ${mode} started successfully on port ${SHARED_PORT}`); return true; } catch (err) { console.error(`Failed to start ${mode}:`, err); return false; } } // Initialize app const app = new Hono(); // Startup message console.log(` ================================================================================ [ModeSwitch Orchestrator] ================================================================================ Listening on port: ${ORCHESTRATOR_PORT} Shared mode port: ${SHARED_PORT} Config file: ${MODE_CONFIG_FILE} ================================================================================ `); // Start initial mode const initialMode = readActiveMode(); await startMode(initialMode); // Export for Bun export default { port: ORCHESTRATOR_PORT, fetch: app.fetch, };