-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdev.mjs
More file actions
executable file
·129 lines (114 loc) · 2.78 KB
/
dev.mjs
File metadata and controls
executable file
·129 lines (114 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env node
import { execFileSync, spawn } from "node:child_process";
import { createWriteStream, writeFileSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const SERVER_BIN = resolve(ROOT, "build/simdeck");
const LOG_PATH = resolve(ROOT, "build/cli.log");
const SERVER_PORT = "4311";
function findListeningPids(port) {
try {
const output = execFileSync(
"lsof",
["-t", `-iTCP:${port}`, "-sTCP:LISTEN"],
{
cwd: ROOT,
encoding: "utf8",
},
).trim();
return output
.split(/\s+/)
.map((value) => Number.parseInt(value, 10))
.filter((value) => Number.isInteger(value));
} catch {
return [];
}
}
function commandForPid(pid) {
try {
return execFileSync("ps", ["-o", "command=", "-p", String(pid)], {
cwd: ROOT,
encoding: "utf8",
}).trim();
} catch {
return "";
}
}
function isManagedCliProcess(pid) {
const command = commandForPid(pid);
return (
command.includes(SERVER_BIN) ||
command.includes("simdeck daemon run") ||
command.includes("simdeck-bin")
);
}
function stopStaleCliProcesses() {
const stalePids = new Set([
...findListeningPids(4311),
...findListeningPids(4312),
]);
for (const pid of stalePids) {
if (pid === process.pid || !isManagedCliProcess(pid)) {
continue;
}
try {
process.kill(pid, "SIGTERM");
} catch {
// Ignore races with already-exited processes.
}
}
}
stopStaleCliProcesses();
writeFileSync(LOG_PATH, "");
const logStream = createWriteStream(LOG_PATH);
console.log(`[server] serving on :${SERVER_PORT} — logs: build/cli.log`);
const cli = spawn(
SERVER_BIN,
[
"daemon",
"run",
"--project-root",
ROOT,
"--metadata-path",
resolve(ROOT, "build/dev-daemon.json"),
"--port",
SERVER_PORT,
"--access-token",
"dev",
],
{
stdio: ["ignore", "pipe", "pipe"],
cwd: ROOT,
},
);
cli.stdout.pipe(logStream);
cli.stderr.pipe(logStream);
const vite = spawn("npx", ["vite", "--host", "127.0.0.1"], {
stdio: "inherit",
cwd: resolve(ROOT, "client"),
});
function cleanup() {
cli.kill();
vite.kill();
logStream.end();
}
process.on("SIGINT", cleanup);
process.on("SIGTERM", cleanup);
cli.on("error", (error) => {
console.error(`[server] failed to start: ${error.message}`);
vite.kill();
process.exit(1);
});
cli.on("exit", (code, signal) => {
const reason =
code == null ? `signal ${signal ?? "unknown"}` : `code ${code}`;
console.log(`[server] exited (${reason})`);
vite.kill();
process.exit(code ?? 1);
});
vite.on("exit", (code) => {
console.log(`[vite] exited (${code})`);
cli.kill();
process.exit(code ?? 1);
});