An ATproto social media client -- with an independent Appview.
at main 50 lines 1.3 kB view raw
1import events from 'node:events' 2import type http from 'node:http' 3 4import cors from 'cors' 5import express from 'express' 6import {createHttpTerminator, type HttpTerminator} from 'http-terminator' 7 8import {type Config} from './config.js' 9import {AppContext} from './context.js' 10import i18n from './i18n.js' 11import {default as routes, errorHandler} from './routes/index.js' 12 13export * from './config.js' 14export * from './db/index.js' 15export * from './logger.js' 16 17export class LinkService { 18 public server?: http.Server 19 private terminator?: HttpTerminator 20 21 constructor( 22 public app: express.Application, 23 public ctx: AppContext, 24 ) {} 25 26 static async create(cfg: Config): Promise<LinkService> { 27 let app = express() 28 app.use(cors()) 29 app.use(i18n.init) 30 31 const ctx = await AppContext.fromConfig(cfg) 32 app = routes(ctx, app) 33 app.use(errorHandler) 34 35 return new LinkService(app, ctx) 36 } 37 38 async start() { 39 this.server = this.app.listen(this.ctx.cfg.service.port) 40 this.server.keepAliveTimeout = 90000 41 this.terminator = createHttpTerminator({server: this.server}) 42 await events.once(this.server, 'listening') 43 } 44 45 async destroy() { 46 this.ctx.abortController.abort() 47 await this.terminator?.terminate() 48 await this.ctx.db.close() 49 } 50}