import { serviceAdapters, apiDocs } from '../services/api'; class RequestManager { constructor() { this.pendingRequests = new Map(); this.requestTimeouts = new Map(); } /** * Debounced request function that cancels previous requests of the same type * @param {string} requestType - Type of request (e.g., 'serviceStatus', 'systemData') * @param {Function} requestFunction - The actual request function to execute * @param {number} debounceMs - Debounce delay in milliseconds * @returns {Promise} - Promise that resolves with the request result */ async debouncedRequest(requestType, requestFunction, _debounceMs = 1000) { // Cancel any pending request of the same type if (this.pendingRequests.has(requestType)) { const { controller, timeoutId } = this.pendingRequests.get(requestType); controller.abort(); clearTimeout(timeoutId); } // Create new abort controller for this request const controller = new AbortController(); const timeoutId = setTimeout(() => { controller.abort(); }, 30000); // 30 second timeout // Store the request info this.pendingRequests.set(requestType, { controller, timeoutId }); try { const result = await requestFunction(controller.signal); this.pendingRequests.delete(requestType); clearTimeout(timeoutId); return result; } catch (error) { this.pendingRequests.delete(requestType); clearTimeout(timeoutId); if (error.name === 'AbortError') { throw new Error('Request was cancelled'); } throw error; } } /** * Get service status with debouncing */ async getServiceStatus(_signal) { const [adaptersResult, docsResult] = await Promise.allSettled([ serviceAdapters.health(), apiDocs.health() ]); return { adapters: adaptersResult, docs: docsResult }; } /** * Get system data with debouncing */ async getSystemData(_signal) { const [servicesResult, eventsResult] = await Promise.allSettled([ serviceAdapters.getServices(), serviceAdapters.getEvents(10) ]); return { services: servicesResult, events: eventsResult }; } /** * Cancel all pending requests */ cancelAllRequests() { this.pendingRequests.forEach(({ controller, timeoutId }) => { controller.abort(); clearTimeout(timeoutId); }); this.pendingRequests.clear(); } /** * Cancel specific request type */ cancelRequest(requestType) { if (this.pendingRequests.has(requestType)) { const { controller, timeoutId } = this.pendingRequests.get(requestType); controller.abort(); clearTimeout(timeoutId); this.pendingRequests.delete(requestType); } } } // Export singleton instance export const requestManager = new RequestManager();