/** * earth-now.co * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * File: apps/api/src/server.ts * Purpose: Fastify app factory (buildApp for tests) + production listener on PORT (default 4000) */ import { pathToFileURL } from "node:url"; import Fastify, { type FastifyInstance } from "fastify"; import { startOpenNotifyPoller } from "./pollers/open-notify.js"; import { startUsgsPoller } from "./pollers/usgs.js"; import { registerRoutes } from "./routes.js"; import { ModelStore } from "./store.js"; export interface BuildAppOptions { logger?: boolean; /** Start the RT pollers (additionally gated by ENABLE_RT_POLLERS !== "0"). */ pollers?: boolean; } export async function buildApp(options: BuildAppOptions = {}): Promise { const app = Fastify({ logger: options.logger ?? true }); const store = new ModelStore(); store.boot(); await registerRoutes(app, store); if (options.pollers ?? true) { const handles = [startUsgsPoller(store), startOpenNotifyPoller(store)]; app.addHook("onClose", async () => { for (const handle of handles) handle.stop(); }); } return app; } const isMain = process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href; if (isMain) { const app = await buildApp(); const port = Number(process.env.PORT ?? 4000); try { await app.listen({ port, host: "0.0.0.0" }); } catch (err) { app.log.error(err); process.exit(1); } }