UNPKG

@kareemaly/researcher

Version:
70 lines (69 loc) 2.45 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileLockRateLimiter = void 0; const promises_1 = __importDefault(require("fs/promises")); const logger_1 = require("./logger"); const log = (0, logger_1.createLogger)("rate-limiter"); class FileLockRateLimiter { constructor(config) { this.config = config; } async initialize() { await this.ensureLockFile(); } async ensureLockFile() { try { await promises_1.default.access(this.config.lockFilePath); } catch { await promises_1.default.writeFile(this.config.lockFilePath, JSON.stringify({ lastRequest: new Date().toISOString(), requestCount: 0, })); } } async readLock() { const data = await promises_1.default.readFile(this.config.lockFilePath, "utf-8"); return JSON.parse(data); } async writeLock(lock) { await promises_1.default.writeFile(this.config.lockFilePath, JSON.stringify(lock)); } async acquire() { await this.ensureLockFile(); const lock = await this.readLock(); const now = new Date(); const lastRequest = new Date(lock.lastRequest); const timeDiff = (now.getTime() - lastRequest.getTime()) / 1000; if (timeDiff >= this.config.periodSeconds) { // Reset if period has passed await this.writeLock({ lastRequest: now.toISOString(), requestCount: 1, }); } else if (lock.requestCount < this.config.requestsPerPeriod) { // Increment if under limit await this.writeLock({ lastRequest: lock.lastRequest, requestCount: lock.requestCount + 1, }); } else { // Wait for next period const waitTime = (this.config.periodSeconds - timeDiff) * 1000; await new Promise((resolve) => setTimeout(resolve, waitTime)); await this.writeLock({ lastRequest: new Date().toISOString(), requestCount: 1, }); } } async release() { // No-op for file-based rate limiting } } exports.FileLockRateLimiter = FileLockRateLimiter;