diff --git a/src/rdrama/session/SessionManager.ts b/src/rdrama/session/SessionManager.ts index 56a314c..dd4801f 100644 --- a/src/rdrama/session/SessionManager.ts +++ b/src/rdrama/session/SessionManager.ts @@ -1,13 +1,18 @@ -import axios, {AxiosInstance, AxiosError} from 'axios'; +import axios, { AxiosInstance, AxiosError, AxiosResponse, AxiosRequestConfig } from 'axios'; import axiosRetry from 'axios-retry'; -import axiosThrottle from 'axios-request-throttle'; +import Bottleneck from 'bottleneck'; class SessionManager { private static instance: SessionManager; public readonly axiosInstance: AxiosInstance; + private limiter: Bottleneck; private constructor() { - axiosThrottle.use(axios, { requestsPerSecond: 1 }); // Throttle setup + // Initialize the Bottleneck limiter + this.limiter = new Bottleneck({ + maxConcurrent: 1, // Maximum number of concurrent requests + minTime: 1000 // Minimum time between dispatches of requests in milliseconds + }); this.axiosInstance = axios.create({ baseURL: 'https://rdrama.net/', @@ -16,6 +21,9 @@ class SessionManager { }, }); + // Wrap axios requests with the limiter + this.wrapAxiosInstance(this.axiosInstance); + axiosRetry(this.axiosInstance, { retries: 3, retryDelay: this.retryDelayStrategy, @@ -41,7 +49,33 @@ class SessionManager { private retryCondition(error: AxiosError): boolean { const status = error.response?.status ?? 0; - return status === 429 || status >= 400; + return status === 429 || status >= 500; + } + + private wrapAxiosInstance(instance: AxiosInstance): void { + // Wrap the get method + const originalGet = instance.get; + instance.get = >(url: string, config?: AxiosRequestConfig): Promise => { + return this.limiter.schedule(() => originalGet.apply(instance, [url, config])) as Promise; + }; + + // Wrap the post method + const originalPost = instance.post; + instance.post = >(url: string, data?: any, config?: AxiosRequestConfig): Promise => { + return this.limiter.schedule(() => originalPost.apply(instance, [url, data, config])) as Promise; + }; + + // Wrap the put method + const originalPut = instance.put; + instance.put = >(url: string, data?: any, config?: AxiosRequestConfig): Promise => { + return this.limiter.schedule(() => originalPut.apply(instance, [url, data, config])) as Promise; + }; + + // Wrap the delete method + const originalDelete = instance.delete; + instance.delete = >(url: string, config?: AxiosRequestConfig): Promise => { + return this.limiter.schedule(() => originalDelete.apply(instance, [url, config])) as Promise; + }; } public setAuthorizationToken(token: string): void {