From e5b2d737b48917c3766cfdfba4e7eec0ae6e62d1 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Sun, 7 Apr 2024 09:47:27 +0530 Subject: [PATCH] Clean up environment detection code --- .../PhotoViewer/FileInfo/MapBox.tsx | 8 ++-- .../machineLearning/machineLearningFactory.ts | 5 ++- .../src/utils/comlink/ComlinkConvertWorker.ts | 4 +- .../src/utils/comlink/ComlinkMLWorker.ts | 4 +- .../src/utils/comlink/ComlinkSearchWorker.ts | 4 +- .../photos/src/utils/common/concurrency.ts | 5 --- web/apps/photos/src/utils/common/index.ts | 41 ------------------- .../photos/src/utils/storage/mlIDbStorage.ts | 4 +- web/packages/next/env.ts | 27 ++++++++++++ web/packages/next/package.json | 1 + web/packages/next/tsconfig.json | 4 ++ web/packages/shared/electron/service.ts | 4 +- web/packages/shared/platform/index.ts | 13 ------ .../shared/storage/localForage/index.ts | 4 +- web/packages/utils/package.json | 1 - 15 files changed, 51 insertions(+), 78 deletions(-) delete mode 100644 web/apps/photos/src/utils/common/concurrency.ts delete mode 100644 web/packages/shared/platform/index.ts diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/MapBox.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/MapBox.tsx index d7e3b9e912..368c3787b6 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/MapBox.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/MapBox.tsx @@ -1,15 +1,13 @@ +import { haveWindow } from "@/next/env"; import { styled } from "@mui/material"; import { useEffect, useRef } from "react"; -import { runningInBrowser } from "utils/common"; import { MapButton } from "./MapButton"; import { t } from "i18next"; import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css"; // Re-uses images from ~leaflet package import "leaflet/dist/leaflet.css"; -runningInBrowser() && require("leaflet-defaulticon-compatibility"); -const L = runningInBrowser() - ? (require("leaflet") as typeof import("leaflet")) - : null; +haveWindow && require("leaflet-defaulticon-compatibility"); +const L = haveWindow ? (require("leaflet") as typeof import("leaflet")) : null; const LAYER_TILE_URL = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; const LAYER_TILE_ATTRIBUTION = diff --git a/web/apps/photos/src/services/machineLearning/machineLearningFactory.ts b/web/apps/photos/src/services/machineLearning/machineLearningFactory.ts index d397a60ad0..9e7cac60c6 100644 --- a/web/apps/photos/src/services/machineLearning/machineLearningFactory.ts +++ b/web/apps/photos/src/services/machineLearning/machineLearningFactory.ts @@ -1,3 +1,4 @@ +import { haveWindow } from "@/next/env"; import { getDedicatedCryptoWorker } from "@ente/shared/crypto"; import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker"; import { addLogLine } from "@ente/shared/logging"; @@ -24,7 +25,6 @@ import { SceneDetectionMethod, SceneDetectionService, } from "types/machineLearning"; -import { getConcurrency } from "utils/common/concurrency"; import { logQueueStats } from "utils/machineLearning"; import arcfaceAlignmentService from "./arcfaceAlignmentService"; import arcfaceCropService from "./arcfaceCropService"; @@ -232,3 +232,6 @@ export class LocalMLSyncContext implements MLSyncContext { } } } + +export const getConcurrency = () => + haveWindow && Math.max(2, Math.ceil(navigator.hardwareConcurrency / 2)); diff --git a/web/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts b/web/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts index 3dc0341607..c9cd9aef43 100644 --- a/web/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts +++ b/web/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts @@ -1,6 +1,6 @@ +import { haveWindow } from "@/next/env"; import { ComlinkWorker } from "@ente/shared/worker/comlinkWorker"; import { Remote } from "comlink"; -import { runningInBrowser } from "utils/common"; import { DedicatedConvertWorker } from "worker/convert.worker"; class ComlinkConvertWorker { @@ -16,7 +16,7 @@ class ComlinkConvertWorker { } export const getDedicatedConvertWorker = () => { - if (runningInBrowser()) { + if (haveWindow) { const cryptoComlinkWorker = new ComlinkWorker< typeof DedicatedConvertWorker >( diff --git a/web/apps/photos/src/utils/comlink/ComlinkMLWorker.ts b/web/apps/photos/src/utils/comlink/ComlinkMLWorker.ts index f61754c6bb..83dfaf2861 100644 --- a/web/apps/photos/src/utils/comlink/ComlinkMLWorker.ts +++ b/web/apps/photos/src/utils/comlink/ComlinkMLWorker.ts @@ -1,9 +1,9 @@ +import { haveWindow } from "@/next/env"; import { ComlinkWorker } from "@ente/shared/worker/comlinkWorker"; -import { runningInBrowser } from "utils/common"; import { DedicatedMLWorker } from "worker/ml.worker"; export const getDedicatedMLWorker = (name: string) => { - if (runningInBrowser()) { + if (haveWindow) { const cryptoComlinkWorker = new ComlinkWorker( name ?? "ente-ml-worker", new Worker(new URL("worker/ml.worker.ts", import.meta.url)), diff --git a/web/apps/photos/src/utils/comlink/ComlinkSearchWorker.ts b/web/apps/photos/src/utils/comlink/ComlinkSearchWorker.ts index 971f12338d..f948440b03 100644 --- a/web/apps/photos/src/utils/comlink/ComlinkSearchWorker.ts +++ b/web/apps/photos/src/utils/comlink/ComlinkSearchWorker.ts @@ -1,6 +1,6 @@ +import { haveWindow } from "@/next/env"; import { ComlinkWorker } from "@ente/shared/worker/comlinkWorker"; import { Remote } from "comlink"; -import { runningInBrowser } from "utils/common"; import { DedicatedSearchWorker } from "worker/search.worker"; class ComlinkSearchWorker { @@ -16,7 +16,7 @@ class ComlinkSearchWorker { } export const getDedicatedSearchWorker = () => { - if (runningInBrowser()) { + if (haveWindow) { const cryptoComlinkWorker = new ComlinkWorker< typeof DedicatedSearchWorker >( diff --git a/web/apps/photos/src/utils/common/concurrency.ts b/web/apps/photos/src/utils/common/concurrency.ts deleted file mode 100644 index bba75f0097..0000000000 --- a/web/apps/photos/src/utils/common/concurrency.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { runningInBrowser } from "."; - -export const getConcurrency = () => - runningInBrowser() && - Math.max(2, Math.ceil(navigator.hardwareConcurrency / 2)); diff --git a/web/apps/photos/src/utils/common/index.ts b/web/apps/photos/src/utils/common/index.ts index 4fcc07717f..df4676a905 100644 --- a/web/apps/photos/src/utils/common/index.ts +++ b/web/apps/photos/src/utils/common/index.ts @@ -1,7 +1,6 @@ import { APP_DOWNLOAD_URL } from "@ente/shared/constants/urls"; import { CustomError } from "@ente/shared/error"; import { isPromise } from "@ente/shared/utils"; -import isElectron from "is-electron"; export function checkConnectivity() { if (navigator.onLine) { @@ -10,46 +9,6 @@ export function checkConnectivity() { throw new Error(CustomError.NO_INTERNET_CONNECTION); } -export function runningInBrowser() { - return typeof window !== "undefined"; -} - -export function runningInWorker() { - return typeof importScripts === "function"; -} - -export function runningInElectron() { - return isElectron(); -} - -export function runningInChrome(includeMobile: boolean) { - try { - const userAgentData = navigator["userAgentData"]; - const chromeBrand = userAgentData?.brands?.filter( - (b) => b.brand === "Google Chrome" || b.brand === "Chromium", - )?.[0]; - return chromeBrand && (includeMobile || userAgentData.mobile === false); - } catch (error) { - console.error("Error in runningInChrome: ", error); - return false; - } -} - -export function offscreenCanvasSupported() { - return !(typeof OffscreenCanvas === "undefined"); -} - -export function webglSupported() { - try { - const canvas = document.createElement("canvas"); - const gl = canvas.getContext("webgl"); - return gl && gl instanceof WebGLRenderingContext; - } catch (error) { - console.error("Error in webglSupported: ", error); - return false; - } -} - export function downloadApp() { openLink(APP_DOWNLOAD_URL, true); } diff --git a/web/apps/photos/src/utils/storage/mlIDbStorage.ts b/web/apps/photos/src/utils/storage/mlIDbStorage.ts index 7ee4a5fcf4..7dca2a68e5 100644 --- a/web/apps/photos/src/utils/storage/mlIDbStorage.ts +++ b/web/apps/photos/src/utils/storage/mlIDbStorage.ts @@ -1,3 +1,4 @@ +import { haveWindow, inElectron } from "@/next/env"; import { addLogLine } from "@ente/shared/logging"; import { logError } from "@ente/shared/sentry"; import { @@ -23,7 +24,6 @@ import { Thing, } from "types/machineLearning"; import { IndexStatus } from "types/machineLearning/ui"; -import { runningInBrowser, runningInElectron } from "utils/common"; interface Config {} @@ -64,7 +64,7 @@ class MLIDbStorage { public _db: Promise>; constructor() { - if (!runningInBrowser() || !runningInElectron()) { + if (!haveWindow || !inElectron) { return; } diff --git a/web/packages/next/env.ts b/web/packages/next/env.ts index 8e66e7fd9c..27cea6f161 100644 --- a/web/packages/next/env.ts +++ b/web/packages/next/env.ts @@ -1,3 +1,5 @@ +import isElectron from "is-electron"; + /** * A build is considered as a development build if either the NODE_ENV is * environment variable is set to 'development'. @@ -10,3 +12,28 @@ * all other commands. */ export const isDevBuild = process.env.NODE_ENV === "development"; + +/** + * `true` if we're running in the default global context (aka the main thread) + * of a web browser. + * + * In particular, this is `false` when we're running in a Web Worker, + * irrespecitve of whether the worker is running in a Node.js context or a web + * browser context. + * + * > We can be running in a browser context either if the user has the page open + * in a web browser, or if we're the renderer process of an Electron app. + */ +export const haveWindow = typeof window !== "undefined"; + +/** + * Return true if we are running in a [Web + * Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) + */ +export const inWorker = typeof importScripts === "function"; + +/** + * Return true if we're running in an Electron app (either main or renderer + * process). + */ +export const inElectron = isElectron(); diff --git a/web/packages/next/package.json b/web/packages/next/package.json index f0bbe85448..f5a325f14d 100644 --- a/web/packages/next/package.json +++ b/web/packages/next/package.json @@ -10,6 +10,7 @@ "get-user-locale": "^2.3", "i18next": "^23.10", "i18next-resources-to-backend": "^1.2.0", + "is-electron": "^2.2", "next": "^14.1", "react": "^18", "react-dom": "^18", diff --git a/web/packages/next/tsconfig.json b/web/packages/next/tsconfig.json index f29c348113..10fe5229cf 100644 --- a/web/packages/next/tsconfig.json +++ b/web/packages/next/tsconfig.json @@ -1,5 +1,9 @@ { "extends": "@/build-config/tsconfig-typecheck.json", + "compilerOptions": { + /* Also indicate expectation of a WebWorker runtime */ + "lib": ["ESnext", "DOM", "DOM.Iterable", "WebWorker"] + }, /* Typecheck all files with the given extensions (here or in subfolders) */ "include": ["**/*.ts", "**/*.tsx"] } diff --git a/web/packages/shared/electron/service.ts b/web/packages/shared/electron/service.ts index 0484b07465..b4f906c0c5 100644 --- a/web/packages/shared/electron/service.ts +++ b/web/packages/shared/electron/service.ts @@ -1,4 +1,4 @@ -import { runningInWorker } from "@ente/shared/platform"; +import { inWorker } from "@/next/env"; import * as Comlink from "comlink"; import { wrap } from "comlink"; import { ElectronAPIsType } from "./types"; @@ -17,7 +17,7 @@ class WorkerSafeElectronServiceImpl implements LimitedElectronAPIs { this.ready = this.init(); } private async init() { - if (runningInWorker()) { + if (inWorker) { const workerSafeElectronClient = wrap(self); diff --git a/web/packages/shared/platform/index.ts b/web/packages/shared/platform/index.ts deleted file mode 100644 index a7a63dd6f4..0000000000 --- a/web/packages/shared/platform/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import isElectron from "is-electron"; - -export function runningInBrowser() { - return typeof window !== "undefined"; -} - -export function runningInWorker() { - return typeof importScripts === "function"; -} - -export function runningInElectron() { - return isElectron(); -} diff --git a/web/packages/shared/storage/localForage/index.ts b/web/packages/shared/storage/localForage/index.ts index 9ddf80d99e..81bbea6106 100644 --- a/web/packages/shared/storage/localForage/index.ts +++ b/web/packages/shared/storage/localForage/index.ts @@ -1,8 +1,8 @@ -import { runningInBrowser } from "../../platform"; +import { haveWindow } from "@/next/env"; import localForage from "localforage"; -if (runningInBrowser()) { +if (haveWindow) { localForage.config({ name: "ente-files", version: 1.0, diff --git a/web/packages/utils/package.json b/web/packages/utils/package.json index bfe78b5f7f..930e3aa44f 100644 --- a/web/packages/utils/package.json +++ b/web/packages/utils/package.json @@ -3,7 +3,6 @@ "version": "0.0.0", "private": true, "dependencies": { - "is-electron": "^2.2", "libsodium-wrappers": "0.7.9", "yup": "^1.4" },