import { AUTH_RATE_LIMIT_SCOPE_DEFAULT, normalizeRateLimitClientIp } from "./auth-rate-limit.js" ;
const pendingAttempts = new Map<string, Promise<void >>();
function normalizeScope(scope: string | undefined): string {
return (scope ?? AUTH_RATE_LIMIT_SCOPE_DEFAULT).trim() || AUTH_RATE_LIMIT_SCOPE_DEFAULT;
}
function buildSerializationKey(ip: string | undefined, scope: string | undefined): string {
return `${normalizeScope(scope)}:${normalizeRateLimitClientIp(ip)}`;
}
export async function withSerializedRateLimitAttempt<T>(params: {
ip: string | undefined;
scope: string | undefined;
run: () => Promise<T>;
}): Promise<T> {
const key = buildSerializationKey(params.ip, params.scope);
const previous = pendingAttempts.get(key) ?? Promise.resolve();
let releaseCurrent!: () => void ;
const current = new Promise<void >((resolve) => {
releaseCurrent = resolve;
});
const tail = previous.catch (() => {}).then(() => current);
pendingAttempts.set(key, tail);
await previous.catch (() => {});
try {
return await params.run();
} finally {
releaseCurrent();
if (pendingAttempts.get(key) === tail) {
pendingAttempts.delete (key);
}
}
}
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland