This commit is contained in:
Manav Rathi 2024-04-30 13:56:11 +05:30
parent 14348351a9
commit 333f9c58f2
No known key found for this signature in database
13 changed files with 96 additions and 93 deletions

View file

@ -26,7 +26,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/utils/electron";
import { isDev } from "./main/utils";
/**
* The URL where the renderer HTML is being served from.

View file

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

View file

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

View file

@ -1,7 +1,7 @@
import { shell } from "electron/common";
import { app, dialog } from "electron/main";
import path from "node:path";
import { posixPath } from "../utils/electron";
import { posixPath } from "../utils";
export const selectDirectory = async () => {
const result = await dialog.showOpenDialog({

View file

@ -2,8 +2,8 @@ import pathToFfmpeg from "ffmpeg-static";
import fs from "node:fs/promises";
import type { ZipItem } from "../../types/ipc";
import log from "../log";
import { withTimeout } from "../utils";
import { execAsync } from "../utils/electron";
import { execAsync } from "../utils";
import { withTimeout } from "../utils/common";
import {
deleteTempFile,
makeFileForDataOrPathOrZipItem,

View file

@ -4,7 +4,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import { CustomErrorMessage, type ZipItem } from "../../types/ipc";
import log from "../log";
import { execAsync, isDev } from "../utils/electron";
import { execAsync, isDev } from "../utils";
import {
deleteTempFile,
makeFileForDataOrPathOrZipItem,

View file

@ -22,6 +22,7 @@ const cachedCLIPImageSession = makeCachedInferenceSession(
export const clipImageEmbedding = async (jpegImageData: Uint8Array) => {
const tempFilePath = await makeTempFilePath();
const imageStream = new Response(jpegImageData.buffer).body;
if (!imageStream) throw new Error("Missing body that we just fed data to");
await writeStream(tempFilePath, imageStream);
try {
return await clipImageEmbedding_(tempFilePath);
@ -134,11 +135,9 @@ const cachedCLIPTextSession = makeCachedInferenceSession(
64173509 /* 61.2 MB */,
);
let _tokenizer: Tokenizer = null;
let _tokenizer: Tokenizer | undefined;
const getTokenizer = () => {
if (!_tokenizer) {
_tokenizer = new Tokenizer();
}
if (!_tokenizer) _tokenizer = new Tokenizer();
return _tokenizer;
};

View file

@ -5,7 +5,7 @@ import path from "node:path";
import { FolderWatch, type CollectionMapping } from "../../types/ipc";
import log from "../log";
import { watchStore } from "../stores/watch";
import { posixPath } from "../utils/electron";
import { posixPath } from "../utils";
import { fsIsDir } from "./fs";
/**

View file

@ -99,7 +99,10 @@ const handleReadZip = async (zipPath: string, entryName: string) => {
try {
const zip = new StreamZip.async({ file: zipPath });
const entry = await zip.entry(entryName);
if (!entry) return new Response("", { status: 404 });
const stream = await zip.stream(entry);
// TODO(MR): when to call zip.close()
return new Response(Readable.toWeb(new Readable(stream)), {
@ -122,7 +125,7 @@ const handleReadZip = async (zipPath: string, entryName: string) => {
`Failed to read entry ${entryName} from zip file at ${zipPath}`,
e,
);
return new Response(`Failed to read stream: ${e.message}`, {
return new Response(`Failed to read stream: ${String(e)}`, {
status: 500,
});
}

View file

@ -0,0 +1,35 @@
/**
* @file grab bag of utility functions.
*
* 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]);
};

View file

@ -1,49 +0,0 @@
import shellescape from "any-shell-escape";
import { app } from "electron/main";
import { exec } from "node:child_process";
import path from "node:path";
import { promisify } from "node:util";
import log from "../log";
/** `true` if the app is running in development mode. */
export const isDev = !app.isPackaged;
/**
* Convert a file system {@link filePath} that uses the local system specific
* path separators into a path that uses POSIX file separators.
*/
export const posixPath = (filePath: string) =>
filePath.split(path.sep).join(path.posix.sep);
/**
* Run a shell command asynchronously.
*
* This is a convenience promisified version of child_process.exec. It runs the
* command asynchronously and returns its stdout and stderr if there were no
* errors.
*
* If the command is passed as a string, then it will be executed verbatim.
*
* If the command is passed as an array, then the first argument will be treated
* as the executable and the remaining (optional) items as the command line
* parameters. This function will shellescape and join the array to form the
* command that finally gets executed.
*
* > Note: This is not a 1-1 replacement of child_process.exec - if you're
* > trying to run a trivial shell command, say something that produces a lot of
* > output, this might not be the best option and it might be better to use the
* > underlying functions.
*/
export const execAsync = (command: string | string[]) => {
const escapedCommand = Array.isArray(command)
? shellescape(command)
: command;
const startTime = Date.now();
const result = execAsync_(escapedCommand);
log.debug(
() => `${escapedCommand} (${Math.round(Date.now() - startTime)} ms)`,
);
return result;
};
const execAsync_ = promisify(exec);

View file

@ -1,35 +1,49 @@
/**
* @file grab bag of utility 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.
*/
import shellescape from "any-shell-escape";
import { app } from "electron/main";
import { exec } from "node:child_process";
import path from "node:path";
import { promisify } from "node:util";
import log from "../log";
/** `true` if the app is running in development mode. */
export const isDev = !app.isPackaged;
/**
* Wait for {@link ms} milliseconds
*
* This function is a promisified `setTimeout`. It returns a promise that
* resolves after {@link ms} milliseconds.
* Convert a file system {@link filePath} that uses the local system specific
* path separators into a path that uses POSIX file separators.
*/
export const wait = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
export const posixPath = (filePath: string) =>
filePath.split(path.sep).join(path.posix.sep);
/**
* Await the given {@link promise} for {@link timeoutMS} milliseconds. If it
* does not resolve within {@link timeoutMS}, then reject with a timeout error.
* Run a shell command asynchronously.
*
* This is a convenience promisified version of child_process.exec. It runs the
* command asynchronously and returns its stdout and stderr if there were no
* errors.
*
* If the command is passed as a string, then it will be executed verbatim.
*
* If the command is passed as an array, then the first argument will be treated
* as the executable and the remaining (optional) items as the command line
* parameters. This function will shellescape and join the array to form the
* command that finally gets executed.
*
* > Note: This is not a 1-1 replacement of child_process.exec - if you're
* > trying to run a trivial shell command, say something that produces a lot of
* > output, this might not be the best option and it might be better to use the
* > underlying functions.
*/
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]);
export const execAsync = (command: string | string[]) => {
const escapedCommand = Array.isArray(command)
? shellescape(command)
: command;
const startTime = Date.now();
const result = execAsync_(escapedCommand);
log.debug(
() => `${escapedCommand} (${Math.round(Date.now() - startTime)} ms)`,
);
return result;
};
const execAsync_ = promisify(exec);

View file

@ -50,12 +50,12 @@
"outDir": "app",
/* Temporary overrides to get things to compile with the older config */
"strict": false,
"noImplicitAny": true
// "strict": false,
"noImplicitAny": true,
/* Below is the state we want */
/* Enable these one by one */
// "strict": true,
"strict": true,
/* Require the `type` modifier when importing types */
// "verbatimModuleSyntax": true