snort/packages/system/src/pow.ts

58 lines
1.4 KiB
TypeScript

import { v4 as uuid } from "uuid";
import { NostrEvent } from "./nostr";
import { PowWorkerMessage } from "./pow-worker";
export interface PowMiner {
minePow(ev: NostrEvent, target: number): Promise<NostrEvent>;
}
interface PowQueue {
resolve: (ev: NostrEvent) => void;
reject: () => void;
timeout: ReturnType<typeof setTimeout>;
}
export class PowWorker implements PowMiner {
#worker: Worker;
#queue: Map<string, PowQueue> = new Map();
constructor(workerPath: string) {
this.#worker = new Worker(workerPath, {
type: "module",
name: "POW",
});
this.#worker.onerror = ev => {
console.error(ev);
};
this.#worker.onmessage = ev => {
const data = ev.data as PowWorkerMessage;
const job = this.#queue.get(data.id);
if (job) {
clearTimeout(job.timeout);
this.#queue.delete(data.id);
job.resolve(data.event);
}
};
}
minePow(ev: NostrEvent, target: number) {
return new Promise<NostrEvent>((resolve, reject) => {
const req = {
id: uuid(),
cmd: "req",
event: ev,
target,
} as PowWorkerMessage;
this.#queue.set(req.id, {
resolve: ex => resolve(ex),
reject,
timeout: setTimeout(() => {
this.#queue.delete(req.id);
reject();
}, 600_000),
});
this.#worker.postMessage(req);
});
}
}