mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	chore(monorepo/server): remove top-level await completely
This commit is contained in:
		| @@ -2,7 +2,6 @@ | ||||
|   "name": "@triliumnext/server", | ||||
|   "version": "0.0.1", | ||||
|   "private": true, | ||||
|   "type": "module", | ||||
|   "dependencies": { | ||||
|     "express": "4.21.2", | ||||
|     "express-openid-connect": "^2.17.1", | ||||
|   | ||||
| @@ -20,120 +20,121 @@ import openID from "./services/open_id.js"; | ||||
| import { t } from "i18next"; | ||||
| import eventService from "./services/events.js"; | ||||
| import log from "./services/log.js"; | ||||
| import "./services/handlers.js"; | ||||
| import "./becca/becca_loader.js"; | ||||
|  | ||||
| await import("./services/handlers.js"); | ||||
| await import("./becca/becca_loader.js"); | ||||
| export default async function buildApp() { | ||||
|     const app = express(); | ||||
|  | ||||
| const app = express(); | ||||
|     const scriptDir = dirname(fileURLToPath(import.meta.url)); | ||||
|  | ||||
| const scriptDir = dirname(fileURLToPath(import.meta.url)); | ||||
|     // Initialize DB | ||||
|     sql_init.initializeDb(); | ||||
|  | ||||
| // Initialize DB | ||||
| sql_init.initializeDb(); | ||||
|     // Listen for database initialization event | ||||
|     eventService.subscribe(eventService.DB_INITIALIZED, async () => { | ||||
|         try { | ||||
|             log.info("Database initialized, setting up LLM features"); | ||||
|  | ||||
| // Listen for database initialization event | ||||
| eventService.subscribe(eventService.DB_INITIALIZED, async () => { | ||||
|     try { | ||||
|         log.info("Database initialized, setting up LLM features"); | ||||
|             // Initialize embedding providers | ||||
|             const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js"); | ||||
|             await initializeEmbeddings(); | ||||
|  | ||||
|         // Initialize embedding providers | ||||
|         const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js"); | ||||
|         await initializeEmbeddings(); | ||||
|             // Initialize the index service for LLM functionality | ||||
|             const { default: indexService } = await import("./services/llm/index_service.js"); | ||||
|             await indexService.initialize().catch(e => console.error("Failed to initialize index service:", e)); | ||||
|  | ||||
|         // Initialize the index service for LLM functionality | ||||
|         const { default: indexService } = await import("./services/llm/index_service.js"); | ||||
|         await indexService.initialize().catch(e => console.error("Failed to initialize index service:", e)); | ||||
|             log.info("LLM features initialized successfully"); | ||||
|         } catch (error) { | ||||
|             console.error("Error initializing LLM features:", error); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|         log.info("LLM features initialized successfully"); | ||||
|     } catch (error) { | ||||
|         console.error("Error initializing LLM features:", error); | ||||
|     // Initialize LLM features only if database is already initialized | ||||
|     if (sql_init.isDbInitialized()) { | ||||
|         try { | ||||
|             // Initialize embedding providers | ||||
|             const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js"); | ||||
|             await initializeEmbeddings(); | ||||
|  | ||||
|             // Initialize the index service for LLM functionality | ||||
|             const { default: indexService } = await import("./services/llm/index_service.js"); | ||||
|             await indexService.initialize().catch(e => console.error("Failed to initialize index service:", e)); | ||||
|         } catch (error) { | ||||
|             console.error("Error initializing LLM features:", error); | ||||
|         } | ||||
|     } else { | ||||
|         console.log("Database not initialized yet. LLM features will be initialized after setup."); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| // Initialize LLM features only if database is already initialized | ||||
| if (sql_init.isDbInitialized()) { | ||||
|     try { | ||||
|         // Initialize embedding providers | ||||
|         const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js"); | ||||
|         await initializeEmbeddings(); | ||||
|     // view engine setup | ||||
|     app.set("views", path.join(scriptDir, "views")); | ||||
|     app.set("view engine", "ejs"); | ||||
|  | ||||
|         // Initialize the index service for LLM functionality | ||||
|         const { default: indexService } = await import("./services/llm/index_service.js"); | ||||
|         await indexService.initialize().catch(e => console.error("Failed to initialize index service:", e)); | ||||
|     } catch (error) { | ||||
|         console.error("Error initializing LLM features:", error); | ||||
|     app.use((req, res, next) => { | ||||
|         // set CORS header | ||||
|         if (config["Network"]["corsAllowOrigin"]) { | ||||
|             res.header("Access-Control-Allow-Origin", config["Network"]["corsAllowOrigin"]); | ||||
|         } | ||||
|         if (config["Network"]["corsAllowMethods"]) { | ||||
|             res.header("Access-Control-Allow-Methods", config["Network"]["corsAllowMethods"]); | ||||
|         } | ||||
|         if (config["Network"]["corsAllowHeaders"]) { | ||||
|             res.header("Access-Control-Allow-Headers", config["Network"]["corsAllowHeaders"]); | ||||
|         } | ||||
|  | ||||
|         res.locals.t = t; | ||||
|         return next(); | ||||
|     }); | ||||
|  | ||||
|     if (!utils.isElectron) { | ||||
|         app.use(compression()); // HTTP compression | ||||
|     } | ||||
| } else { | ||||
|     console.log("Database not initialized yet. LLM features will be initialized after setup."); | ||||
|  | ||||
|     app.use( | ||||
|         helmet({ | ||||
|             hidePoweredBy: false, // errors out in electron | ||||
|             contentSecurityPolicy: false, | ||||
|             crossOriginEmbedderPolicy: false | ||||
|         }) | ||||
|     ); | ||||
|  | ||||
|     app.use(express.text({ limit: "500mb" })); | ||||
|     app.use(express.json({ limit: "500mb" })); | ||||
|     app.use(express.raw({ limit: "500mb" })); | ||||
|     app.use(express.urlencoded({ extended: false })); | ||||
|     app.use(cookieParser()); | ||||
|     app.use(express.static(path.join(scriptDir, "public/root"))); | ||||
|     app.use(`/manifest.webmanifest`, express.static(path.join(scriptDir, "public/manifest.webmanifest"))); | ||||
|     app.use(`/robots.txt`, express.static(path.join(scriptDir, "public/robots.txt"))); | ||||
|     app.use(`/icon.png`, express.static(path.join(scriptDir, "public/icon.png"))); | ||||
|     app.use(sessionParser); | ||||
|     app.use(favicon(`${scriptDir}/../assets/icon.ico`)); | ||||
|  | ||||
|     if (openID.isOpenIDEnabled()) | ||||
|         app.use(auth(openID.generateOAuthConfig())); | ||||
|  | ||||
|     await assets.register(app); | ||||
|     routes.register(app); | ||||
|     custom.register(app); | ||||
|     error_handlers.register(app); | ||||
|  | ||||
|     // triggers sync timer | ||||
|     await import("./services/sync.js"); | ||||
|  | ||||
|     // triggers backup timer | ||||
|     await import("./services/backup.js"); | ||||
|  | ||||
|     // trigger consistency checks timer | ||||
|     await import("./services/consistency_checks.js"); | ||||
|  | ||||
|     await import("./services/scheduler.js"); | ||||
|  | ||||
|     startScheduledCleanup(); | ||||
|  | ||||
|     if (utils.isElectron) { | ||||
|         (await import("@electron/remote/main/index.js")).initialize(); | ||||
|     } | ||||
|  | ||||
|     return app; | ||||
| } | ||||
|  | ||||
| // view engine setup | ||||
| app.set("views", path.join(scriptDir, "views")); | ||||
| app.set("view engine", "ejs"); | ||||
|  | ||||
| app.use((req, res, next) => { | ||||
|     // set CORS header | ||||
|     if (config["Network"]["corsAllowOrigin"]) { | ||||
|         res.header("Access-Control-Allow-Origin", config["Network"]["corsAllowOrigin"]); | ||||
|     } | ||||
|     if (config["Network"]["corsAllowMethods"]) { | ||||
|         res.header("Access-Control-Allow-Methods", config["Network"]["corsAllowMethods"]); | ||||
|     } | ||||
|     if (config["Network"]["corsAllowHeaders"]) { | ||||
|         res.header("Access-Control-Allow-Headers", config["Network"]["corsAllowHeaders"]); | ||||
|     } | ||||
|  | ||||
|     res.locals.t = t; | ||||
|     return next(); | ||||
| }); | ||||
|  | ||||
| if (!utils.isElectron) { | ||||
|     app.use(compression()); // HTTP compression | ||||
| } | ||||
|  | ||||
| app.use( | ||||
|     helmet({ | ||||
|         hidePoweredBy: false, // errors out in electron | ||||
|         contentSecurityPolicy: false, | ||||
|         crossOriginEmbedderPolicy: false | ||||
|     }) | ||||
| ); | ||||
|  | ||||
| app.use(express.text({ limit: "500mb" })); | ||||
| app.use(express.json({ limit: "500mb" })); | ||||
| app.use(express.raw({ limit: "500mb" })); | ||||
| app.use(express.urlencoded({ extended: false })); | ||||
| app.use(cookieParser()); | ||||
| app.use(express.static(path.join(scriptDir, "public/root"))); | ||||
| app.use(`/manifest.webmanifest`, express.static(path.join(scriptDir, "public/manifest.webmanifest"))); | ||||
| app.use(`/robots.txt`, express.static(path.join(scriptDir, "public/robots.txt"))); | ||||
| app.use(`/icon.png`, express.static(path.join(scriptDir, "public/icon.png"))); | ||||
| app.use(sessionParser); | ||||
| app.use(favicon(`${scriptDir}/../assets/icon.ico`)); | ||||
|  | ||||
| if (openID.isOpenIDEnabled()) | ||||
|     app.use(auth(openID.generateOAuthConfig())); | ||||
|  | ||||
| await assets.register(app); | ||||
| routes.register(app); | ||||
| custom.register(app); | ||||
| error_handlers.register(app); | ||||
|  | ||||
| // triggers sync timer | ||||
| await import("./services/sync.js"); | ||||
|  | ||||
| // triggers backup timer | ||||
| await import("./services/backup.js"); | ||||
|  | ||||
| // trigger consistency checks timer | ||||
| await import("./services/consistency_checks.js"); | ||||
|  | ||||
| await import("./services/scheduler.js"); | ||||
|  | ||||
| startScheduledCleanup(); | ||||
|  | ||||
| if (utils.isElectron) { | ||||
|     (await import("@electron/remote/main/index.js")).initialize(); | ||||
| } | ||||
|  | ||||
| export default app; | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
| import { initializeTranslations } from "./services/i18n.js"; | ||||
|  | ||||
| async function startApplication() { | ||||
|     await initializeTranslations(); | ||||
|     await import("./www.js"); | ||||
| } | ||||
|  | ||||
| await initializeTranslations(); | ||||
| await startApplication(); | ||||
| startApplication(); | ||||
|   | ||||
| @@ -1,16 +1,17 @@ | ||||
| import type { Application } from "express"; | ||||
| import swaggerUi from "swagger-ui-express"; | ||||
| import { readFile } from "fs/promises"; | ||||
| import { fileURLToPath } from "url"; | ||||
| import { dirname, join } from "path"; | ||||
| import yaml from "js-yaml"; | ||||
| import type { JsonObject } from "swagger-ui-express"; | ||||
| import { readFileSync } from "fs"; | ||||
|  | ||||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||||
| const etapiDocument = yaml.load(await readFile(join(__dirname, "../etapi/etapi.openapi.yaml"), "utf8")) as JsonObject; | ||||
| const apiDocument = JSON.parse(await readFile(join(__dirname, "api", "openapi.json"), "utf-8")); | ||||
|  | ||||
| function register(app: Application) { | ||||
| export default function register(app: Application) { | ||||
|     const etapiDocument = yaml.load(readFileSync(join(__dirname, "../etapi/etapi.openapi.yaml"), "utf8")) as JsonObject; | ||||
|     const apiDocument = JSON.parse(readFileSync(join(__dirname, "api", "openapi.json"), "utf-8")); | ||||
|  | ||||
|     app.use( | ||||
|         "/etapi/docs/", | ||||
|         swaggerUi.serveFiles(etapiDocument), | ||||
| @@ -29,7 +30,3 @@ function register(app: Application) { | ||||
|         }) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     register | ||||
| }; | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { ipcMain } from "electron"; | ||||
| import type { Application } from "express"; | ||||
|  | ||||
| interface Response { | ||||
|     statusCode: number; | ||||
| @@ -10,7 +9,7 @@ interface Response { | ||||
|     send: (obj: {}) => void; // eslint-disable-line @typescript-eslint/no-empty-object-type | ||||
| } | ||||
|  | ||||
| function init(app: Application) { | ||||
| function init(app: Express.Application) { | ||||
|     ipcMain.on("server-request", (event, arg) => { | ||||
|         const req = { | ||||
|             url: arg.url, | ||||
|   | ||||
| @@ -12,19 +12,6 @@ import AbstractBeccaEntity from "../becca/entities/abstract_becca_entity.js"; | ||||
| import type { IncomingMessage, Server as HttpServer } from "http"; | ||||
| import type { EntityChange } from "./entity_changes_interface.js"; | ||||
|  | ||||
| if (isDev) { | ||||
|     const chokidar = (await import("chokidar")).default; | ||||
|     const debounce = (await import("debounce")).default; | ||||
|     const debouncedReloadFrontend = debounce(() => reloadFrontend("source code change"), 200); | ||||
|     chokidar | ||||
|         .watch("src/public", { | ||||
|             ignored: "src/public/app/doc_notes/en/User Guide" | ||||
|         }) | ||||
|         .on("add", debouncedReloadFrontend) | ||||
|         .on("change", debouncedReloadFrontend) | ||||
|         .on("unlink", debouncedReloadFrontend); | ||||
| } | ||||
|  | ||||
| let webSocketServer!: WebSocketServer; | ||||
| let lastSyncedPush: number | null = null; | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #!/usr/bin/env node | ||||
|  | ||||
| import app from "./app.js"; | ||||
| import sessionParser from "./routes/session_parser.js"; | ||||
| import fs from "fs"; | ||||
| import http from "http"; | ||||
| @@ -13,6 +12,8 @@ import ws from "./services/ws.js"; | ||||
| import utils from "./services/utils.js"; | ||||
| import port from "./services/port.js"; | ||||
| import host from "./services/host.js"; | ||||
| import buildApp from "./app.js"; | ||||
| import type { Express } from "express"; | ||||
|  | ||||
| const MINIMUM_NODE_VERSION = "20.0.0"; | ||||
|  | ||||
| @@ -47,6 +48,8 @@ tmp.setGracefulCleanup(); | ||||
| startTrilium(); | ||||
|  | ||||
| async function startTrilium() { | ||||
|     const app = await buildApp(); | ||||
|  | ||||
|     /** | ||||
|      * The intended behavior is to detect when a second instance is running, in that case open the old instance | ||||
|      * instead of the new one. This is complicated by the fact that it is possible to run multiple instances of Trilium | ||||
| @@ -74,7 +77,7 @@ async function startTrilium() { | ||||
|         log.info(`CPU model: ${cpuModel}, logical cores: ${cpuInfos.length}, freq: ${cpuInfos[0].speed} Mhz`); | ||||
|     } | ||||
|  | ||||
|     const httpServer = startHttpServer(); | ||||
|     const httpServer = startHttpServer(app); | ||||
|  | ||||
|     ws.init(httpServer, sessionParser as any); // TODO: Not sure why session parser is incompatible. | ||||
|  | ||||
| @@ -84,7 +87,7 @@ async function startTrilium() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function startHttpServer() { | ||||
| function startHttpServer(app: Express) { | ||||
|     app.set("port", port); | ||||
|     app.set("host", host); | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| { | ||||
|   "extends": "../../tsconfig.base.json", | ||||
|   "compilerOptions": { | ||||
|     "module": "ESNext", | ||||
|     "target": "ESNext", | ||||
|     "moduleResolution": "bundler", | ||||
|     "module": "NodeNext", | ||||
|     "moduleResolution": "nodenext", | ||||
|     "outDir": "dist", | ||||
|     "types": [ | ||||
|       "node", | ||||
|   | ||||
| @@ -3,8 +3,7 @@ const { join } = require('path'); | ||||
|  | ||||
| module.exports = { | ||||
|   output: { | ||||
|     path: join(__dirname, 'dist'), | ||||
|     libraryTarget: "module" | ||||
|     path: join(__dirname, 'dist') | ||||
|   }, | ||||
|   plugins: [ | ||||
|     new NxAppWebpackPlugin({ | ||||
| @@ -17,8 +16,5 @@ module.exports = { | ||||
|       outputHashing: 'none', | ||||
|       generatePackageJson: true, | ||||
|     }) | ||||
|   ], | ||||
|   experiments: { | ||||
|     outputModule: true | ||||
|   } | ||||
|   ] | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user