|
@@ -1,6 +1,21 @@
|
|
|
-import { app, BrowserWindow } from "electron";
|
|
|
+/**
|
|
|
+ * @file Entry point for the main (Node.js) process of our Electron app.
|
|
|
+ *
|
|
|
+ * The code in this file is invoked by Electron when our app starts -
|
|
|
+ * Conceptually (after all the transpilation etc has happened) this can be
|
|
|
+ * thought of `electron main.ts`. We're running in the context of the so called
|
|
|
+ * "main" process which runs in a Node.js environment.
|
|
|
+ *
|
|
|
+ * https://www.electronjs.org/docs/latest/tutorial/process-model#the-main-process
|
|
|
+ */
|
|
|
+import * as log from "electron-log";
|
|
|
+import { app, BrowserWindow } from "electron/main";
|
|
|
import serveNextAt from "next-electron-server";
|
|
|
+import { existsSync } from "node:fs";
|
|
|
+import * as fs from "node:fs/promises";
|
|
|
+import * as path from "node:path";
|
|
|
import { initWatcher } from "./services/chokidar";
|
|
|
+import { logErrorSentry } from "./services/sentry";
|
|
|
import { isDev } from "./utils/common";
|
|
|
import { addAllowOriginHeader } from "./utils/cors";
|
|
|
import { createWindow } from "./utils/createWindow";
|
|
@@ -8,7 +23,6 @@ import { setupAppEventEmitter } from "./utils/events";
|
|
|
import setupIpcComs from "./utils/ipcComms";
|
|
|
import { setupLogging } from "./utils/logging";
|
|
|
import {
|
|
|
- enableSharedArrayBufferSupport,
|
|
|
handleDockIconHideOnAutoLaunch,
|
|
|
handleDownloads,
|
|
|
handleExternalLinks,
|
|
@@ -19,8 +33,6 @@ import {
|
|
|
setupTrayItem,
|
|
|
} from "./utils/main";
|
|
|
|
|
|
-let mainWindow: BrowserWindow;
|
|
|
-
|
|
|
let appIsQuitting = false;
|
|
|
|
|
|
let updateIsAvailable = false;
|
|
@@ -63,15 +75,75 @@ const setupRendererServer = () => {
|
|
|
serveNextAt(rendererURL);
|
|
|
};
|
|
|
|
|
|
-setupRendererServer();
|
|
|
-setupLogging(isDev);
|
|
|
+function enableSharedArrayBufferSupport() {
|
|
|
+ app.commandLine.appendSwitch("enable-features", "SharedArrayBuffer");
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * [Note: Increased disk cache for the desktop app]
|
|
|
+ *
|
|
|
+ * Set the "disk-cache-size" command line flag to ask the Chromium process to
|
|
|
+ * use a larger size for the caches that it keeps on disk. This allows us to use
|
|
|
+ * the same web-native caching mechanism on both the web and the desktop app,
|
|
|
+ * just ask the embedded Chromium to be a bit more generous in disk usage when
|
|
|
+ * running as the desktop app.
|
|
|
+ *
|
|
|
+ * The size we provide is in bytes. We set it to a large value, 5 GB (5 * 1024 *
|
|
|
+ * 1024 * 1024 = 5368709120)
|
|
|
+ * https://www.electronjs.org/docs/latest/api/command-line-switches#--disk-cache-sizesize
|
|
|
+ *
|
|
|
+ * Note that increasing the disk cache size does not guarantee that Chromium
|
|
|
+ * will respect in verbatim, it uses its own heuristics atop this hint.
|
|
|
+ * https://superuser.com/questions/378991/what-is-chrome-default-cache-size-limit/1577693#1577693
|
|
|
+ */
|
|
|
+const increaseDiskCache = () => {
|
|
|
+ app.commandLine.appendSwitch("disk-cache-size", "5368709120");
|
|
|
+};
|
|
|
|
|
|
-const gotTheLock = app.requestSingleInstanceLock();
|
|
|
-if (!gotTheLock) {
|
|
|
- app.quit();
|
|
|
-} else {
|
|
|
+/**
|
|
|
+ * Older versions of our app used to maintain a cache dir using the main
|
|
|
+ * process. This has been deprecated in favor of using a normal web cache (See:
|
|
|
+ * [Note: Increased disk cache for the desktop app]).
|
|
|
+ *
|
|
|
+ * Delete the old cache dir if it exists. This code was added March 2024, and
|
|
|
+ * can be removed after some time once most people have upgraded to newer
|
|
|
+ * versions.
|
|
|
+ */
|
|
|
+const deleteLegacyDiskCacheDirIfExists = async () => {
|
|
|
+ // The existing code was passing "cache" as a parameter to getPath. This is
|
|
|
+ // incorrect if we go by the types - "cache" is not a valid value for the
|
|
|
+ // parameter to `app.getPath`.
|
|
|
+ //
|
|
|
+ // It might be an issue in the types, since at runtime it seems to work. For
|
|
|
+ // example, on macOS I get `~/Library/Caches`.
|
|
|
+ //
|
|
|
+ // Irrespective, we replicate the original behaviour so that we get back the
|
|
|
+ // same path that the old got was getting.
|
|
|
+ //
|
|
|
+ // @ts-expect-error
|
|
|
+ const cacheDir = path.join(app.getPath("cache"), "ente");
|
|
|
+ if (existsSync(cacheDir)) {
|
|
|
+ log.info(`Removing legacy disk cache from ${cacheDir}`);
|
|
|
+ await fs.rm(cacheDir, { recursive: true });
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const main = () => {
|
|
|
+ setupLogging(isDev);
|
|
|
+
|
|
|
+ const gotTheLock = app.requestSingleInstanceLock();
|
|
|
+ if (!gotTheLock) {
|
|
|
+ app.quit();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let mainWindow: BrowserWindow;
|
|
|
+
|
|
|
+ setupRendererServer();
|
|
|
handleDockIconHideOnAutoLaunch();
|
|
|
+ increaseDiskCache();
|
|
|
enableSharedArrayBufferSupport();
|
|
|
+
|
|
|
app.on("second-instance", () => {
|
|
|
// Someone tried to run a second instance, we should focus our window.
|
|
|
if (mainWindow) {
|
|
@@ -99,7 +171,17 @@ if (!gotTheLock) {
|
|
|
handleExternalLinks(mainWindow);
|
|
|
addAllowOriginHeader(mainWindow);
|
|
|
setupAppEventEmitter(mainWindow);
|
|
|
+
|
|
|
+ try {
|
|
|
+ deleteLegacyDiskCacheDirIfExists();
|
|
|
+ } catch (e) {
|
|
|
+ // Log but otherwise ignore errors during non-critical startup
|
|
|
+ // actions
|
|
|
+ logErrorSentry(e, "Ignoring startup error");
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
app.on("before-quit", () => setIsAppQuitting(true));
|
|
|
-}
|
|
|
+};
|
|
|
+
|
|
|
+main();
|