@open-mercato/cli 0.6.3-develop.3894.1.352abf4240 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +1 -1
- package/dist/agentic/shared/AGENTS.md.template +1 -0
- package/dist/lib/dev-env-reload.js +40 -1
- package/dist/lib/dev-env-reload.js.map +2 -2
- package/dist/lib/generate-watch-structure.js +153 -0
- package/dist/lib/generate-watch-structure.js.map +7 -0
- package/dist/lib/testing/integration.js +14 -0
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/mercato.js +244 -98
- package/dist/mercato.js.map +2 -2
- package/package.json +7 -8
- package/src/__tests__/mercato.test.ts +13 -3
- package/src/lib/__tests__/dev-env-reload.test.ts +21 -1
- package/src/lib/__tests__/generate-watch-structure.test.ts +80 -0
- package/src/lib/dev-env-reload.ts +47 -0
- package/src/lib/generate-watch-structure.ts +170 -0
- package/src/lib/testing/integration.ts +14 -0
- package/src/mercato.ts +241 -67
package/dist/mercato.js
CHANGED
|
@@ -246,6 +246,102 @@ function buildServerProcessEnvironment(environment) {
|
|
|
246
246
|
}
|
|
247
247
|
return runtimeEnv;
|
|
248
248
|
}
|
|
249
|
+
function resolveDevRuntimeBaseUrl(environment = process.env) {
|
|
250
|
+
const configured = environment.APP_URL ?? environment.NEXT_PUBLIC_APP_URL ?? environment.NEXTAUTH_URL;
|
|
251
|
+
if (configured?.trim()) {
|
|
252
|
+
return configured.trim().replace(/\/+$/, "");
|
|
253
|
+
}
|
|
254
|
+
return `http://localhost:${environment.PORT?.trim() || "3000"}`;
|
|
255
|
+
}
|
|
256
|
+
function writeDevSplashChildState(state) {
|
|
257
|
+
if (process.env.OM_DEV_SPLASH_RUNTIME_WRAPPER === "1") return;
|
|
258
|
+
const stateFile = process.env.OM_DEV_SPLASH_CHILD_STATE_FILE;
|
|
259
|
+
if (!stateFile?.trim()) return;
|
|
260
|
+
try {
|
|
261
|
+
fs.mkdirSync(path.dirname(stateFile), { recursive: true });
|
|
262
|
+
fs.writeFileSync(stateFile, `${JSON.stringify({
|
|
263
|
+
mode: process.env.OM_DEV_SPLASH_MODE || "dev",
|
|
264
|
+
failed: false,
|
|
265
|
+
failureLines: [],
|
|
266
|
+
failureCommand: null,
|
|
267
|
+
...state
|
|
268
|
+
}, null, 2)}
|
|
269
|
+
`);
|
|
270
|
+
} catch {
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function writeDevSplashRuntimeStarting(detail = "Starting Next.js dev server") {
|
|
274
|
+
writeDevSplashChildState({
|
|
275
|
+
phase: "Preparing app runtime",
|
|
276
|
+
detail,
|
|
277
|
+
ready: false,
|
|
278
|
+
readyUrl: null,
|
|
279
|
+
loginUrl: null,
|
|
280
|
+
progressLabel: "Launching app runtime",
|
|
281
|
+
activity: detail
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function resolveSplashProgressFallback() {
|
|
285
|
+
const current = Number.parseInt(process.env.OM_DEV_SPLASH_STAGE_CURRENT ?? "", 10);
|
|
286
|
+
const total = Number.parseInt(process.env.OM_DEV_SPLASH_STAGE_TOTAL ?? "", 10);
|
|
287
|
+
if (Number.isFinite(current) && Number.isFinite(total) && total > 0) {
|
|
288
|
+
return { current, total };
|
|
289
|
+
}
|
|
290
|
+
if (process.env.OM_DEV_SPLASH_MODE === "greenfield" || process.env.OM_DEV_SPLASH_MODE === "setup") {
|
|
291
|
+
return { current: 5, total: 5 };
|
|
292
|
+
}
|
|
293
|
+
return { current: 3, total: 3 };
|
|
294
|
+
}
|
|
295
|
+
function writeDevSplashRuntimeRestarting(reason) {
|
|
296
|
+
const progress = resolveSplashProgressFallback();
|
|
297
|
+
writeDevSplashChildState({
|
|
298
|
+
phase: "App runtime is restarting",
|
|
299
|
+
detail: `Reason: ${reason}`,
|
|
300
|
+
ready: false,
|
|
301
|
+
readyUrl: null,
|
|
302
|
+
loginUrl: null,
|
|
303
|
+
progressCurrent: progress.current,
|
|
304
|
+
progressTotal: progress.total,
|
|
305
|
+
progressLabel: "Restarting app runtime",
|
|
306
|
+
activity: `App runtime restart: ${reason}`
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
function writeDevSplashRuntimeReady(reason) {
|
|
310
|
+
const readyUrl = resolveDevRuntimeBaseUrl();
|
|
311
|
+
const progress = resolveSplashProgressFallback();
|
|
312
|
+
writeDevSplashChildState({
|
|
313
|
+
phase: "App is ready",
|
|
314
|
+
detail: reason ? `Restart completed after ${reason}` : "Next.js dev server is ready",
|
|
315
|
+
ready: true,
|
|
316
|
+
readyUrl,
|
|
317
|
+
loginUrl: `${readyUrl}/login`,
|
|
318
|
+
progressCurrent: progress.current,
|
|
319
|
+
progressTotal: progress.total,
|
|
320
|
+
progressPercent: 100,
|
|
321
|
+
progressLabel: "App is ready",
|
|
322
|
+
activity: reason ? `Restart completed after ${reason}` : "App runtime is ready"
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
function resolveDevWarmupReadyTimeoutMs(environment = process.env) {
|
|
326
|
+
const parsed = Number.parseInt(environment.OM_DEV_WARMUP_READY_TIMEOUT_MS ?? "", 10);
|
|
327
|
+
if (Number.isFinite(parsed) && parsed >= 0) return parsed;
|
|
328
|
+
return 3e5;
|
|
329
|
+
}
|
|
330
|
+
async function waitForDevWarmupReadyFile(filePath, options = {}) {
|
|
331
|
+
const normalized = filePath?.trim();
|
|
332
|
+
if (!normalized) return "ready";
|
|
333
|
+
const timeoutMs = options.timeoutMs ?? resolveDevWarmupReadyTimeoutMs();
|
|
334
|
+
const startedAt = Date.now();
|
|
335
|
+
while (true) {
|
|
336
|
+
if (options.signal?.aborted) return "aborted";
|
|
337
|
+
try {
|
|
338
|
+
if (fs.existsSync(normalized)) return "ready";
|
|
339
|
+
} catch {
|
|
340
|
+
}
|
|
341
|
+
if (timeoutMs >= 0 && Date.now() - startedAt >= timeoutMs) return "timeout";
|
|
342
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
249
345
|
function waitForManagedProcessExit(proc, label) {
|
|
250
346
|
return new Promise((resolve) => {
|
|
251
347
|
proc.on("exit", (code, signal) => {
|
|
@@ -445,18 +541,17 @@ async function runGeneratorSuite(quiet) {
|
|
|
445
541
|
function createGenerateWatchChecksumFn() {
|
|
446
542
|
return async () => {
|
|
447
543
|
const { createResolver } = await import("./lib/resolver.js");
|
|
448
|
-
const {
|
|
544
|
+
const { calculateGenerateWatchStructureChecksum } = await import("./lib/generate-watch-structure.js");
|
|
449
545
|
const resolver = createResolver();
|
|
450
|
-
const
|
|
451
|
-
path.join(resolver.getAppDir(), "src", "modules.ts"),
|
|
452
|
-
path.join(resolver.getAppDir(), "src", "modules")
|
|
453
|
-
]);
|
|
546
|
+
const moduleRoots = [];
|
|
454
547
|
for (const entry of resolver.loadEnabledModules()) {
|
|
455
548
|
const roots = resolver.getModulePaths(entry);
|
|
456
|
-
|
|
457
|
-
tracked.add(roots.pkgBase);
|
|
549
|
+
moduleRoots.push({ appBase: roots.appBase, pkgBase: roots.pkgBase });
|
|
458
550
|
}
|
|
459
|
-
return
|
|
551
|
+
return calculateGenerateWatchStructureChecksum({
|
|
552
|
+
modulesFile: path.join(resolver.getAppDir(), "src", "modules.ts"),
|
|
553
|
+
moduleRoots
|
|
554
|
+
});
|
|
460
555
|
};
|
|
461
556
|
}
|
|
462
557
|
async function buildAllModules() {
|
|
@@ -1390,10 +1485,11 @@ async function run(argv = process.argv) {
|
|
|
1390
1485
|
let processes = [];
|
|
1391
1486
|
let didRetryCorruptedTurbopackCache = false;
|
|
1392
1487
|
let stopping = false;
|
|
1393
|
-
let
|
|
1488
|
+
let devRestartPromiseResolve = null;
|
|
1394
1489
|
let activeLazySupervisor = null;
|
|
1395
1490
|
let activeLazySchedulerSupervisor = null;
|
|
1396
1491
|
let activeGenerateWatcher = null;
|
|
1492
|
+
let lastRestartReason = null;
|
|
1397
1493
|
const generateWatcherMode = resolveGenerateWatcherMode(process.env);
|
|
1398
1494
|
const envReloader = createDevEnvReloader(appDir, process.env, initialProcessEnvironmentEntries);
|
|
1399
1495
|
function cleanup() {
|
|
@@ -1466,53 +1562,74 @@ async function run(argv = process.argv) {
|
|
|
1466
1562
|
const nextBin = resolveInstalledBinary(nodeModulesBases, "next/dist/bin/next");
|
|
1467
1563
|
const mercatoBin = resolveInstalledBinary(nodeModulesBases, "@open-mercato/cli/bin/mercato");
|
|
1468
1564
|
const stopEnvWatcher = watchDevEnvFiles(appDir, (filePath) => {
|
|
1469
|
-
|
|
1565
|
+
devRestartPromiseResolve?.({
|
|
1470
1566
|
label: "Environment file change",
|
|
1471
1567
|
restart: true,
|
|
1472
1568
|
filePath
|
|
1473
1569
|
});
|
|
1474
1570
|
});
|
|
1475
|
-
const
|
|
1476
|
-
|
|
1571
|
+
const waitForDevRestart = () => new Promise((resolve) => {
|
|
1572
|
+
devRestartPromiseResolve = resolve;
|
|
1477
1573
|
});
|
|
1478
|
-
const startNextDev = (runtimeEnv) =>
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
cwd: appDir
|
|
1574
|
+
const startNextDev = (runtimeEnv) => {
|
|
1575
|
+
let readyResolve = () => void 0;
|
|
1576
|
+
const readyPromise = new Promise((resolve) => {
|
|
1577
|
+
readyResolve = resolve;
|
|
1483
1578
|
});
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1579
|
+
const exitPromise = new Promise((resolve) => {
|
|
1580
|
+
writeDevSplashRuntimeStarting(
|
|
1581
|
+
lastRestartReason ? `Restarting Next.js dev server. Reason: ${lastRestartReason}` : "Starting Next.js dev server"
|
|
1582
|
+
);
|
|
1583
|
+
const nextProcess = spawn("node", [nextBin, "dev", "--turbopack"], {
|
|
1584
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
1585
|
+
env: runtimeEnv,
|
|
1586
|
+
cwd: appDir
|
|
1587
|
+
});
|
|
1588
|
+
processes.push(nextProcess);
|
|
1589
|
+
let combinedOutput = "";
|
|
1590
|
+
let reportedReady = false;
|
|
1591
|
+
const appendOutput = (chunk) => {
|
|
1592
|
+
combinedOutput += chunk;
|
|
1593
|
+
if (combinedOutput.length > 32768) {
|
|
1594
|
+
combinedOutput = combinedOutput.slice(-32768);
|
|
1595
|
+
}
|
|
1596
|
+
if (!reportedReady && /\bready in\b/i.test(chunk)) {
|
|
1597
|
+
reportedReady = true;
|
|
1598
|
+
writeDevSplashRuntimeReady(lastRestartReason ?? void 0);
|
|
1599
|
+
lastRestartReason = null;
|
|
1600
|
+
readyResolve();
|
|
1601
|
+
}
|
|
1602
|
+
};
|
|
1603
|
+
nextProcess.stdout?.on("data", (chunk) => {
|
|
1604
|
+
const text = typeof chunk === "string" ? chunk : chunk.toString();
|
|
1605
|
+
process.stdout.write(text);
|
|
1606
|
+
appendOutput(text);
|
|
1607
|
+
});
|
|
1608
|
+
nextProcess.stderr?.on("data", (chunk) => {
|
|
1609
|
+
const text = typeof chunk === "string" ? chunk : chunk.toString();
|
|
1610
|
+
process.stderr.write(text);
|
|
1611
|
+
appendOutput(text);
|
|
1612
|
+
});
|
|
1613
|
+
nextProcess.on("exit", async (code, signal) => {
|
|
1614
|
+
if (!didRetryCorruptedTurbopackCache && isTurbopackCacheCorruption(combinedOutput)) {
|
|
1615
|
+
didRetryCorruptedTurbopackCache = true;
|
|
1616
|
+
lastRestartReason = "corrupted Turbopack dev cache";
|
|
1617
|
+
writeDevSplashRuntimeRestarting(lastRestartReason);
|
|
1618
|
+
console.log("[server] Detected corrupted Turbopack dev cache. Clearing .mercato/next/dev and restarting Next.js once...");
|
|
1619
|
+
removeTurbopackDevCache(appDir);
|
|
1620
|
+
const restarted = startNextDev(runtimeEnv);
|
|
1621
|
+
restarted.readyPromise.then(readyResolve);
|
|
1622
|
+
return resolve(await restarted.exitPromise);
|
|
1623
|
+
}
|
|
1624
|
+
resolve({
|
|
1625
|
+
label: "Next.js dev server",
|
|
1626
|
+
code,
|
|
1627
|
+
signal
|
|
1628
|
+
});
|
|
1513
1629
|
});
|
|
1514
1630
|
});
|
|
1515
|
-
|
|
1631
|
+
return { exitPromise, readyPromise };
|
|
1632
|
+
};
|
|
1516
1633
|
try {
|
|
1517
1634
|
while (!stopping) {
|
|
1518
1635
|
envReloader.reload();
|
|
@@ -1521,59 +1638,84 @@ async function run(argv = process.argv) {
|
|
|
1521
1638
|
const autoSpawnSchedulerMode = resolveAutoSpawnSchedulerMode(process.env);
|
|
1522
1639
|
const queueStrategy = process.env.QUEUE_STRATEGY || "local";
|
|
1523
1640
|
const schedulerCommand = lookupModuleCommand(getCliModules(), "scheduler", "start");
|
|
1641
|
+
const nextRuntime = startNextDev(runtimeEnv);
|
|
1642
|
+
const restartPromise = waitForDevRestart();
|
|
1643
|
+
const backgroundStartAbort = new AbortController();
|
|
1644
|
+
const cancelBackgroundStart = () => backgroundStartAbort.abort();
|
|
1645
|
+
nextRuntime.exitPromise.finally(cancelBackgroundStart);
|
|
1646
|
+
restartPromise.then(cancelBackgroundStart);
|
|
1647
|
+
let backgroundExitResolve = () => void 0;
|
|
1648
|
+
const backgroundExitPromise = new Promise((resolve) => {
|
|
1649
|
+
backgroundExitResolve = resolve;
|
|
1650
|
+
});
|
|
1524
1651
|
const managedExitPromises = [
|
|
1525
|
-
|
|
1526
|
-
|
|
1652
|
+
nextRuntime.exitPromise,
|
|
1653
|
+
restartPromise,
|
|
1654
|
+
backgroundExitPromise
|
|
1527
1655
|
];
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
const
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
appDir,
|
|
1538
|
-
runtimeEnv,
|
|
1539
|
-
workers: discoveredWorkers,
|
|
1540
|
-
pollMs: resolveLazyPollMs(process.env),
|
|
1541
|
-
restartOnUnexpectedExit: resolveLazyRestart(process.env)
|
|
1542
|
-
});
|
|
1543
|
-
} else {
|
|
1544
|
-
console.log("[server] Eager worker auto-spawn enabled - starting workers for all queues...");
|
|
1545
|
-
const workerProcess = spawn("node", [mercatoBin, "queue", "worker", "--all"], {
|
|
1546
|
-
stdio: "inherit",
|
|
1547
|
-
env: runtimeEnv,
|
|
1548
|
-
cwd: appDir
|
|
1549
|
-
});
|
|
1550
|
-
processes.push(workerProcess);
|
|
1551
|
-
managedExitPromises.push(waitForManagedProcessExit(workerProcess, formatQueueWorkerLabel(discoveredWorkerQueues)));
|
|
1656
|
+
const startBackgroundServices = async () => {
|
|
1657
|
+
if (stopping || backgroundStartAbort.signal.aborted) return;
|
|
1658
|
+
const warmupReady = await waitForDevWarmupReadyFile(process.env.OM_DEV_WARMUP_READY_FILE, {
|
|
1659
|
+
timeoutMs: resolveDevWarmupReadyTimeoutMs(process.env),
|
|
1660
|
+
signal: backgroundStartAbort.signal
|
|
1661
|
+
});
|
|
1662
|
+
if (warmupReady === "aborted" || stopping || backgroundStartAbort.signal.aborted) return;
|
|
1663
|
+
if (warmupReady === "timeout") {
|
|
1664
|
+
console.warn("[server] Timed out waiting for dev warmup marker; starting background services anyway.");
|
|
1552
1665
|
}
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1666
|
+
if (autoSpawnWorkersMode !== "off") {
|
|
1667
|
+
const discoveredWorkers = getRegisteredCliWorkers();
|
|
1668
|
+
const discoveredWorkerQueues = [...new Set(discoveredWorkers.map((worker) => worker.queue))];
|
|
1669
|
+
if (discoveredWorkerQueues.length === 0) {
|
|
1670
|
+
console.error("[server] AUTO_SPAWN_WORKERS is enabled, but no queues were discovered from CLI modules. Run `yarn generate` and verify `.mercato/generated/modules.cli.generated.ts` contains worker entries. Continuing without auto-spawned workers.");
|
|
1671
|
+
} else if (autoSpawnWorkersMode === "lazy") {
|
|
1672
|
+
console.log(`[server] Lazy worker auto-spawn enabled \u2014 workers will start on first job (${discoveredWorkerQueues.length} queue(s) watched).`);
|
|
1673
|
+
activeLazySupervisor = startLazyWorkerSupervisor({
|
|
1674
|
+
mercatoBin,
|
|
1675
|
+
appDir,
|
|
1676
|
+
runtimeEnv,
|
|
1677
|
+
workers: discoveredWorkers,
|
|
1678
|
+
pollMs: resolveLazyPollMs(process.env),
|
|
1679
|
+
restartOnUnexpectedExit: resolveLazyRestart(process.env)
|
|
1680
|
+
});
|
|
1681
|
+
} else {
|
|
1682
|
+
console.log("[server] Eager worker auto-spawn enabled - starting workers for all queues...");
|
|
1683
|
+
const workerProcess = spawn("node", [mercatoBin, "queue", "worker", "--all"], {
|
|
1684
|
+
stdio: "inherit",
|
|
1685
|
+
env: runtimeEnv,
|
|
1686
|
+
cwd: appDir
|
|
1687
|
+
});
|
|
1688
|
+
processes.push(workerProcess);
|
|
1689
|
+
waitForManagedProcessExit(workerProcess, formatQueueWorkerLabel(discoveredWorkerQueues)).then(backgroundExitResolve);
|
|
1690
|
+
}
|
|
1575
1691
|
}
|
|
1576
|
-
|
|
1692
|
+
if (autoSpawnSchedulerMode !== "off" && queueStrategy === "local") {
|
|
1693
|
+
if (schedulerCommand.status !== "ok") {
|
|
1694
|
+
console.log(`[server] Skipping scheduler auto-start \u2014 ${describeMissingModuleCommand(schedulerCommand)}`);
|
|
1695
|
+
} else if (autoSpawnSchedulerMode === "lazy") {
|
|
1696
|
+
console.log("[server] Lazy scheduler auto-spawn enabled - scheduler will start when an enabled schedule exists.");
|
|
1697
|
+
activeLazySchedulerSupervisor = startLazySchedulerSupervisor({
|
|
1698
|
+
mercatoBin,
|
|
1699
|
+
appDir,
|
|
1700
|
+
runtimeEnv,
|
|
1701
|
+
pollMs: resolveLazySchedulerPollMs(process.env),
|
|
1702
|
+
restartOnUnexpectedExit: resolveLazySchedulerRestart(process.env)
|
|
1703
|
+
});
|
|
1704
|
+
} else {
|
|
1705
|
+
console.log("[server] Eager scheduler auto-spawn enabled - starting scheduler polling engine...");
|
|
1706
|
+
const schedulerProcess = spawn("node", [mercatoBin, "scheduler", "start"], {
|
|
1707
|
+
stdio: "inherit",
|
|
1708
|
+
env: runtimeEnv,
|
|
1709
|
+
cwd: appDir
|
|
1710
|
+
});
|
|
1711
|
+
processes.push(schedulerProcess);
|
|
1712
|
+
waitForManagedProcessExit(schedulerProcess, "Scheduler polling engine").then(backgroundExitResolve);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
nextRuntime.readyPromise.then(() => {
|
|
1717
|
+
void startBackgroundServices();
|
|
1718
|
+
});
|
|
1577
1719
|
if (generateWatcherMode === "in-process") {
|
|
1578
1720
|
console.log("[server] In-process generate watcher enabled \u2014 structural changes will regenerate without a sidecar process.");
|
|
1579
1721
|
activeGenerateWatcher = startInProcessGenerateWatcher({
|
|
@@ -1594,10 +1736,14 @@ async function run(argv = process.argv) {
|
|
|
1594
1736
|
console.log("[server] Legacy out-of-process generate watcher selected via OM_DEV_GENERATE_WATCH_MODE=legacy \u2014 expect the dev orchestrator to spawn `mercato generate watch --skip-initial`.");
|
|
1595
1737
|
}
|
|
1596
1738
|
const firstExit = await Promise.race(managedExitPromises);
|
|
1739
|
+
if (isDevServerRestartResult(firstExit)) {
|
|
1740
|
+
lastRestartReason = `${firstExit.label.toLowerCase()} (${path.basename(firstExit.filePath)})`;
|
|
1741
|
+
writeDevSplashRuntimeRestarting(lastRestartReason);
|
|
1742
|
+
}
|
|
1597
1743
|
await cleanupAndWait();
|
|
1598
|
-
|
|
1744
|
+
devRestartPromiseResolve = null;
|
|
1599
1745
|
if (isDevServerRestartResult(firstExit)) {
|
|
1600
|
-
console.log(`[server] Detected
|
|
1746
|
+
console.log(`[server] Detected ${firstExit.label.toLowerCase()} (${path.basename(firstExit.filePath)}). Restarting app runtime...`);
|
|
1601
1747
|
continue;
|
|
1602
1748
|
}
|
|
1603
1749
|
if (!isExpectedManagedExit(firstExit, { stopping })) {
|