UNPKG

3.26 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const axios_1 = require("axios");
4class RequestLimiter {
5 constructor(max_requests, interval, axiosClient) {
6 this.max_requests = 3;
7 this.interval = 3000;
8 this.requests = 0;
9 this.lastRequest = 0;
10 this.timer = false;
11 this.queue = [];
12 /**
13 * Wrap the callable given by the user and wrap it in a promise
14 * @param callable
15 * @returns {Promise<any>}
16 */
17 this.wrapCallable = async (callable) => {
18 let resolvedCallback = null;
19 let rejectCallback = null;
20 const delayedPromise = new Promise((resolve, reject) => {
21 resolvedCallback = resolve;
22 rejectCallback = reject;
23 });
24 this.queue.push({
25 resolve: resolvedCallback,
26 reject: rejectCallback,
27 callable: callable
28 });
29 return delayedPromise;
30 };
31 /**
32 * Check if a new item from the queue should be called
33 */
34 this.check = () => {
35 if (this.timer === false || this.queue.length > 0) {
36 this.setTimer();
37 }
38 // check if we have reached the rate limit yet for this limiter
39 if (this.queue.length > 0 && this.requests < this.max_requests) {
40 // run as many requests as possible
41 for (let i = this.requests; i < this.max_requests; i++) {
42 const queueItem = this.queue.shift();
43 if (!queueItem)
44 break;
45 this.requests++;
46 this.lastRequest = Date.now();
47 Promise.resolve(queueItem.callable(this.axiosClient))
48 .then(queueItem.resolve)
49 .catch(queueItem.reject);
50 }
51 this.check();
52 }
53 if (this.queue.length === 0) {
54 this.clearTimer();
55 }
56 };
57 /**
58 * Start the timer which updates and resets the limits
59 */
60 this.setTimer = () => {
61 if (this.timer !== false)
62 return;
63 this.timer = setInterval(() => {
64 if (this.queue.length === 0) {
65 this.clearTimer();
66 }
67 this.requests = 0;
68 this.check();
69 }, this.interval);
70 };
71 /**
72 * Clear the timer
73 */
74 this.clearTimer = () => {
75 if (this.timer !== false) {
76 clearInterval(this.timer);
77 this.timer = false;
78 }
79 };
80 /**
81 * Run the request limit checker
82 * @param callable
83 * @returns {any}
84 */
85 this.run = async (callable) => {
86 const promise = this.wrapCallable(callable);
87 this.check();
88 return promise;
89 };
90 this.max_requests = max_requests;
91 this.interval = interval;
92 // default to standard axios instance
93 this.axiosClient = axiosClient || axios_1.default;
94 }
95}
96exports.default = RequestLimiter;