perf(macos): compile embedded gateway with bytecode

This commit is contained in:
Peter Steinberger
2025-12-19 22:11:41 +01:00
parent 96be450cbb
commit 836f645621
3 changed files with 114 additions and 112 deletions

View File

@@ -138,6 +138,7 @@ if [[ "${SKIP_GATEWAY_PACKAGE:-0}" != "1" ]]; then
BUN_OUT="$RELAY_DIR/clawdis-gateway" BUN_OUT="$RELAY_DIR/clawdis-gateway"
bun build "$ROOT_DIR/dist/macos/gateway-daemon.js" \ bun build "$ROOT_DIR/dist/macos/gateway-daemon.js" \
--compile \ --compile \
--bytecode \
--outfile "$BUN_OUT" \ --outfile "$BUN_OUT" \
-e playwright-core \ -e playwright-core \
-e electron \ -e electron \

View File

@@ -79,10 +79,7 @@ function stripFrontMatter(content: string): string {
return trimmed; return trimmed;
} }
async function loadTemplate( async function loadTemplate(name: string, fallback: string): Promise<string> {
name: string,
fallback: string,
): Promise<string> {
const templatePath = path.join(TEMPLATE_DIR, name); const templatePath = path.join(TEMPLATE_DIR, name);
try { try {
const content = await fs.readFile(templatePath, "utf-8"); const content = await fs.readFile(templatePath, "utf-8");

View File

@@ -19,74 +19,75 @@ function hasFlag(args: string[], flag: string): boolean {
const args = process.argv.slice(2); const args = process.argv.slice(2);
if (hasFlag(args, "--version") || hasFlag(args, "-v")) { type GatewayWsLogStyle = "auto" | "full" | "compact";
async function main() {
if (hasFlag(args, "--version") || hasFlag(args, "-v")) {
// Match `clawdis --version` behavior for Swift env/version checks. // Match `clawdis --version` behavior for Swift env/version checks.
// Keep output a single line. // Keep output a single line.
console.log(BUNDLED_VERSION); console.log(BUNDLED_VERSION);
process.exit(0); process.exit(0);
} }
type GatewayWsLogStyle = "auto" | "full" | "compact"; const [
const [
{ loadConfig }, { loadConfig },
{ startGatewayServer }, { startGatewayServer },
{ setGatewayWsLogStyle }, { setGatewayWsLogStyle },
{ setVerbose }, { setVerbose },
{ defaultRuntime }, { defaultRuntime },
] = await Promise.all([ ] = await Promise.all([
import("../config/config.js"), import("../config/config.js"),
import("../gateway/server.js"), import("../gateway/server.js"),
import("../gateway/ws-logging.js"), import("../gateway/ws-logging.js"),
import("../globals.js"), import("../globals.js"),
import("../runtime.js"), import("../runtime.js"),
]); ]);
setVerbose(hasFlag(args, "--verbose")); setVerbose(hasFlag(args, "--verbose"));
const wsLogRaw = ( const wsLogRaw = (
hasFlag(args, "--compact") ? "compact" : argValue(args, "--ws-log") hasFlag(args, "--compact") ? "compact" : argValue(args, "--ws-log")
) as string | undefined; ) as string | undefined;
const wsLogStyle: GatewayWsLogStyle = const wsLogStyle: GatewayWsLogStyle =
wsLogRaw === "compact" ? "compact" : wsLogRaw === "full" ? "full" : "auto"; wsLogRaw === "compact" ? "compact" : wsLogRaw === "full" ? "full" : "auto";
setGatewayWsLogStyle(wsLogStyle); setGatewayWsLogStyle(wsLogStyle);
const portRaw = const portRaw =
argValue(args, "--port") ?? process.env.CLAWDIS_GATEWAY_PORT ?? "18789"; argValue(args, "--port") ?? process.env.CLAWDIS_GATEWAY_PORT ?? "18789";
const port = Number.parseInt(portRaw, 10); const port = Number.parseInt(portRaw, 10);
if (Number.isNaN(port) || port <= 0) { if (Number.isNaN(port) || port <= 0) {
defaultRuntime.error(`Invalid --port (${portRaw})`); defaultRuntime.error(`Invalid --port (${portRaw})`);
process.exit(1); process.exit(1);
} }
const cfg = loadConfig(); const cfg = loadConfig();
const bindRaw = const bindRaw =
argValue(args, "--bind") ?? argValue(args, "--bind") ??
process.env.CLAWDIS_GATEWAY_BIND ?? process.env.CLAWDIS_GATEWAY_BIND ??
cfg.gateway?.bind ?? cfg.gateway?.bind ??
"loopback"; "loopback";
const bind = const bind =
bindRaw === "loopback" || bindRaw === "loopback" ||
bindRaw === "tailnet" || bindRaw === "tailnet" ||
bindRaw === "lan" || bindRaw === "lan" ||
bindRaw === "auto" bindRaw === "auto"
? bindRaw ? bindRaw
: null; : null;
if (!bind) { if (!bind) {
defaultRuntime.error( defaultRuntime.error(
'Invalid --bind (use "loopback", "tailnet", "lan", or "auto")', 'Invalid --bind (use "loopback", "tailnet", "lan", or "auto")',
); );
process.exit(1); process.exit(1);
} }
const token = argValue(args, "--token"); const token = argValue(args, "--token");
if (token) process.env.CLAWDIS_GATEWAY_TOKEN = token; if (token) process.env.CLAWDIS_GATEWAY_TOKEN = token;
let server: Awaited<ReturnType<typeof startGatewayServer>> | null = null; let server: Awaited<ReturnType<typeof startGatewayServer>> | null = null;
let shuttingDown = false; let shuttingDown = false;
let forceExitTimer: ReturnType<typeof setTimeout> | null = null; let forceExitTimer: ReturnType<typeof setTimeout> | null = null;
const shutdown = (signal: string) => { const shutdown = (signal: string) => {
process.removeListener("SIGTERM", onSigterm); process.removeListener("SIGTERM", onSigterm);
process.removeListener("SIGINT", onSigint); process.removeListener("SIGINT", onSigint);
@@ -116,20 +117,23 @@ const shutdown = (signal: string) => {
process.exit(0); process.exit(0);
} }
})(); })();
}; };
const onSigterm = () => shutdown("SIGTERM"); const onSigterm = () => shutdown("SIGTERM");
const onSigint = () => shutdown("SIGINT"); const onSigint = () => shutdown("SIGINT");
process.once("SIGTERM", onSigterm); process.once("SIGTERM", onSigterm);
process.once("SIGINT", onSigint); process.once("SIGINT", onSigint);
try { try {
server = await startGatewayServer(port, { bind }); server = await startGatewayServer(port, { bind });
} catch (err) { } catch (err) {
defaultRuntime.error(`Gateway failed to start: ${String(err)}`); defaultRuntime.error(`Gateway failed to start: ${String(err)}`);
process.exit(1); process.exit(1);
}
// Keep process alive
await new Promise<never>(() => {});
} }
// Keep process alive void main();
await new Promise<never>(() => {});