create-mercato-app 0.6.3-develop.3876.1.d40fe4ec2d → 0.6.3-develop.3881.1.0b590ac4eb
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/package.json
CHANGED
|
@@ -66,6 +66,17 @@ export function isIgnorableTurboShutdownLine(line) {
|
|
|
66
66
|
|| /^command (interrupted|cancelled|canceled)/i.test(plain)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
export function isIgnorableConsolidatedWatchLine(line) {
|
|
70
|
+
if (typeof line !== 'string') return false
|
|
71
|
+
const plain = normalize(line)
|
|
72
|
+
if (!plain.startsWith('[watch]')) return false
|
|
73
|
+
return /^\[watch\] consolidated watcher: /.test(plain)
|
|
74
|
+
|| /^\[watch\] [^:]+: rebuilding\.\.\.$/.test(plain)
|
|
75
|
+
|| /^\[watch\] [^:]+: rebuild complete$/.test(plain)
|
|
76
|
+
|| /^\[watch\] [^:]+: no source files found, skipping rebuild$/.test(plain)
|
|
77
|
+
|| /^\[watch\] no workspace packages with a `watch` script /.test(plain)
|
|
78
|
+
}
|
|
79
|
+
|
|
69
80
|
const FAILURE_NOISE_PREDICATES = [
|
|
70
81
|
isIgnorableBoxDrawingLine,
|
|
71
82
|
isIgnorableEnvInjectionLine,
|
|
@@ -89,6 +100,7 @@ const TURBO_NOISE_PREDICATES = [
|
|
|
89
100
|
isIgnorableTurboCacheCancellationLine,
|
|
90
101
|
isIgnorableTurboShutdownLine,
|
|
91
102
|
isIgnorableBoxDrawingLine,
|
|
103
|
+
isIgnorableConsolidatedWatchLine,
|
|
92
104
|
]
|
|
93
105
|
|
|
94
106
|
export function isIgnorableTurboLine(line) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import spawn from 'cross-spawn'
|
|
2
|
+
|
|
3
|
+
// Windows does not propagate signals from a parent process down to grandchildren
|
|
4
|
+
// the way POSIX does: child.kill('SIGTERM'/'SIGKILL') only terminates the direct
|
|
5
|
+
// child, leaving any further descendants (next dev, mercato generate watch, etc.)
|
|
6
|
+
// alive and still holding ports. taskkill with /T (tree) /F (force) is the
|
|
7
|
+
// platform-blessed way to terminate the whole descendant tree. On POSIX we keep
|
|
8
|
+
// child.kill so the existing graceful-then-forced two-phase shutdown is preserved.
|
|
9
|
+
export function killProcessTree(child, signal, options = {}) {
|
|
10
|
+
if (!child) return false
|
|
11
|
+
|
|
12
|
+
const platform = options.platform ?? process.platform
|
|
13
|
+
const spawnImpl = options.spawn ?? spawn
|
|
14
|
+
|
|
15
|
+
if (platform === 'win32') {
|
|
16
|
+
const pid = child.pid
|
|
17
|
+
if (typeof pid !== 'number' || Number.isNaN(pid) || pid <= 0) {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const killer = spawnImpl('taskkill', ['/pid', String(pid), '/T', '/F'], {
|
|
22
|
+
stdio: 'ignore',
|
|
23
|
+
windowsHide: true,
|
|
24
|
+
})
|
|
25
|
+
if (killer && typeof killer.on === 'function') {
|
|
26
|
+
killer.on('error', () => { /* best-effort: taskkill may not exist on stripped images */ })
|
|
27
|
+
}
|
|
28
|
+
return true
|
|
29
|
+
} catch {
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (child.killed) return false
|
|
35
|
+
try {
|
|
36
|
+
child.kill(signal)
|
|
37
|
+
return true
|
|
38
|
+
} catch {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
}
|
package/template/scripts/dev.mjs
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
stripAnsi,
|
|
24
24
|
} from './dev-splash-helpers.mjs'
|
|
25
25
|
import { purgeAppBuildCaches } from './dev-cache-purge.mjs'
|
|
26
|
+
import { killProcessTree } from './dev-shutdown-utils.mjs'
|
|
26
27
|
import { resolveSpawnCommand } from './dev-spawn-utils.mjs'
|
|
27
28
|
import { createDevSplashCodingFlow } from './dev-splash-coding-flow.mjs'
|
|
28
29
|
import { createDevSplashGitRepoFlow } from './dev-splash-git-repo-flow.mjs'
|
|
@@ -1023,13 +1024,13 @@ function shutdown(exitCode = 0) {
|
|
|
1023
1024
|
}
|
|
1024
1025
|
|
|
1025
1026
|
for (const child of alive) {
|
|
1026
|
-
child
|
|
1027
|
+
killProcessTree(child, 'SIGTERM')
|
|
1027
1028
|
}
|
|
1028
1029
|
|
|
1029
1030
|
setTimeout(() => {
|
|
1030
1031
|
for (const child of children) {
|
|
1031
1032
|
if (!child.killed) {
|
|
1032
|
-
child
|
|
1033
|
+
killProcessTree(child, 'SIGKILL')
|
|
1033
1034
|
}
|
|
1034
1035
|
}
|
|
1035
1036
|
closeDevLogSession()
|
|
@@ -1492,10 +1493,21 @@ async function runPassthroughStage(label, commandArgs, options = {}) {
|
|
|
1492
1493
|
console.log(`✅ ${formatProgressLine(label, stageCurrent, stageTotal, resolveProgressPercent(stageCurrent, stageTotal))} in ${formatDuration(Date.now() - startedAt)}`)
|
|
1493
1494
|
}
|
|
1494
1495
|
|
|
1496
|
+
function resolveWatchPackagesScript() {
|
|
1497
|
+
// `OM_WATCH_PACKAGES_MODE=legacy` falls back to the Turbo per-package
|
|
1498
|
+
// fan-out for developers who need the old behavior (debugging, or pairing
|
|
1499
|
+
// with `OM_PACKAGE_WATCH_MODE=persistent` for hot rebuilds at the cost of
|
|
1500
|
+
// ~1 GB more idle RSS). Default is the consolidated single-process watcher.
|
|
1501
|
+
const raw = String(process.env.OM_WATCH_PACKAGES_MODE ?? '').trim().toLowerCase()
|
|
1502
|
+
return raw === 'legacy' ? 'watch:packages:legacy' : 'watch:packages'
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1495
1505
|
function startPackageWatch() {
|
|
1506
|
+
const watchScript = resolveWatchPackagesScript()
|
|
1507
|
+
|
|
1496
1508
|
if (classic) {
|
|
1497
|
-
const child = spawnCommand(yarnCommand, [
|
|
1498
|
-
label:
|
|
1509
|
+
const child = spawnCommand(yarnCommand, [watchScript], {
|
|
1510
|
+
label: watchScript,
|
|
1499
1511
|
logFile: getDevRunnerLog(),
|
|
1500
1512
|
mirrorOutput: true,
|
|
1501
1513
|
})
|
|
@@ -1529,16 +1541,7 @@ function startPackageWatch() {
|
|
|
1529
1541
|
activity: 'Workspace package watch started',
|
|
1530
1542
|
})
|
|
1531
1543
|
|
|
1532
|
-
const child = spawnCommand(yarnCommand, [
|
|
1533
|
-
'turbo',
|
|
1534
|
-
'run',
|
|
1535
|
-
'watch',
|
|
1536
|
-
'--filter=./packages/*',
|
|
1537
|
-
'--concurrency=32',
|
|
1538
|
-
'--output-logs=errors-only',
|
|
1539
|
-
'--log-order=grouped',
|
|
1540
|
-
'--log-prefix=none',
|
|
1541
|
-
], {
|
|
1544
|
+
const child = spawnCommand(yarnCommand, [watchScript], {
|
|
1542
1545
|
label: 'Watching workspace packages',
|
|
1543
1546
|
logFile: getDevRunnerLog(),
|
|
1544
1547
|
mirrorOutput: verbose,
|