mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-09 01:58:45 +00:00
* chore: add prettier configuration Signed-off-by: Xe Iaso <me@xeiaso.net> * format: run prettier tree-wide Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(prettier): ignore intentionally ungrammatical files Signed-off-by: Xe Iaso <me@xeiaso.net> * ci: add PR title lint rule Signed-off-by: Xe Iaso <me@xeiaso.net> * ci: add DCO check Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: add commitlint and husky Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: add CONTRIBUTING guidelines Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: set SKIP_INTEGRATION in precommit tests Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: update spelling Signed-off-by: Xe Iaso <me@xeiaso.net> * ci(dco): remove reopened trigger Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: remove dead file Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(prettier): don't format nginx includes Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net>
96 lines
2.3 KiB
TypeScript
96 lines
2.3 KiB
TypeScript
type ProgressCallback = (nonce: number) => void;
|
||
|
||
interface ProcessOptions {
|
||
basePrefix: string;
|
||
version: string;
|
||
}
|
||
|
||
const getHardwareConcurrency = () =>
|
||
navigator.hardwareConcurrency !== undefined
|
||
? navigator.hardwareConcurrency
|
||
: 1;
|
||
|
||
export default function process(
|
||
options: ProcessOptions,
|
||
data: string,
|
||
difficulty: number = 5,
|
||
signal: AbortSignal | null = null,
|
||
progressCallback?: ProgressCallback,
|
||
threads: number = Math.trunc(Math.max(getHardwareConcurrency() / 2, 1)),
|
||
): Promise<string> {
|
||
console.debug("fast algo");
|
||
|
||
// Choose worker based on secure context.
|
||
// Use the WebCrypto worker if the page is a secure context; otherwise fall back to pure‑JS.
|
||
let workerMethod: "webcrypto" | "purejs" = "purejs";
|
||
if (window.isSecureContext) {
|
||
workerMethod = "webcrypto";
|
||
}
|
||
|
||
if (
|
||
navigator.userAgent.includes("Firefox") ||
|
||
navigator.userAgent.includes("Goanna")
|
||
) {
|
||
console.log("Firefox detected, using pure-JS fallback");
|
||
workerMethod = "purejs";
|
||
}
|
||
|
||
return new Promise((resolve, reject) => {
|
||
let webWorkerURL = `${options.basePrefix}/.within.website/x/cmd/anubis/static/js/worker/sha256-${workerMethod}.mjs?cacheBuster=${options.version}`;
|
||
|
||
const workers: Worker[] = [];
|
||
let settled = false;
|
||
|
||
const onAbort = () => {
|
||
console.log("PoW aborted");
|
||
cleanup();
|
||
reject(new DOMException("Aborted", "AbortError"));
|
||
};
|
||
|
||
const cleanup = () => {
|
||
if (settled) {
|
||
return;
|
||
}
|
||
settled = true;
|
||
workers.forEach((w) => w.terminate());
|
||
if (signal != null) {
|
||
signal.removeEventListener("abort", onAbort);
|
||
}
|
||
};
|
||
|
||
if (signal != null) {
|
||
if (signal.aborted) {
|
||
return onAbort();
|
||
}
|
||
signal.addEventListener("abort", onAbort, { once: true });
|
||
}
|
||
|
||
for (let i = 0; i < threads; i++) {
|
||
let worker = new Worker(webWorkerURL);
|
||
|
||
worker.onmessage = (event) => {
|
||
if (typeof event.data === "number") {
|
||
progressCallback?.(event.data);
|
||
} else {
|
||
cleanup();
|
||
resolve(event.data);
|
||
}
|
||
};
|
||
|
||
worker.onerror = (event) => {
|
||
cleanup();
|
||
reject(event);
|
||
};
|
||
|
||
worker.postMessage({
|
||
data,
|
||
difficulty,
|
||
nonce: i,
|
||
threads,
|
||
});
|
||
|
||
workers.push(worker);
|
||
}
|
||
});
|
||
}
|