fee254e7e6
- Backend: Koa + @koa/router serving the HIBP-style /range/:prefix k-anonymity API, backed by Postgres via pg, with migrate/seed scripts run through tsx. - Frontend: React + wouter, bundled with webpack (dev server + prod build), thin client that hashes passwords locally and only sends the hash prefix. - Import package: CLI to bulk-load a wordlist or hash list into the database, plus a separate script to pull the full dataset from the HIBP range API. Both support parallelism (worker threads for wordlist hashing, concurrency limiter for DB/HTTP fan-out). - Dev tooling: docker compose for a local Postgres, .env.local/.env.example, DATABASE_URL support as an alternative to discrete PG* vars.
24 lines
569 B
TypeScript
24 lines
569 B
TypeScript
// Bounds how many async tasks run at once. Used both for fanning out
|
|
// concurrent DB upserts and concurrent HTTP requests.
|
|
export function createLimiter(concurrency: number) {
|
|
let active = 0;
|
|
const queue: Array<() => void> = [];
|
|
|
|
function release() {
|
|
active--;
|
|
queue.shift()?.();
|
|
}
|
|
|
|
return async function limit<T>(fn: () => Promise<T>): Promise<T> {
|
|
if (active >= concurrency) {
|
|
await new Promise<void>((resolve) => queue.push(resolve));
|
|
}
|
|
active++;
|
|
try {
|
|
return await fn();
|
|
} finally {
|
|
release();
|
|
}
|
|
};
|
|
}
|