| 588 | } |
| 589 | |
| 590 | export const startDevServer: StartDevServer = async opts => { |
| 591 | const { |
| 592 | entrypoint: rawEntrypoint, |
| 593 | workPath, |
| 594 | meta = {}, |
| 595 | config, |
| 596 | service, |
| 597 | onStdout, |
| 598 | onStderr, |
| 599 | } = opts; |
| 600 | |
| 601 | const framework = config?.framework; |
| 602 | |
| 603 | // Check for an existing persistent server. |
| 604 | // Include serviceName so that services sharing a workspace get separate servers. |
| 605 | const serviceName = |
| 606 | service?.name ?? |
| 607 | (typeof meta.serviceName === 'string' ? meta.serviceName : undefined); |
| 608 | const serverKey = serviceName |
| 609 | ? `${workPath}::${framework}::${serviceName}` |
| 610 | : `${workPath}::${framework}`; |
| 611 | const existing = PERSISTENT_SERVERS.get(serverKey); |
| 612 | if (existing) { |
| 613 | return { |
| 614 | port: existing.port, |
| 615 | pid: existing.pid, |
| 616 | shutdown: async () => { |
| 617 | // no-op so CLI does not kill persistent server per request |
| 618 | }, |
| 619 | }; |
| 620 | } |
| 621 | |
| 622 | // Check for a pending start operation before spawning a new server |
| 623 | { |
| 624 | const pending = PENDING_STARTS.get(serverKey); |
| 625 | if (pending) { |
| 626 | const { port, pid } = await pending; |
| 627 | return { |
| 628 | port, |
| 629 | pid, |
| 630 | shutdown: async () => {}, |
| 631 | }; |
| 632 | } |
| 633 | } |
| 634 | |
| 635 | // No framework is defined, so most likely this is 'handler' class-based |
| 636 | // serverless functions that should be served directly using vercel-runtime |
| 637 | // instead of dev server. |
| 638 | // Otherwise the framework would be a known one or just 'python'. |
| 639 | if (!framework) { |
| 640 | return null; |
| 641 | } |
| 642 | |
| 643 | // Silence Node warnings and install cleanup handlers once |
| 644 | if (!restoreWarnings) restoreWarnings = silenceNodeWarnings(); |
| 645 | installGlobalCleanupHandlers(); |
| 646 | const env = { ...process.env, ...(meta.env || {}) } as NodeJS.ProcessEnv; |
| 647 | const entrypoint = rawEntrypoint === '<detect>' ? undefined : rawEntrypoint; |