Browse Source

Enum instead of error

Manav Rathi 1 year ago
parent
commit
093b3a67cb

+ 1 - 1
desktop/src/main.ts

@@ -29,7 +29,7 @@ import { createWatcher } from "./main/services/watch";
 import { userPreferences } from "./main/stores/user-preferences";
 import { migrateLegacyWatchStoreIfNeeded } from "./main/stores/watch";
 import { registerStreamProtocol } from "./main/stream";
-import { isDev } from "./main/util";
+import { isDev } from "./main/utils-electron";
 
 /**
  * The URL where the renderer HTML is being served from.

+ 1 - 1
desktop/src/main/ipc.ts

@@ -66,7 +66,7 @@ import {
     watchUpdateIgnoredFiles,
     watchUpdateSyncedFiles,
 } from "./services/watch";
-import { openDirectory, openLogDirectory } from "./util";
+import { openDirectory, openLogDirectory } from "./utils-electron";
 
 /**
  * Listen for IPC events sent/invoked by the renderer process, and route them to

+ 1 - 1
desktop/src/main/log.ts

@@ -1,6 +1,6 @@
 import log from "electron-log";
 import util from "node:util";
-import { isDev } from "./util";
+import { isDev } from "./utils-electron";
 
 /**
  * Initialize logging in the main process.

+ 1 - 1
desktop/src/main/menu.ts

@@ -9,7 +9,7 @@ import { allowWindowClose } from "../main";
 import { forceCheckForAppUpdates } from "./services/app-update";
 import autoLauncher from "./services/auto-launcher";
 import { userPreferences } from "./stores/user-preferences";
-import { openLogDirectory } from "./util";
+import { openLogDirectory } from "./utils-electron";
 
 /** Create and return the entries in the app's main menu bar */
 export const createApplicationMenu = async (mainWindow: BrowserWindow) => {

+ 2 - 21
desktop/src/main/services/ffmpeg.ts

@@ -5,7 +5,8 @@ import { ElectronFile } from "../../types/ipc";
 import log from "../log";
 import { writeStream } from "../stream";
 import { generateTempFilePath, getTempDirPath } from "../temp";
-import { execAsync } from "../util";
+import { withTimeout } from "../utils";
+import { execAsync } from "../utils-electron";
 
 const INPUT_PATH_PLACEHOLDER = "INPUT";
 const FFMPEG_PLACEHOLDER = "FFMPEG";
@@ -132,23 +133,3 @@ export async function deleteTempFile(tempFilePath: string) {
         log.error("Attempting to delete a non-temp file ${tempFilePath}");
     await fs.rm(tempFilePath, { force: true });
 }
-
-/**
- * Await the given {@link promise} for {@link timeoutMS} milliseconds. If it
- * does not resolve within {@link timeoutMS}, then reject with a timeout error.
- */
-export const withTimeout = async <T>(promise: Promise<T>, ms: number) => {
-    let timeoutId: ReturnType<typeof setTimeout>;
-    const rejectOnTimeout = new Promise<T>((_, reject) => {
-        timeoutId = setTimeout(
-            () => reject(new Error("Operation timed out")),
-            ms,
-        );
-    });
-    const promiseAndCancelTimeout = async () => {
-        const result = await promise;
-        clearTimeout(timeoutId);
-        return result;
-    };
-    return Promise.race([promiseAndCancelTimeout(), rejectOnTimeout]);
-};

+ 1 - 1
desktop/src/main/services/imageProcessor.ts

@@ -5,7 +5,7 @@ import { CustomErrors, ElectronFile } from "../../types/ipc";
 import log from "../log";
 import { writeStream } from "../stream";
 import { generateTempFilePath } from "../temp";
-import { execAsync, isDev } from "../util";
+import { execAsync, isDev } from "../utils-electron";
 import { deleteTempFile } from "./ffmpeg";
 
 const IMAGE_MAGICK_PLACEHOLDER = "IMAGE_MAGICK";

+ 12 - 4
desktop/src/main/services/ml-clip.ts

@@ -22,14 +22,16 @@ import {
     modelSavePath,
 } from "./ml";
 
-const textModelName = "clip-text-vit-32-uint8.onnx";
-const textModelByteSize = 64173509; // 61.2 MB
-
 const cachedCLIPImageSession = makeCachedInferenceSession(
     "clip-image-vit-32-float32.onnx",
     351468764 /* 335.2 MB */,
 );
 
+const cachedCLIPTextSession = makeCachedInferenceSession(
+    "clip-text-vit-32-uint8.onnx",
+    64173509 /* 61.2 MB */,
+);
+
 let textModelDownloadInProgress = false;
 
 /* TODO(MR): use the generic method. Then we can remove the exports for the
@@ -202,7 +204,13 @@ const getTokenizer = () => {
 };
 
 export const clipTextEmbedding = async (text: string) => {
-    const session = await onnxTextSession();
+    const session = await Promise.race([
+        cachedCLIPTextSession(),
+        new Promise<"downloading-model">((resolve) =>
+            setTimeout(() => resolve("downloading-model"), 100),
+        ),
+    ]);
+    await onnxTextSession();
     const t1 = Date.now();
     const tokenizer = getTokenizer();
     const tokenizedText = Int32Array.from(tokenizer.encodeForCLIP(text));

+ 0 - 0
desktop/src/main/util.ts → desktop/src/main/utils-electron.ts


+ 35 - 0
desktop/src/main/utils.ts

@@ -0,0 +1,35 @@
+/**
+ * @file grab bag of utitity functions.
+ *
+ * Many of these are verbatim copies of functions from web code since there
+ * isn't currently a common package that both of them share.
+ */
+
+/**
+ * Wait for {@link ms} milliseconds
+ *
+ * This function is a promisified `setTimeout`. It returns a promise that
+ * resolves after {@link ms} milliseconds.
+ */
+export const wait = (ms: number) =>
+    new Promise((resolve) => setTimeout(resolve, ms));
+
+/**
+ * Await the given {@link promise} for {@link timeoutMS} milliseconds. If it
+ * does not resolve within {@link timeoutMS}, then reject with a timeout error.
+ */
+export const withTimeout = async <T>(promise: Promise<T>, ms: number) => {
+    let timeoutId: ReturnType<typeof setTimeout>;
+    const rejectOnTimeout = new Promise<T>((_, reject) => {
+        timeoutId = setTimeout(
+            () => reject(new Error("Operation timed out")),
+            ms,
+        );
+    });
+    const promiseAndCancelTimeout = async () => {
+        const result = await promise;
+        clearTimeout(timeoutId);
+        return result;
+    };
+    return Promise.race([promiseAndCancelTimeout(), rejectOnTimeout]);
+};