@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.
80 lines • 3.51 kB
JavaScript
/**
* @module RateLimiter
*/
import {} from "../../../../backoff-policies/contracts/_module.js";
import { exponentialBackoff } from "../../../../backoff-policies/implementations/_module.js";
import {} from "../../../../execution-context/contracts/_module.js";
import {} from "../../../../rate-limiter/contracts/_module.js";
import { InternalRateLimiterPolicy, } from "../../../../rate-limiter/implementations/adapters/database-rate-limiter-adapter/internal-rate-limiter-policy.js";
import { RateLimiterStateManager } from "../../../../rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-state-manager.js";
import { RateLimiterStorage } from "../../../../rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-storage.js";
import { FixedWindowLimiter } from "../../../../rate-limiter/implementations/policies/_module.js";
import { TimeSpan } from "../../../../time-span/implementations/_module.js";
/**
* IMPORT_PATH: `"@daiso-tech/core/rate-limiter/database-rate-limiter-adapter"`
* @group Adapters
*/
export class DatabaseRateLimiterAdapter {
rateLimiterStorage;
rateLimiterStateManager;
/**
* @example
* ```ts
* import { DatabaseRateLimiterAdapter } from "@daiso-tech/core/rate-limiter/database-rate-limiter-adapter";
* import { MemoryRateLimiterStorageAdapter } from "@daiso-tech/core/rate-limiter/memory-rate-limiter-storage-adapter";
*
* const rateLimiterStorageAdapter = new MemoryRateLimiterStorageAdapter();
* const rateLimiterAdapter = new DatabaseRateLimiterAdapter({
* adapter: rateLimiterStorageAdapter
* });
* ```
*/
constructor(settings) {
const { adapter, backoffPolicy = exponentialBackoff(), rateLimiterPolicy = new FixedWindowLimiter(), } = settings;
const internalRateLimiterPolicy = new InternalRateLimiterPolicy(rateLimiterPolicy);
this.rateLimiterStorage = new RateLimiterStorage({
adapter: adapter,
rateLimiterPolicy: internalRateLimiterPolicy,
backoffPolicy,
});
this.rateLimiterStateManager = new RateLimiterStateManager(internalRateLimiterPolicy, backoffPolicy);
}
async getState(context, key) {
const state = await this.rateLimiterStorage.find(context, key);
if (state === null) {
return null;
}
return {
success: state.success,
attempt: state.attempt,
resetTime: TimeSpan.fromDateRange({
end: state.resetTime,
}),
};
}
async updateState(context, key, limit) {
const currentDate = new Date();
const track = this.rateLimiterStateManager.track(currentDate);
const updateState = this.rateLimiterStateManager.updateState(limit, currentDate);
const state = await this.rateLimiterStorage.atomicUpdate({
context,
key,
update: (prevState) => {
const newState1 = track(prevState);
const newState2 = updateState(newState1);
return newState2;
},
});
return {
success: state.success,
attempt: state.attempt,
resetTime: TimeSpan.fromDateRange({
end: state.resetTime,
}),
};
}
async reset(context, key) {
await this.rateLimiterStorage.remove(context, key);
}
}
//# sourceMappingURL=database-rate-limiter-adapter.js.map