@10stars/config 15.1.1 → 15.1.4
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 +2 -2
- package/src/index.ts +1 -1
- package/src/runner.ts +44 -26
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/runner.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { colors, getNextColor, type ColorName } from "./colors"
|
|
|
2
2
|
|
|
3
3
|
export interface CommandConfig {
|
|
4
4
|
/** Label shown as prefix in output */
|
|
5
|
-
label
|
|
5
|
+
label?: string
|
|
6
6
|
/** Command to run (string will be split by spaces, array used as-is) */
|
|
7
7
|
command: string | string[]
|
|
8
8
|
/** Color for the label (auto-assigned if not provided) */
|
|
@@ -10,7 +10,7 @@ export interface CommandConfig {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
interface RunningProcess {
|
|
13
|
-
label
|
|
13
|
+
label?: string
|
|
14
14
|
proc: ReturnType<typeof Bun.spawn>
|
|
15
15
|
prefix: string
|
|
16
16
|
}
|
|
@@ -24,7 +24,11 @@ async function pipeOutput(
|
|
|
24
24
|
const text = decoder.decode(chunk).trimEnd()
|
|
25
25
|
if (text) {
|
|
26
26
|
for (const line of text.split("\n")) {
|
|
27
|
-
|
|
27
|
+
if (prefix) {
|
|
28
|
+
console.log(`${prefix} ${line}`)
|
|
29
|
+
} else {
|
|
30
|
+
console.log(line)
|
|
31
|
+
}
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
}
|
|
@@ -40,9 +44,13 @@ export async function runConcurrently(commands: CommandConfig[]): Promise<void>
|
|
|
40
44
|
const processes: RunningProcess[] = []
|
|
41
45
|
|
|
42
46
|
for (const config of commands) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
let prefix = ""
|
|
48
|
+
if (config.label) {
|
|
49
|
+
const colorName = config.color ?? getNextColor()
|
|
50
|
+
const colorFn = colors[colorName]
|
|
51
|
+
prefix = `[${colorFn(config.label)}]`
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
const args = parseCommand(config.command)
|
|
47
55
|
|
|
48
56
|
const proc = Bun.spawn(args, {
|
|
@@ -61,30 +69,40 @@ export async function runConcurrently(commands: CommandConfig[]): Promise<void>
|
|
|
61
69
|
pipeOutput(proc.stderr, prefix)
|
|
62
70
|
}
|
|
63
71
|
|
|
64
|
-
//
|
|
65
|
-
const
|
|
72
|
+
// Kill all processes and exit
|
|
73
|
+
const killAll = (exitCode: number) => {
|
|
66
74
|
for (const { proc } of processes) {
|
|
67
|
-
|
|
75
|
+
try {
|
|
76
|
+
proc.kill()
|
|
77
|
+
} catch {
|
|
78
|
+
// Process may already be dead
|
|
79
|
+
}
|
|
68
80
|
}
|
|
69
|
-
process.exit(
|
|
81
|
+
process.exit(exitCode)
|
|
70
82
|
}
|
|
71
|
-
process.on("SIGINT", cleanup)
|
|
72
|
-
process.on("SIGTERM", cleanup)
|
|
73
83
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
// Handle SIGINT/SIGTERM to kill all child processes
|
|
85
|
+
process.on("SIGINT", () => killAll(0))
|
|
86
|
+
process.on("SIGTERM", () => killAll(0))
|
|
87
|
+
|
|
88
|
+
// Create a promise for each process that resolves on completion or rejects on failure
|
|
89
|
+
const processPromises = processes.map(async ({ label, proc, prefix }) => {
|
|
90
|
+
const exitCode = await proc.exited
|
|
91
|
+
if (exitCode !== 0) {
|
|
92
|
+
const labelText = label ? ` (${label})` : ""
|
|
93
|
+
console.error(
|
|
94
|
+
`\n${prefix} Process${labelText} exited with code ${exitCode}. Stopping all processes...`,
|
|
95
|
+
)
|
|
96
|
+
throw new Error(`Process failed with exit code ${exitCode}`)
|
|
97
|
+
}
|
|
98
|
+
return { label, exitCode }
|
|
99
|
+
})
|
|
84
100
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
101
|
+
try {
|
|
102
|
+
// Wait for all to succeed - if any fails, it will throw and we catch it
|
|
103
|
+
await Promise.all(processPromises)
|
|
104
|
+
} catch {
|
|
105
|
+
// One process failed - kill all others and exit
|
|
106
|
+
killAll(1)
|
|
89
107
|
}
|
|
90
108
|
}
|