UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

97 lines (81 loc) 2.72 kB
import { type ChildProcess, exec } from 'node:child_process'; import { resolve } from 'node:path'; let serverProcess: ChildProcess | null = null; let serverStartPromise: Promise<void> | null = null; interface WebServerOptions { command: string; env?: Record<string, string>; port: number; reuseExistingServer?: boolean; timeout?: number; } async function isServerRunning(port: number): Promise<boolean> { try { const response = await fetch(`http://localhost:${port}/chat`, { method: 'HEAD', }); return response.ok; } catch { return false; } } export async function startWebServer(options: WebServerOptions): Promise<void> { const { command, port, timeout = 120_000, env = {}, reuseExistingServer = true } = options; // If server is already being started by another worker, wait for it if (serverStartPromise) { console.log(`⏳ Waiting for server to start (started by another worker)...`); return serverStartPromise; } // Check if server is already running if (reuseExistingServer && (await isServerRunning(port))) { console.log(`✅ Reusing existing server on port ${port}`); return; } // Create a promise for the server startup and store it serverStartPromise = (async () => { console.log(`🚀 Starting web server: ${command}`); // Get the project root directory (parent of e2e folder) const projectRoot = resolve(__dirname, '../../..'); // Start the server process serverProcess = exec(command, { cwd: projectRoot, env: { ...process.env, ENABLE_AUTH_PROTECTION: '0', ENABLE_OIDC: '0', NEXT_PUBLIC_ENABLE_CLERK_AUTH: '0', NEXT_PUBLIC_ENABLE_NEXT_AUTH: '0', NODE_OPTIONS: '--max-old-space-size=6144', PORT: String(port), ...env, }, }); // Forward server output to console for debugging serverProcess.stdout?.on('data', (data) => { console.log(`[server] ${data}`); }); serverProcess.stderr?.on('data', (data) => { console.error(`[server] ${data}`); }); // Wait for server to be ready const startTime = Date.now(); while (!(await isServerRunning(port))) { if (Date.now() - startTime > timeout) { throw new Error(`Server failed to start within ${timeout}ms`); } await new Promise((resolve) => { setTimeout(resolve, 1000); }); } console.log(`✅ Web server is ready on port ${port}`); })(); return serverStartPromise; } export async function stopWebServer(): Promise<void> { if (serverProcess) { console.log('🛑 Stopping web server...'); serverProcess.kill(); serverProcess = null; serverStartPromise = null; } }