chore: add bun support (#2254)
All checks were successful
Build / build (push) Successful in 1m4s
Build Docker image / docker-arm64 (push) Successful in 1m25s
Build Docker image / docker-amd64 (push) Successful in 1m55s

It definitely has some benefits:
- It starts up insanely quickly compared to Node.
- It can run typescript directly, allow the build step to be reduced to verify/noEmit.

It does not implement NodeJS APIs perfectly, so I've had to add some special handling for Bun, but I think that's okay.

Reviewed-on: #2254
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-06-22 19:58:48 -07:00 committed by Sainan
parent 84f081312b
commit cee622d5e9
4 changed files with 26 additions and 10 deletions

View File

@ -8,8 +8,11 @@
"build": "tsc --incremental --sourceMap && ncp static/webui build/static/webui", "build": "tsc --incremental --sourceMap && ncp static/webui build/static/webui",
"build:dev": "tsc --incremental --sourceMap", "build:dev": "tsc --incremental --sourceMap",
"build-and-start": "npm run build && npm run start", "build-and-start": "npm run build && npm run start",
"build-and-start:bun": "npm run verify && npm run bun-run",
"dev": "node scripts/dev.js", "dev": "node scripts/dev.js",
"dev:bun": "bun scripts/dev.js",
"verify": "tsgo --noEmit", "verify": "tsgo --noEmit",
"bun-run": "bun src/index.ts",
"lint": "eslint --ext .ts .", "lint": "eslint --ext .ts .",
"lint:ci": "eslint --ext .ts --rule \"prettier/prettier: off\" .", "lint:ci": "eslint --ext .ts --rule \"prettier/prettier: off\" .",
"lint:fix": "eslint --fix --ext .ts .", "lint:fix": "eslint --fix --ext .ts .",

View File

@ -14,6 +14,7 @@ args.push("--secret");
args.push(secret); args.push(secret);
let buildproc, runproc; let buildproc, runproc;
const spawnopts = { stdio: "inherit", shell: true };
function run(changedFile) { function run(changedFile) {
if (changedFile) { if (changedFile) {
console.log(`Change to ${changedFile} detected`); console.log(`Change to ${changedFile} detected`);
@ -28,7 +29,8 @@ function run(changedFile) {
runproc = undefined; runproc = undefined;
} }
const thisbuildproc = spawn("npm", ["run", "build:dev"], { stdio: "inherit", shell: true }); const thisbuildproc = spawn("npm", ["run", process.versions.bun ? "verify" : "build:dev"], spawnopts);
const thisbuildstart = Date.now();
buildproc = thisbuildproc; buildproc = thisbuildproc;
buildproc.on("exit", code => { buildproc.on("exit", code => {
if (buildproc !== thisbuildproc) { if (buildproc !== thisbuildproc) {
@ -36,7 +38,8 @@ function run(changedFile) {
} }
buildproc = undefined; buildproc = undefined;
if (code === 0) { if (code === 0) {
runproc = spawn("npm", ["run", "start", "--", ...args], { stdio: "inherit", shell: true }); console.log(`${process.versions.bun ? "Verified" : "Built"} in ${Date.now() - thisbuildstart} ms`);
runproc = spawn("npm", ["run", process.versions.bun ? "bun-run" : "start", "--", ...args], spawnopts);
runproc.on("exit", () => { runproc.on("exit", () => {
runproc = undefined; runproc = undefined;
}); });

View File

@ -5,7 +5,12 @@ import { config, configPath, loadConfig } from "./configService";
import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService"; import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService";
let amnesia = false; let amnesia = false;
fs.watchFile(configPath, () => { fs.watchFile(configPath, (now, then) => {
// https://github.com/oven-sh/bun/issues/20542
if (process.versions.bun && now.mtimeMs == then.mtimeMs) {
return;
}
if (amnesia) { if (amnesia) {
amnesia = false; amnesia = false;
} else { } else {

View File

@ -46,16 +46,21 @@ export const startWebServer = (): void => {
"Access the WebUI in your browser at http://localhost" + (httpPort == 80 ? "" : ":" + httpPort) "Access the WebUI in your browser at http://localhost" + (httpPort == 80 ? "" : ":" + httpPort)
); );
void runWsSelfTest("wss", httpsPort).then(ok => { // https://github.com/oven-sh/bun/issues/20547
if (!ok) { if (!process.versions.bun) {
logger.warn(`WSS self-test failed. The server may not actually be reachable at port ${httpsPort}.`); void runWsSelfTest("wss", httpsPort).then(ok => {
if (process.platform == "win32") { if (!ok) {
logger.warn( logger.warn(
`You can check who actually has that port via powershell: Get-Process -Id (Get-NetTCPConnection -LocalPort ${httpsPort}).OwningProcess` `WSS self-test failed. The server may not actually be reachable at port ${httpsPort}.`
); );
if (process.platform == "win32") {
logger.warn(
`You can check who actually has that port via powershell: Get-Process -Id (Get-NetTCPConnection -LocalPort ${httpsPort}).OwningProcess`
);
}
} }
} });
}); }
}); });
}); });
}; };