Repository Public
1/** Entry point: validate config, migrate, build, listen, shut down gracefully. */2import { buildServer } from './app.js';3import { loadConfig } from './config.js';4import { migrate } from './migrate.js';56async function main(): Promise<void> {7 const config = loadConfig();8 await migrate(config.databaseUrl);9 const server = await buildServer(config);10 await server.app.listen({ port: config.port, host: config.host });11 server.startBackground();1213 let closing = false;14 const shutdown = (signal: string): void => {15 if (closing) return;16 closing = true;17 server.app.log.info({ signal }, 'shutting down');18 const force = setTimeout(() => process.exit(1), 10_000);19 force.unref();20 // Stop accepting, close WebSockets with 1001, end the pool.21 server.close().then(22 () => process.exit(0),23 () => process.exit(1),24 );25 };26 process.on('SIGTERM', () => shutdown('SIGTERM'));27 process.on('SIGINT', () => shutdown('SIGINT'));28}2930main().catch((err: unknown) => {31 // Configuration / startup errors only: messages never contain secret values.32 console.error((err as Error).message);33 process.exit(1);34});35