UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

59 lines 2.21 kB
/** * @module RateLimiter */ import {} from "../../../../backoff-policies/_module.js"; import { RATE_LIMITER_STATE, } from "../../../../rate-limiter/contracts/_module.js"; import {} from "../../../../rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-policy.js"; import { TimeSpan } from "../../../../time-span/implementations/time-span.js"; import { callInvokable } from "../../../../utilities/_module.js"; /** * @internal */ export class RateLimiterStorage { adapter; rateLimiterPolicy; backoffPolicy; constructor(settings) { const { adapter, rateLimiterPolicy, backoffPolicy } = settings; this.adapter = adapter; this.rateLimiterPolicy = rateLimiterPolicy; this.backoffPolicy = backoffPolicy; } async atomicUpdate(args) { const currentDate = new Date(); const state = await this.adapter.transaction(async (trx) => { const data = await this.adapter.find(args.key); let currentState = data?.state; if (currentState === undefined) { currentState = this.rateLimiterPolicy.initialState(currentDate); } const newState = args.update(currentState); await trx.upsert(args.key, newState, this.rateLimiterPolicy.getExpiration(newState, { backoffPolicy: this.backoffPolicy, currentDate, })); return newState; }); return this.toAdapterState(state); } toAdapterState(state) { return { success: state.type === RATE_LIMITER_STATE.ALLOWED, attempt: state.attempt, resetTime: state.type === RATE_LIMITER_STATE.ALLOWED ? null : TimeSpan.fromTimeSpan(callInvokable(this.backoffPolicy, state.attempt, null)).toEndDate(new Date(state.startedAt)), }; } async find(key) { const data = await this.adapter.find(key); if (data === null) { return null; } return this.toAdapterState(data.state); } async remove(key) { await this.adapter.remove(key); } } //# sourceMappingURL=rate-limiter-storage.js.map