From: Chris Duncan Date: Thu, 6 Aug 2026 05:42:41 +0000 (-0700) Subject: Remove unused job property and 10 second vault request timeout to support UX. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=df61bcf30563aa042c03edfe654f866a1771f7f6;p=libnemo.git Remove unused job property and 10 second vault request timeout to support UX. --- diff --git a/src/lib/vault/index.ts b/src/lib/vault/index.ts index e45b70d..5d19bd4 100644 --- a/src/lib/vault/index.ts +++ b/src/lib/vault/index.ts @@ -15,6 +15,7 @@ type Task = { data: TaskData reject: (value: any) => void resolve: (value: any) => void + timeout: number | NodeJS.Timeout } //@ts-expect-error @@ -25,7 +26,6 @@ const TERMINATED = 'Worker terminated' export class Vault { #eventTarget: EventTarget = new EventTarget() - #job?: Task #isLocked: boolean = true #isTerminated: boolean = false #tasks: Map = new Map() @@ -44,7 +44,8 @@ export class Vault { BROWSER: { this.#url = URL.createObjectURL(new Blob([vaultWorker], { type: 'text/javascript' })) this.#worker = new Worker(this.#url, { type: 'module' }) - this.#worker.addEventListener('message', listener) + this.#worker.addEventListener('message', this.#report) + this.#worker.addEventListener('error', this.terminate) } NODE: { this.#worker = new NodeWorker(vaultWorker, { @@ -59,7 +60,7 @@ export class Vault { get isLocked (): boolean { return this.#isLocked } - request> (payload: Record>): Promise> { + request> (payload: Record> & Record<'action', string>): Promise> { if (this.#isTerminated) { throw new Error(TERMINATED) } @@ -76,17 +77,26 @@ export class Vault { taskId } return new Promise((resolve, reject): void => { + const timeout = setTimeout(() => { + this.#tasks.delete(taskId) + reject(new Error('Vault request timed out', { cause: payload.action })) + }, 10_000) const task: Task = { data, resolve, - reject + reject, + timeout } this.#tasks.set(taskId, task) try { BROWSER: this.#worker.postMessage(data, buffers) NODE: this.#worker.postMessage({ data }, buffers) } catch (err) { + clearTimeout(timeout) this.#tasks.delete(taskId) + for (const buffer of buffers) { + new Uint8Array(buffer).fill(0) + } reject(err) } }) @@ -98,20 +108,20 @@ export class Vault { BROWSER: URL.revokeObjectURL(this.#url) //@ts-expect-error NODE: this.#worker.unref() - this.#job?.reject(TERMINATED) - this.#job = undefined for (const [_, task] of this.#tasks) { task?.reject?.(TERMINATED) } this.#tasks.clear() } - #report (results: unknown): void { - if (results == null) return - const { taskUrl, taskId, error, isLocked } = results as Record + #report (message: unknown): void { + if (message == null || typeof message !== 'object') return + if (!('data' in message) || message.data == null || typeof message !== 'object') return + const results = message.data as Record + const { taskUrl, taskId, error, isLocked } = results if (taskUrl === this.#url) { if (typeof taskId !== 'string') { - throw new Error('Vault worker job invalid ID') + throw new Error('Vault worker job invalid ID', { cause: typeof taskId }) } if (typeof isLocked === 'boolean' && this.#isLocked !== isLocked) { this.#isLocked = isLocked @@ -125,7 +135,7 @@ export class Vault { } const { resolve, reject } = task if (error != null) { - reject(results) + reject(new Error(String(error))) } else { resolve(results) }