chore: move all services inside the apps folder (#7321)
* chore: move all services inside the apps folder * chore: rename apiserver to server
This commit is contained in:
parent
6000639921
commit
944b873184
3442 changed files with 1 additions and 4 deletions
129
apps/live/src/server.ts
Normal file
129
apps/live/src/server.ts
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
import compression from "compression";
|
||||
import cors from "cors";
|
||||
import expressWs from "express-ws";
|
||||
import express, { Request, Response } from "express";
|
||||
import helmet from "helmet";
|
||||
// hocuspocus server
|
||||
import { getHocusPocusServer } from "@/core/hocuspocus-server.js";
|
||||
// helpers
|
||||
import { convertHTMLDocumentToAllFormats } from "@/core/helpers/convert-document.js";
|
||||
import { logger, manualLogger } from "@/core/helpers/logger.js";
|
||||
// types
|
||||
import { TConvertDocumentRequestBody } from "@/core/types/common.js";
|
||||
|
||||
export class Server {
|
||||
private app: any;
|
||||
private router: any;
|
||||
private hocuspocusServer: any;
|
||||
private serverInstance: any;
|
||||
|
||||
constructor() {
|
||||
this.app = express();
|
||||
this.router = express.Router();
|
||||
expressWs(this.app);
|
||||
this.app.set("port", process.env.PORT || 3000);
|
||||
this.setupMiddleware();
|
||||
this.setupHocusPocus();
|
||||
this.setupRoutes();
|
||||
}
|
||||
|
||||
private setupMiddleware() {
|
||||
// Security middleware
|
||||
this.app.use(helmet());
|
||||
// Middleware for response compression
|
||||
this.app.use(compression({ level: 6, threshold: 5 * 1000 }));
|
||||
// Logging middleware
|
||||
this.app.use(logger);
|
||||
// Body parsing middleware
|
||||
this.app.use(express.json());
|
||||
this.app.use(express.urlencoded({ extended: true }));
|
||||
// cors middleware
|
||||
this.app.use(cors());
|
||||
this.app.use(process.env.LIVE_BASE_PATH || "/live", this.router);
|
||||
}
|
||||
|
||||
private async setupHocusPocus() {
|
||||
this.hocuspocusServer = await getHocusPocusServer().catch((err) => {
|
||||
manualLogger.error("Failed to initialize HocusPocusServer:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
private setupRoutes() {
|
||||
this.router.get("/health", (_req: Request, res: Response) => {
|
||||
res.status(200).json({ status: "OK" });
|
||||
});
|
||||
|
||||
this.router.ws("/collaboration", (ws: any, req: Request) => {
|
||||
try {
|
||||
this.hocuspocusServer.handleConnection(ws, req);
|
||||
} catch (err) {
|
||||
manualLogger.error("WebSocket connection error:", err);
|
||||
ws.close();
|
||||
}
|
||||
});
|
||||
|
||||
this.router.post("/convert-document", (req: Request, res: Response) => {
|
||||
const { description_html, variant } = req.body as TConvertDocumentRequestBody;
|
||||
try {
|
||||
if (description_html === undefined || variant === undefined) {
|
||||
res.status(400).send({
|
||||
message: "Missing required fields",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { description, description_binary } = convertHTMLDocumentToAllFormats({
|
||||
document_html: description_html,
|
||||
variant,
|
||||
});
|
||||
res.status(200).json({
|
||||
description,
|
||||
description_binary,
|
||||
});
|
||||
} catch (error) {
|
||||
manualLogger.error("Error in /convert-document endpoint:", error);
|
||||
res.status(500).send({
|
||||
message: `Internal server error. ${error}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.app.use((_req: Request, res: Response) => {
|
||||
res.status(404).send("Not Found");
|
||||
});
|
||||
}
|
||||
|
||||
public listen() {
|
||||
this.serverInstance = this.app.listen(this.app.get("port"), () => {
|
||||
manualLogger.info(`Plane Live server has started at port ${this.app.get("port")}`);
|
||||
});
|
||||
}
|
||||
|
||||
public async destroy() {
|
||||
// Close the HocusPocus server WebSocket connections
|
||||
await this.hocuspocusServer.destroy();
|
||||
manualLogger.info("HocusPocus server WebSocket connections closed gracefully.");
|
||||
// Close the Express server
|
||||
this.serverInstance.close(() => {
|
||||
manualLogger.info("Express server closed gracefully.");
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const server = new Server();
|
||||
server.listen();
|
||||
|
||||
// Graceful shutdown on unhandled rejection
|
||||
process.on("unhandledRejection", async (err: any) => {
|
||||
manualLogger.info("Unhandled Rejection: ", err);
|
||||
manualLogger.info(`UNHANDLED REJECTION! 💥 Shutting down...`);
|
||||
await server.destroy();
|
||||
});
|
||||
|
||||
// Graceful shutdown on uncaught exception
|
||||
process.on("uncaughtException", async (err: any) => {
|
||||
manualLogger.info("Uncaught Exception: ", err);
|
||||
manualLogger.info(`UNCAUGHT EXCEPTION! 💥 Shutting down...`);
|
||||
await server.destroy();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue