Browse Source

Tighten type checking progressively

Manav Rathi 1 year ago
parent
commit
7be4b47e51

+ 0 - 5
desktop/.eslintrc.js

@@ -7,11 +7,6 @@ module.exports = {
         // "plugin:@typescript-eslint/strict-type-checked",
         // "plugin:@typescript-eslint/stylistic-type-checked",
     ],
-    /* Temporarily disable some rules
-       Enhancement: Remove me */
-    rules: {
-        "no-unused-vars": "off",
-    },
     /* Temporarily add a global
        Enhancement: Remove me */
     globals: {

+ 17 - 17
desktop/docs/dependencies.md

@@ -61,15 +61,15 @@ Electron process. This allows us to directly use the output produced by
 
 ### Others
 
-* [any-shell-escape](https://github.com/boazy/any-shell-escape) is for
-  escaping shell commands before we execute them (e.g. say when invoking the
-  embedded ffmpeg CLI).
+-   [any-shell-escape](https://github.com/boazy/any-shell-escape) is for
+    escaping shell commands before we execute them (e.g. say when invoking the
+    embedded ffmpeg CLI).
 
-* [auto-launch](https://github.com/Teamwork/node-auto-launch) is for
-  automatically starting our app on login, if the user so wishes.
+-   [auto-launch](https://github.com/Teamwork/node-auto-launch) is for
+    automatically starting our app on login, if the user so wishes.
 
-* [electron-store](https://github.com/sindresorhus/electron-store) is used for
-  persisting user preferences and other arbitrary data.
+-   [electron-store](https://github.com/sindresorhus/electron-store) is used for
+    persisting user preferences and other arbitrary data.
 
 ## Dev
 
@@ -79,12 +79,12 @@ are similar to that in the web code.
 
 Some extra ones specific to the code here are:
 
-* [concurrently](https://github.com/open-cli-tools/concurrently) for spawning
-  parallel tasks when we do `yarn dev`.
+-   [concurrently](https://github.com/open-cli-tools/concurrently) for spawning
+    parallel tasks when we do `yarn dev`.
 
-* [shx](https://github.com/shelljs/shx) for providing a portable way to use Unix
-  commands in our `package.json` scripts. This allows us to use the same
-  commands (like `ln`) across different platforms like Linux and Windows.
+-   [shx](https://github.com/shelljs/shx) for providing a portable way to use
+    Unix commands in our `package.json` scripts. This allows us to use the same
+    commands (like `ln`) across different platforms like Linux and Windows.
 
 ## Functionality
 
@@ -111,11 +111,11 @@ watcher for the watch folders functionality.
 
 ### AI/ML
 
-* [onnxruntime-node](https://github.com/Microsoft/onnxruntime)
-* html-entities is used by the bundled clip-bpe-ts.
-* GGML binaries are bundled
-* We also use [jpeg-js](https://github.com/jpeg-js/jpeg-js#readme) for
-  conversion of all images to JPEG before processing.
+-   [onnxruntime-node](https://github.com/Microsoft/onnxruntime)
+-   html-entities is used by the bundled clip-bpe-ts.
+-   GGML binaries are bundled
+-   We also use [jpeg-js](https://github.com/jpeg-js/jpeg-js#readme) for
+    conversion of all images to JPEG before processing.
 
 ## ZIP
 

+ 0 - 3
desktop/src/main/init.ts

@@ -1,6 +1,5 @@
 import { app, BrowserWindow, nativeImage, Tray } from "electron";
 import { existsSync } from "node:fs";
-import os from "node:os";
 import path from "node:path";
 import { isAppQuitting, rendererURL } from "../main";
 import autoLauncher from "../services/autoLauncher";
@@ -77,8 +76,6 @@ export const createWindow = async () => {
     return mainWindow;
 };
 
-export async function handleUpdates(mainWindow: BrowserWindow) {}
-
 export const setupTrayItem = (mainWindow: BrowserWindow) => {
     const iconName = isPlatform("mac")
         ? "taskbar-icon-Template.png"

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

@@ -94,16 +94,16 @@ export const attachIPCHandlers = () => {
 
     // - General
 
-    ipcMain.handle("appVersion", (_) => appVersion());
+    ipcMain.handle("appVersion", () => appVersion());
 
     ipcMain.handle("openDirectory", (_, dirPath) => openDirectory(dirPath));
 
-    ipcMain.handle("openLogDirectory", (_) => openLogDirectory());
+    ipcMain.handle("openLogDirectory", () => openLogDirectory());
 
     // See [Note: Catching exception during .send/.on]
     ipcMain.on("logToDisk", (_, message) => logToDisk(message));
 
-    ipcMain.on("clear-electron-store", (_) => {
+    ipcMain.on("clear-electron-store", () => {
         clearElectronStore();
     });
 
@@ -111,11 +111,11 @@ export const attachIPCHandlers = () => {
         setEncryptionKey(encryptionKey),
     );
 
-    ipcMain.handle("getEncryptionKey", (_) => getEncryptionKey());
+    ipcMain.handle("getEncryptionKey", () => getEncryptionKey());
 
     // - App update
 
-    ipcMain.on("update-and-restart", (_) => updateAndRestart());
+    ipcMain.on("update-and-restart", () => updateAndRestart());
 
     ipcMain.on("skip-app-update", (_, version) => skipAppUpdate(version));
 
@@ -160,13 +160,13 @@ export const attachIPCHandlers = () => {
 
     // - File selection
 
-    ipcMain.handle("selectDirectory", (_) => selectDirectory());
+    ipcMain.handle("selectDirectory", () => selectDirectory());
 
-    ipcMain.handle("showUploadFilesDialog", (_) => showUploadFilesDialog());
+    ipcMain.handle("showUploadFilesDialog", () => showUploadFilesDialog());
 
-    ipcMain.handle("showUploadDirsDialog", (_) => showUploadDirsDialog());
+    ipcMain.handle("showUploadDirsDialog", () => showUploadDirsDialog());
 
-    ipcMain.handle("showUploadZipDialog", (_) => showUploadZipDialog());
+    ipcMain.handle("showUploadZipDialog", () => showUploadZipDialog());
 
     // - FS
 
@@ -206,7 +206,7 @@ export const attachIPCHandlers = () => {
 
     // - Upload
 
-    ipcMain.handle("getPendingUploads", (_) => getPendingUploads());
+    ipcMain.handle("getPendingUploads", () => getPendingUploads());
 
     ipcMain.handle(
         "setToUploadFiles",
@@ -255,7 +255,7 @@ export const attachFSWatchIPCHandlers = (watcher: FSWatcher) => {
         removeWatchMapping(watcher, folderPath),
     );
 
-    ipcMain.handle("getWatchMappings", (_) => getWatchMappings());
+    ipcMain.handle("getWatchMappings", () => getWatchMappings());
 
     ipcMain.handle(
         "updateWatchMappingSyncedFiles",

+ 2 - 1
desktop/src/preload.ts

@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-vars */
 /**
  * @file The preload script
  *
@@ -53,7 +54,7 @@ import type {
 const appVersion = (): Promise<string> => ipcRenderer.invoke("appVersion");
 
 const openDirectory = (dirPath: string): Promise<void> =>
-    ipcRenderer.invoke("openDirectory");
+    ipcRenderer.invoke("openDirectory", dirPath);
 
 const openLogDirectory = (): Promise<void> =>
     ipcRenderer.invoke("openLogDirectory");

+ 15 - 12
desktop/src/services/clipService.ts

@@ -2,11 +2,10 @@ import { app, net } from "electron/main";
 import { existsSync } from "fs";
 import fs from "node:fs/promises";
 import path from "node:path";
-import { CustomErrors } from "../types/ipc";
 import { writeStream } from "../main/fs";
 import log from "../main/log";
 import { execAsync, isDev } from "../main/util";
-import { Model } from "../types/ipc";
+import { CustomErrors, Model, isModel } from "../types/ipc";
 import Tokenizer from "../utils/clip-bpe-ts/mod";
 import { getPlatform } from "../utils/common/platform";
 import { generateTempFilePath } from "../utils/temp";
@@ -200,6 +199,8 @@ export const computeImageEmbedding = async (
     model: Model,
     imageData: Uint8Array,
 ): Promise<Float32Array> => {
+    if (!isModel(model)) throw new Error(`Invalid CLIP model ${model}`);
+
     let tempInputFilePath = null;
     try {
         tempInputFilePath = await generateTempFilePath("");
@@ -247,12 +248,11 @@ async function computeImageEmbedding_(
     if (!existsSync(inputFilePath)) {
         throw new Error("Invalid file path");
     }
-    if (model === Model.GGML_CLIP) {
-        return await computeGGMLImageEmbedding(inputFilePath);
-    } else if (model === Model.ONNX_CLIP) {
-        return await computeONNXImageEmbedding(inputFilePath);
-    } else {
-        throw new Error(`Invalid CLIP model ${model}`);
+    switch (model) {
+        case "ggml-clip":
+            return await computeGGMLImageEmbedding(inputFilePath);
+        case "onnx-clip":
+            return await computeONNXImageEmbedding(inputFilePath);
     }
 }
 
@@ -387,6 +387,8 @@ export async function computeTextEmbedding(
     model: Model,
     text: string,
 ): Promise<Float32Array> {
+    if (!isModel(model)) throw new Error(`Invalid CLIP model ${model}`);
+
     try {
         const embedding = computeTextEmbedding_(model, text);
         return embedding;
@@ -404,10 +406,11 @@ async function computeTextEmbedding_(
     model: Model,
     text: string,
 ): Promise<Float32Array> {
-    if (model === Model.GGML_CLIP) {
-        return await computeGGMLTextEmbedding(text);
-    } else {
-        return await computeONNXTextEmbedding(text);
+    switch (model) {
+        case "ggml-clip":
+            return await computeGGMLTextEmbedding(text);
+        case "onnx-clip":
+            return await computeONNXTextEmbedding(text);
     }
 }
 

+ 2 - 0
desktop/src/services/fs.ts

@@ -115,7 +115,9 @@ export const getZipFileStream = async (
     const inProgress = {
         current: false,
     };
+    // eslint-disable-next-line no-unused-vars
     let resolveObj: (value?: any) => void = null;
+    // eslint-disable-next-line no-unused-vars
     let rejectObj: (reason?: any) => void = null;
     stream.on("readable", () => {
         try {

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

@@ -1,11 +1,10 @@
 import { existsSync } from "fs";
 import fs from "node:fs/promises";
 import path from "path";
-import { CustomErrors } from "../types/ipc";
 import { writeStream } from "../main/fs";
 import log from "../main/log";
 import { execAsync, isDev } from "../main/util";
-import { ElectronFile } from "../types/ipc";
+import { CustomErrors, ElectronFile } from "../types/ipc";
 import { isPlatform } from "../utils/common/platform";
 import { generateTempFilePath } from "../utils/temp";
 import { deleteTempFile } from "./ffmpeg";

+ 1 - 0
desktop/src/types/any-shell-escape.d.ts

@@ -19,6 +19,7 @@
  *     curl -v -H "Location;" -H "User-Agent: FooBar's so-called ""Browser""" "http://www.daveeddy.com/?name=dave&age=24"
 Which is suitable for being executed by the shell.
  */
+/* eslint-disable no-unused-vars */
 declare module "any-shell-escape" {
     declare const shellescape: (args: readonly string | string[]) => string;
     export default shellescape;

+ 4 - 4
desktop/src/types/ipc.ts

@@ -71,6 +71,7 @@ export interface WatchStoreType {
 }
 
 export enum FILE_PATH_TYPE {
+    /* eslint-disable no-unused-vars */
     FILES = "files",
     ZIPS = "zips",
 }
@@ -80,7 +81,6 @@ export interface AppUpdateInfo {
     version: string;
 }
 
-export enum Model {
-    GGML_CLIP = "ggml-clip",
-    ONNX_CLIP = "onnx-clip",
-}
+export type Model = "ggml-clip" | "onnx-clip";
+
+export const isModel = (s: unknown) => s == "ggml-clip" || s == "onnx-clip";

+ 1 - 0
desktop/src/types/main.ts

@@ -18,6 +18,7 @@ export interface KeysStoreType {
     };
 }
 
+/* eslint-disable no-unused-vars */
 export const FILE_PATH_KEYS: {
     [k in FILE_PATH_TYPE]: keyof UploadStoreType;
 } = {