(startPort = 3002)
| 265 | * Probes ports in parallel batches for speed. |
| 266 | */ |
| 267 | export async function scanActiveServers(startPort = 3002): Promise<ActiveServer[]> { |
| 268 | const endPort = startPort + MAX_PORT_SCAN - 1; |
| 269 | const servers: ActiveServer[] = []; |
| 270 | |
| 271 | // Probe in batches of 20 to avoid too many concurrent connections |
| 272 | const batchSize = 20; |
| 273 | for (let batchStart = startPort; batchStart <= endPort; batchStart += batchSize) { |
| 274 | const batchEnd = Math.min(batchStart + batchSize - 1, endPort); |
| 275 | const ports = Array.from({ length: batchEnd - batchStart + 1 }, (_, i) => batchStart + i); |
| 276 | |
| 277 | const results = await Promise.all( |
| 278 | ports.map(async (port) => { |
| 279 | const config = await probePort(port); |
| 280 | if (!config) return null; |
| 281 | const pid = await getProcessOnPort(port); |
| 282 | return { |
| 283 | port, |
| 284 | projectName: config.projectName, |
| 285 | projectDir: config.projectDir, |
| 286 | version: config.version, |
| 287 | pid, |
| 288 | }; |
| 289 | }), |
| 290 | ); |
| 291 | |
| 292 | for (const r of results) { |
| 293 | if (r) servers.push(r); |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | return servers; |
| 298 | } |
| 299 | |
| 300 | /** |
| 301 | * Kill all active HyperFrames preview servers by sending SIGTERM to their PIDs. |
no test coverage detected