Scratch space for learning atproto app development
1import events from "node:events"; 2import type http from "node:http"; 3import cors from "cors"; 4import express, { type Express } from "express"; 5import helmet from "helmet"; 6import { pino } from "pino"; 7 8import { createDb, migrateToLatest } from "#/db"; 9import { env } from "#/env"; 10import { Ingester } from "#/firehose/ingester"; 11import errorHandler from "#/middleware/errorHandler"; 12import requestLogger from "#/middleware/requestLogger"; 13import { createRouter } from "#/routes"; 14import type { AppContext } from "./config"; 15 16export class Server { 17 constructor( 18 public app: express.Application, 19 public server: http.Server, 20 public ctx: AppContext 21 ) {} 22 23 static async create() { 24 const { NODE_ENV, HOST, PORT } = env; 25 26 const logger = pino({ name: "server start" }); 27 const db = createDb(":memory:"); 28 await migrateToLatest(db); 29 const ingester = new Ingester(db); 30 ingester.start(); 31 const ctx = { 32 db, 33 ingester, 34 logger, 35 }; 36 37 const app: Express = express(); 38 39 // Set the application to trust the reverse proxy 40 app.set("trust proxy", true); 41 42 // TODO: middleware for sqlite server 43 // TODO: middleware for OAuth 44 45 // Middlewares 46 app.use(express.json()); 47 app.use(express.urlencoded({ extended: true })); 48 app.use(cors({ origin: env.CORS_ORIGIN, credentials: true })); 49 app.use(helmet()); 50 51 // Request logging 52 app.use(requestLogger); 53 54 // Routes 55 const router = createRouter(ctx); 56 app.use(router); 57 58 // Error handlers 59 app.use(errorHandler()); 60 61 const server = app.listen(env.PORT); 62 await events.once(server, "listening"); 63 logger.info(`Server (${NODE_ENV}) running on port http://${HOST}:${PORT}`); 64 65 return new Server(app, server, ctx); 66 } 67 68 async close() { 69 this.ctx.logger.info("sigint received, shutting down"); 70 this.ctx.ingester.destroy(); 71 return new Promise<void>((resolve) => { 72 this.server.close(() => { 73 this.ctx.logger.info("server closed"); 74 resolve(); 75 }); 76 }); 77 } 78}