@kareemaly/researcher
Version:
CLI tool for web research
70 lines (69 loc) • 2.45 kB
JavaScript
;
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;