@paleo/workspace 0.14.0 → 0.14.2
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/dist/dev-server.d.ts +6 -0
- package/dist/dev-server.js +49 -21
- package/package.json +1 -1
package/dist/dev-server.d.ts
CHANGED
|
@@ -33,6 +33,12 @@ export interface DevServerSummaryContext {
|
|
|
33
33
|
}[];
|
|
34
34
|
}
|
|
35
35
|
export declare function runDevServer(config: DevServerConfig): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Poll the foreground's own spawn PIDs; when none remain alive, the servers were stopped from
|
|
38
|
+
* outside this process (`dev down`, `down --all`, eviction, or a manual kill). Fires `onStopped`
|
|
39
|
+
* once so the foreground can exit instead of hanging on dead servers.
|
|
40
|
+
*/
|
|
41
|
+
export declare function watchForExternalStop(pids: number[], onStopped: () => void, isAlive?: (pid: number) => boolean, intervalMs?: number): NodeJS.Timeout | undefined;
|
|
36
42
|
export type WorktreeReadyCheck = {
|
|
37
43
|
ok: true;
|
|
38
44
|
} | {
|
package/dist/dev-server.js
CHANGED
|
@@ -82,17 +82,7 @@ async function start(config, mainWorktree, options) {
|
|
|
82
82
|
if (await runStartChecks(config, mainWorktree, ctx, options))
|
|
83
83
|
return;
|
|
84
84
|
const state = { spawnPids: {}, startedCallbacks: [] };
|
|
85
|
-
|
|
86
|
-
await spawnAndAwait(config, ctx, state);
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
await rollbackStart(state.spawnPids, state.startedCallbacks, ctx);
|
|
90
|
-
if (err instanceof StartupError) {
|
|
91
|
-
handleStartupFailure(err);
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
throw err;
|
|
95
|
-
}
|
|
85
|
+
await spawnWithRollback(config, ctx, state);
|
|
96
86
|
const slot = registerStartedServer(config, mainWorktree, state.spawnPids);
|
|
97
87
|
printStartSummary(config, slot, state.spawnPids);
|
|
98
88
|
}
|
|
@@ -121,21 +111,22 @@ async function runForeground(config, mainWorktree, options) {
|
|
|
121
111
|
process.on("SIGTERM", onSignal);
|
|
122
112
|
if (await runStartChecks(config, mainWorktree, ctx, options))
|
|
123
113
|
process.exit(0);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await rollbackStart(state.spawnPids, state.startedCallbacks, ctx);
|
|
129
|
-
if (err instanceof StartupError) {
|
|
130
|
-
handleStartupFailure(err);
|
|
131
|
-
process.exit(1);
|
|
132
|
-
}
|
|
133
|
-
throw err;
|
|
114
|
+
// A signal during startup hands teardown to onSignal (rollback + exit 130); block so we
|
|
115
|
+
// neither roll back twice nor register a server that is being torn down.
|
|
116
|
+
if (!(await spawnWithRollback(config, ctx, state, () => shuttingDown))) {
|
|
117
|
+
await new Promise(() => { });
|
|
134
118
|
}
|
|
135
119
|
const slot = registerStartedServer(config, mainWorktree, state.spawnPids);
|
|
136
120
|
started = true;
|
|
137
121
|
printStartSummary(config, slot, state.spawnPids);
|
|
138
122
|
tailLogs(config, state.spawnPids);
|
|
123
|
+
watchForExternalStop(Object.values(state.spawnPids), () => {
|
|
124
|
+
if (shuttingDown)
|
|
125
|
+
return;
|
|
126
|
+
shuttingDown = true;
|
|
127
|
+
console.log("\nDev-server stopped externally (e.g. `dev down`). Exiting.");
|
|
128
|
+
process.exit(0);
|
|
129
|
+
});
|
|
139
130
|
await new Promise(() => { });
|
|
140
131
|
}
|
|
141
132
|
async function shutdownForeground(config, mainWorktree) {
|
|
@@ -153,6 +144,26 @@ async function runStartChecks(config, mainWorktree, ctx, { evict, restart }) {
|
|
|
153
144
|
await checkPortsFree(config.servers, ctx.cwd);
|
|
154
145
|
return false;
|
|
155
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Spawn and await readiness, rolling back on failure. Returns `false` when `isAborted` reports a
|
|
149
|
+
* concurrent shutdown — the caller must then yield teardown to whoever set it, not proceed.
|
|
150
|
+
*/
|
|
151
|
+
async function spawnWithRollback(config, ctx, state, isAborted = () => false) {
|
|
152
|
+
try {
|
|
153
|
+
await spawnAndAwait(config, ctx, state);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
if (isAborted())
|
|
157
|
+
return false;
|
|
158
|
+
await rollbackStart(state.spawnPids, state.startedCallbacks, ctx);
|
|
159
|
+
if (err instanceof StartupError) {
|
|
160
|
+
handleStartupFailure(err);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
165
|
+
return !isAborted();
|
|
166
|
+
}
|
|
156
167
|
async function spawnAndAwait(config, ctx, state) {
|
|
157
168
|
for (const server of config.servers) {
|
|
158
169
|
console.log(`Starting ${server.name} dev server...`);
|
|
@@ -203,6 +214,7 @@ function printStartSummary(config, slot, spawnPids) {
|
|
|
203
214
|
}
|
|
204
215
|
}
|
|
205
216
|
const TAIL_INTERVAL_MS = 300;
|
|
217
|
+
const LIVENESS_POLL_MS = 1000;
|
|
206
218
|
function tailLogs(config, spawnPids) {
|
|
207
219
|
const names = Object.keys(spawnPids);
|
|
208
220
|
const prefixed = names.length > 1;
|
|
@@ -231,6 +243,22 @@ function followLogFile(path, prefix) {
|
|
|
231
243
|
process.stdout.write(prefix === "" ? text : text.replace(/^(?=.)/gm, prefix));
|
|
232
244
|
}, TAIL_INTERVAL_MS);
|
|
233
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Poll the foreground's own spawn PIDs; when none remain alive, the servers were stopped from
|
|
248
|
+
* outside this process (`dev down`, `down --all`, eviction, or a manual kill). Fires `onStopped`
|
|
249
|
+
* once so the foreground can exit instead of hanging on dead servers.
|
|
250
|
+
*/
|
|
251
|
+
export function watchForExternalStop(pids, onStopped, isAlive = isProcessAlive, intervalMs = LIVENESS_POLL_MS) {
|
|
252
|
+
if (pids.length === 0)
|
|
253
|
+
return;
|
|
254
|
+
const timer = setInterval(() => {
|
|
255
|
+
if (pids.some(isAlive))
|
|
256
|
+
return;
|
|
257
|
+
clearInterval(timer);
|
|
258
|
+
onStopped();
|
|
259
|
+
}, intervalMs);
|
|
260
|
+
return timer;
|
|
261
|
+
}
|
|
234
262
|
async function rollbackStart(spawnPids, startedCallbacks, ctx) {
|
|
235
263
|
console.error("\nStopping dev servers...");
|
|
236
264
|
for (const pid of Object.values(spawnPids)) {
|