social bookmarking for atproto
1/*
2 * clippr: a social bookmarking service for the AT Protocol
3 * Copyright (c) 2025 clippr contributors.
4 * SPDX-License-Identifier: AGPL-3.0-only
5 */
6
7import { serve, type ServerType } from "@hono/node-server";
8import { Config } from "./config.js";
9import {
10 readFromFirehose,
11 startFirehose,
12 stopFirehose,
13} from "./network/jetstream.js";
14import app from "./server.js";
15import { Database } from "./db/database.js";
16import Logger from "./logger.js";
17
18async function main() {
19 const logger = Logger;
20 logger.info(`Clippr-BE v${process.env.npm_package_version} starting...`);
21
22 // Config is already loaded into the app (when preparing logger)
23 const config = Config.getInstance().getConfig();
24
25 logger.verbose("Initializing database...");
26 Database.getInstance();
27
28 logger.verbose("Initializing Jetstream connection...");
29 startFirehose();
30 readFromFirehose();
31
32 logger.verbose("Starting XRPC server...");
33 const server: ServerType = serve({
34 port: config.port,
35 hostname: config.hostname,
36 fetch: app.fetch,
37 });
38
39 logger.info(
40 `XRPC server launched at http://${config.hostname}:${config.port}`,
41 );
42
43 process.removeAllListeners("SIGINT");
44 process.removeAllListeners("SIGTERM");
45
46 process.once("SIGINT", () => gracefulShutdown("SIGINT"));
47 process.once("SIGTERM", () => gracefulShutdown("SIGTERM"));
48
49 function gracefulShutdown(signal: string) {
50 logger.info(`Received ${signal}, shutting down...`);
51 server.close();
52 stopFirehose();
53 logger.info("Bye!");
54 process.exit(0);
55 }
56}
57
58main();