silgi 0.43.8 → 0.43.9
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/cli/commands/run.mjs +41 -103
- package/dist/package.mjs +1 -1
- package/dist/types/kits.d.mts +3 -3
- package/package.json +1 -1
|
@@ -4,14 +4,39 @@ import prepare_default from "./prepare.mjs";
|
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
import { useSilgiCLI } from "silgi";
|
|
6
6
|
import { version } from "silgi/meta";
|
|
7
|
-
import {
|
|
7
|
+
import { runCommand } from "citty";
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
9
9
|
import { platform } from "node:os";
|
|
10
10
|
import { promisify } from "node:util";
|
|
11
11
|
import treeKill from "tree-kill";
|
|
12
12
|
|
|
13
13
|
//#region src/cli/commands/run.ts
|
|
14
|
-
const
|
|
14
|
+
const treeKillAsync = promisify(treeKill);
|
|
15
|
+
function waitForProcess(proc) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
proc.on("exit", (code) => resolve(code ?? 0));
|
|
18
|
+
proc.on("error", (err) => reject(err));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function killProcessTree(pid, signal = "SIGTERM") {
|
|
22
|
+
try {
|
|
23
|
+
await treeKillAsync(pid, signal);
|
|
24
|
+
return true;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
consola.warn(`Failed to kill process tree for PID ${pid}:`, error);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function setupSignalHandlers(onSignal) {
|
|
31
|
+
const signals = [
|
|
32
|
+
"SIGINT",
|
|
33
|
+
"SIGTERM",
|
|
34
|
+
"SIGHUP"
|
|
35
|
+
];
|
|
36
|
+
signals.forEach((signal) => process.on(signal, () => onSignal(signal)));
|
|
37
|
+
return () => signals.forEach((signal) => process.off(signal, () => onSignal(signal)));
|
|
38
|
+
}
|
|
39
|
+
const command = {
|
|
15
40
|
meta: {
|
|
16
41
|
name: "dev",
|
|
17
42
|
description: "Start the development server for the project",
|
|
@@ -35,93 +60,20 @@ const command = defineCommand({
|
|
|
35
60
|
const silgi = useSilgiCLI();
|
|
36
61
|
const startCommand = args.command || rawArgs[0];
|
|
37
62
|
let childPid = null;
|
|
38
|
-
let childProcess = null;
|
|
39
63
|
let hasExited = false;
|
|
40
|
-
let exitTimeout = null;
|
|
41
|
-
const signalHandlers = [];
|
|
42
|
-
const treeKillAsync = promisify(treeKill);
|
|
43
|
-
const cleanupResources = async () => {};
|
|
44
64
|
const cleanupAndExit = async (code = 0) => {
|
|
45
65
|
if (hasExited) return;
|
|
46
66
|
hasExited = true;
|
|
47
|
-
|
|
48
|
-
clearTimeout(exitTimeout);
|
|
49
|
-
exitTimeout = null;
|
|
50
|
-
}
|
|
51
|
-
try {
|
|
52
|
-
await cleanupResources();
|
|
53
|
-
} catch (error) {
|
|
54
|
-
consola.warn("Error during cleanup:", error instanceof Error ? error.message : String(error));
|
|
55
|
-
} finally {
|
|
56
|
-
signalHandlers.forEach((removeHandler) => removeHandler());
|
|
57
|
-
signalHandlers.length = 0;
|
|
58
|
-
process.exit(code);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const killProcessTree = async (pid, signal = "SIGTERM") => {
|
|
62
|
-
try {
|
|
63
|
-
await treeKillAsync(pid, signal);
|
|
64
|
-
return true;
|
|
65
|
-
} catch (error) {
|
|
66
|
-
consola.warn(`Failed to kill process tree for PID ${pid}:`, error instanceof Error ? error.message : String(error));
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const handleSignal = async (signal, watcher) => {
|
|
71
|
-
if (hasExited) return;
|
|
72
|
-
consola.info(`Received ${signal}, terminating process...`);
|
|
73
|
-
if (watcher && typeof watcher.close === "function") try {
|
|
74
|
-
await watcher.close();
|
|
75
|
-
} catch (error) {
|
|
76
|
-
consola.warn("Error closing watcher:", error instanceof Error ? error.message : String(error));
|
|
77
|
-
}
|
|
78
|
-
if (childPid) try {
|
|
79
|
-
await killProcessTree(childPid, signal);
|
|
80
|
-
exitTimeout = setTimeout(async () => {
|
|
81
|
-
if (hasExited) return;
|
|
82
|
-
consola.warn("Process did not exit gracefully, forcing termination...");
|
|
83
|
-
try {
|
|
84
|
-
await killProcessTree(childPid, "SIGKILL");
|
|
85
|
-
} finally {
|
|
86
|
-
await cleanupAndExit(1);
|
|
87
|
-
}
|
|
88
|
-
}, 3e3);
|
|
89
|
-
if (childProcess) await new Promise((resolve) => {
|
|
90
|
-
childProcess.on("exit", () => resolve());
|
|
91
|
-
childProcess.on("error", () => resolve());
|
|
92
|
-
});
|
|
93
|
-
clearTimeout(exitTimeout);
|
|
94
|
-
exitTimeout = null;
|
|
95
|
-
await cleanupAndExit(0);
|
|
96
|
-
} catch (error) {
|
|
97
|
-
consola.error("Error during process termination:", error instanceof Error ? error.message : String(error));
|
|
98
|
-
await cleanupAndExit(1);
|
|
99
|
-
}
|
|
100
|
-
else await cleanupAndExit(0);
|
|
101
|
-
};
|
|
102
|
-
const setupSignalHandlers = (watcher) => {
|
|
103
|
-
const signals = [
|
|
104
|
-
"SIGINT",
|
|
105
|
-
"SIGTERM",
|
|
106
|
-
"SIGHUP"
|
|
107
|
-
];
|
|
108
|
-
signals.forEach((signal) => {
|
|
109
|
-
const handler = () => {
|
|
110
|
-
process.off(signal, handler);
|
|
111
|
-
handleSignal(signal, watcher).catch((error) => {
|
|
112
|
-
consola.error("Error in signal handler:", error instanceof Error ? error.message : String(error));
|
|
113
|
-
process.exit(1);
|
|
114
|
-
});
|
|
115
|
-
};
|
|
116
|
-
signalHandlers.push(() => {
|
|
117
|
-
process.off(signal, handler);
|
|
118
|
-
});
|
|
119
|
-
process.on(signal, handler);
|
|
120
|
-
});
|
|
67
|
+
process.exit(code);
|
|
121
68
|
};
|
|
122
69
|
try {
|
|
123
70
|
const watcher = await watchDev();
|
|
124
|
-
setupSignalHandlers(
|
|
71
|
+
const removeSignalHandlers = setupSignalHandlers(async (signal) => {
|
|
72
|
+
consola.info(`Received ${signal}, terminating process...`);
|
|
73
|
+
if (watcher?.close) await watcher.close().catch(() => {});
|
|
74
|
+
if (childPid) await killProcessTree(childPid, signal);
|
|
75
|
+
await cleanupAndExit(0);
|
|
76
|
+
});
|
|
125
77
|
consola.info(`Starting command: nr ${startCommand}`);
|
|
126
78
|
const isWindows = platform() === "win32";
|
|
127
79
|
const proc = spawn("nr", [startCommand], {
|
|
@@ -130,34 +82,20 @@ const command = defineCommand({
|
|
|
130
82
|
cwd: process.cwd(),
|
|
131
83
|
...!isWindows && { detached: true }
|
|
132
84
|
});
|
|
133
|
-
childProcess = proc;
|
|
134
85
|
childPid = proc.pid ?? null;
|
|
135
86
|
if (!childPid) throw new Error("Failed to start child process: no PID assigned");
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (code !== null && code !== 0) consola.error(`Process exited with code ${code}`);
|
|
142
|
-
if (!hasExited) cleanupAndExit(code || 0).catch(() => {});
|
|
143
|
-
});
|
|
144
|
-
try {
|
|
145
|
-
await proc;
|
|
146
|
-
consola.success(`Process exited successfully.`);
|
|
147
|
-
cleanupAndExit(0);
|
|
148
|
-
} catch (procError) {
|
|
149
|
-
const exitCode = procError && typeof procError.exitCode === "number" ? procError.exitCode : 1;
|
|
150
|
-
consola.error(`Process exited with code: ${exitCode}`);
|
|
151
|
-
if (silgi.options.debug) consola.withTag("silgi").error("Error while running the command", procError);
|
|
152
|
-
cleanupAndExit(exitCode);
|
|
153
|
-
}
|
|
87
|
+
const exitCode = await waitForProcess(proc);
|
|
88
|
+
if (exitCode !== 0) consola.error(`Process exited with code ${exitCode}`);
|
|
89
|
+
else consola.success("Process exited successfully.");
|
|
90
|
+
removeSignalHandlers();
|
|
91
|
+
await cleanupAndExit(exitCode);
|
|
154
92
|
} catch (error) {
|
|
155
93
|
consola.error(`Failed to start the development server: ${error instanceof Error ? error.message : error}`);
|
|
156
94
|
if (silgi.options.debug) consola.withTag("silgi").error("Error while running the command", error);
|
|
157
|
-
cleanupAndExit(1);
|
|
95
|
+
await cleanupAndExit(1);
|
|
158
96
|
}
|
|
159
97
|
}
|
|
160
|
-
}
|
|
98
|
+
};
|
|
161
99
|
var run_default = command;
|
|
162
100
|
|
|
163
101
|
//#endregion
|
package/dist/package.mjs
CHANGED
package/dist/types/kits.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { SilgiCLI } from "./silgiCLI.mjs";
|
|
2
2
|
import { BuildSilgi } from "./silgi.mjs";
|
|
3
3
|
import { ESMCodeGenOptions, ESMImport } from "knitwork";
|
|
4
|
-
import * as
|
|
4
|
+
import * as h33 from "h3";
|
|
5
5
|
import { PresetName } from "silgi/presets";
|
|
6
|
-
import * as
|
|
6
|
+
import * as nitropack_types1 from "nitropack/types";
|
|
7
7
|
|
|
8
8
|
//#region src/types/kits.d.ts
|
|
9
9
|
interface SilgiCommands {}
|
|
@@ -24,7 +24,7 @@ interface GenImport {
|
|
|
24
24
|
imports: ESMImport | ESMImport[];
|
|
25
25
|
options?: ESMCodeGenOptions;
|
|
26
26
|
}
|
|
27
|
-
type Framework<T extends PresetName> = T extends "nitro" ?
|
|
27
|
+
type Framework<T extends PresetName> = T extends "nitro" ? nitropack_types1.NitroApp : T extends "nuxt" ? nitropack_types1.NitroApp : T extends "h3" ? h33.Router : never;
|
|
28
28
|
interface DefineFrameworkOptions<T extends PresetName> extends Omit<BuildSilgi, "framework"> {
|
|
29
29
|
framework: Framework<T>;
|
|
30
30
|
}
|