const { spawn, execSync } = require('child_process'); const http = require('http'); const fs = require('fs'); const path = require('path'); const BACKEND_PORT = 4400; const MAX_WAIT = 60000; const distMainPath = path.join(__dirname, '..', 'backend', 'dist', 'main.js'); if (!fs.existsSync(distMainPath)) { console.log('[start-dev] Compiling backend dist/main.js before launch...'); execSync('npm run build', { cwd: path.join(__dirname, '..', 'backend'), stdio: 'inherit' }); } function waitForBackend(port, timeout) { return new Promise((resolve, reject) => { const start = Date.now(); function check() { const req = http.get(`http://127.0.0.1:${port}/api/docs`, (res) => { resolve(); }); req.on('error', () => { if (Date.now() - start > timeout) { reject(new Error(`Backend did not start within ${timeout/1000}s`)); } else { setTimeout(check, 1000); } }); req.setTimeout(3000, () => { req.destroy(); }); } setTimeout(check, 3000); }); } const backend = spawn('npm', ['run', 'dev:backend'], { stdio: 'inherit', shell: true }); waitForBackend(BACKEND_PORT, MAX_WAIT).then(() => { const store = spawn('npm', ['run', 'dev:frontend'], { stdio: 'inherit', shell: true }); const admin = spawn('npm', ['run', 'dev:admin'], { stdio: 'inherit', shell: true }); const openBrowsers = spawn('node', ['scripts/open-browsers.js'], { stdio: 'inherit', shell: true }); process.on('SIGINT', () => { backend.kill(); store.kill(); admin.kill(); openBrowsers.kill(); process.exit(); }); }).catch((err) => { console.error(err.message); backend.kill(); process.exit(1); });