adpa-enterprise-framework-automation
Version:
Modular, standards-compliant Node.js/TypeScript automation framework for enterprise requirements, project, and data management. Provides CLI and API for BABOK v3, PMBOK 7th Edition, and DMBOK 2.0 (in progress). Production-ready Express.js API with TypeSpe
71 lines • 2.35 kB
JavaScript
/**
* Rate Limiter Implementation
* Controls API request rates to prevent exceeding service limits
*/
export class RateLimiter {
config;
minuteRequests = [];
hourRequests = [];
constructor(config) {
this.config = config;
}
async waitForAvailableSlot() {
const now = Date.now();
// Clean old requests
this.cleanOldRequests(now);
// Check if we can make a request
if (this.canMakeRequest()) {
this.recordRequest(now);
return;
}
// Calculate wait time
const waitTime = this.calculateWaitTime(now);
if (waitTime > 0) {
await this.sleep(waitTime);
return this.waitForAvailableSlot();
}
}
canMakeRequest() {
return this.minuteRequests.length < this.config.requestsPerMinute &&
this.hourRequests.length < this.config.requestsPerHour;
}
cleanOldRequests(now) {
const oneMinuteAgo = now - 60 * 1000;
const oneHourAgo = now - 60 * 60 * 1000;
this.minuteRequests = this.minuteRequests.filter(req => req.timestamp > oneMinuteAgo);
this.hourRequests = this.hourRequests.filter(req => req.timestamp > oneHourAgo);
}
recordRequest(timestamp) {
const record = { timestamp };
this.minuteRequests.push(record);
this.hourRequests.push(record);
}
calculateWaitTime(now) {
if (this.minuteRequests.length >= this.config.requestsPerMinute) {
const oldestRequest = this.minuteRequests[0];
return (oldestRequest.timestamp + 60 * 1000) - now;
}
if (this.hourRequests.length >= this.config.requestsPerHour) {
const oldestRequest = this.hourRequests[0];
return (oldestRequest.timestamp + 60 * 60 * 1000) - now;
}
return 0;
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
getStatus() {
const now = Date.now();
this.cleanOldRequests(now);
return {
minuteRequests: this.minuteRequests.length,
hourRequests: this.hourRequests.length
};
}
}
// Legacy compatibility export
export const rateLimiter = new RateLimiter({
requestsPerMinute: 60,
requestsPerHour: 1000
});
//# sourceMappingURL=rate-limiter.js.map