Files
bitvid/js/nostr/nip04WorkerClient.js
T

109 lines
2.6 KiB
JavaScript

import { devLogger } from "../utils/logger.js";
const DEFAULT_TIMEOUT_MS = 12000;
let workerInstance = null;
let workerReady = false;
let requestId = 0;
const pending = new Map();
function attachWorkerListeners(worker) {
if (!worker || workerReady) {
return;
}
worker.addEventListener("message", (event) => {
const data = event?.data || {};
const id = data.id;
if (!pending.has(id)) {
return;
}
const entry = pending.get(id);
pending.delete(id);
clearTimeout(entry.timeoutId);
if (data.ok && typeof data.ciphertext === "string") {
entry.resolve(data.ciphertext);
return;
}
const message = data?.error?.message || "nip04-worker-error";
const error = new Error(message);
error.name = data?.error?.name || "Error";
entry.reject(error);
});
worker.addEventListener("error", (error) => {
devLogger.warn("[nip04WorkerClient] Worker error", error);
for (const entry of pending.values()) {
clearTimeout(entry.timeoutId);
entry.reject(error instanceof Error ? error : new Error("nip04-worker-error"));
}
pending.clear();
});
workerReady = true;
}
function ensureWorker() {
if (workerInstance) {
return workerInstance;
}
if (typeof Worker === "undefined") {
return null;
}
try {
workerInstance = new Worker(new URL("./nip04Worker.js", import.meta.url), {
type: "module",
});
attachWorkerListeners(workerInstance);
} catch (error) {
devLogger.warn("[nip04WorkerClient] Failed to create worker", error);
workerInstance = null;
}
return workerInstance;
}
export function encryptNip04InWorker({
privateKey,
targetPubkey,
plaintext,
timeoutMs = DEFAULT_TIMEOUT_MS,
} = {}) {
const worker = ensureWorker();
if (!worker) {
return Promise.reject(new Error("nip04-worker-unavailable"));
}
const trimmedPrivateKey =
typeof privateKey === "string" ? privateKey.trim() : "";
const trimmedTarget =
typeof targetPubkey === "string" ? targetPubkey.trim() : "";
const message = typeof plaintext === "string" ? plaintext : "";
if (!trimmedPrivateKey || !trimmedTarget) {
return Promise.reject(new Error("nip04-worker-invalid-input"));
}
const id = `${Date.now()}-${requestId++}`;
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
pending.delete(id);
reject(new Error("nip04-worker-timeout"));
}, timeoutMs);
pending.set(id, { resolve, reject, timeoutId });
worker.postMessage({
id,
privateKey: trimmedPrivateKey,
targetPubkey: trimmedTarget,
plaintext: message,
});
});
}