@enegalan/request-manager 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/request-manager.cjs.js +0 -4
- package/dist/request-manager.cjs.js.map +1 -1
- package/dist/request-manager.cjs.min.js +0 -4
- package/dist/request-manager.cjs.min.js.map +1 -1
- package/dist/request-manager.esm.js +0 -4
- package/dist/request-manager.esm.js.map +1 -1
- package/dist/request-manager.esm.min.js +0 -4
- package/dist/request-manager.esm.min.js.map +1 -1
- package/dist/request-manager.js +0 -4
- package/dist/request-manager.js.map +1 -1
- package/dist/request-manager.min.js +0 -4
- package/dist/request-manager.min.js.map +1 -1
- package/dist/request-manager.umd.js +0 -4
- package/dist/request-manager.umd.js.map +1 -1
- package/dist/request-manager.umd.min.js +0 -4
- package/dist/request-manager.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-manager.cjs.js","sources":["../main.js"],"sourcesContent":["/**\n * RequestManager - A library for managing and regulating HTTP requests efficiently.\n * @license MIT\n * This library allows you to manage HTTP requests from any library (ajax, Ext.Ajax, axios, fetch, etc.)\n * by accepting Promises as parameters. When a request is repeated with the same identifier,\n * the previous request is automatically cancelled and the new one is executed, giving priority to the most recent requests.\n\n * @param {Object} managerOptions - The options for the manager\n * @param {boolean} managerOptions.verbose - If true, cancellation errors will include messages\n * @returns {RequestManager} A new RequestManager instance\n*/\nclass RequestManager {\n constructor(managerOptions = {}) {\n /**\n * Map to store active requests by their unique identifier.\n * Each entry contains:\n * - promise: The original promise\n * - abortController: AbortController instance (if available)\n * - cancelToken: Cancel token (for axios compatibility)\n * - wrapperPromise: The promise that wraps the request\n * - resolveWrapper: The function to resolve the wrapper promise\n * - rejectWrapper: The function to reject the wrapper promise\n * - isCancelled: Whether the request has been cancelled\n * - verbose: Whether to include verbose messages in the cancellation error\n */\n this.activeRequests = new Map();\n /**\n * Verbose mode: if true, cancellation errors will include messages\n * @type {boolean}\n */\n this.verbose = managerOptions.verbose || false;\n /**\n * Manager options: the options that were passed to the constructor\n * @type {Object}\n */\n this.managerOptions = managerOptions;\n /**\n * Options for the current request: will be flushed after the request is completed\n * @type {Object}\n */\n this.options = {};\n /**\n * AbortController instance for the current request: will be flushed after the request is completed\n * @type {AbortController}\n */\n this.abortController = null;\n }\n\n /**\n * Flushes the options for the current request\n * @private\n */\n #_flushRequestOptions() {\n this.options = {};\n }\n\n /**\n * Gets the manager options\n * @returns {Object} Manager options\n */\n getOptions() {\n return this.managerOptions;\n }\n\n /**\n * Sets the manager options\n * @param {Object} options - The options to set\n */\n setOptions(options) {\n this.managerOptions = options;\n if (options.verbose !== undefined) {\n this.verbose = options.verbose;\n }\n }\n\n /**\n * Sets the options for the current request\n * @param {Object} options - The options to set\n * @private\n */\n #_setRequestOptions(options) {\n this.options = options;\n }\n\n /**\n * Creates an AbortController and returns its signal.\n * The AbortController is stored internally and will be used by the next request() call.\n * This allows users to get the signal before creating the request.\n * \n * @returns {AbortSignal} The signal from a new AbortController\n * \n * @example\n * const signal = requestManager.getSignal();\n * requestManager.request('/api/users', fetch('/api/users', { signal }));\n */\n getSignal() {\n return this.getAbortController().signal;\n }\n\n /**\n * Gets the current AbortController instance\n * Creates a new AbortController if none exists or if the current one is aborted\n * @returns {AbortController} The current AbortController instance\n */\n getAbortController() {\n // Create a new AbortController if none exists or if the current one is aborted\n if (!this.abortController || this.abortController.signal.aborted) {\n this.abortController = new AbortController();\n }\n return this.abortController;\n }\n\n /**\n * Clears the current AbortController\n * @private\n */\n #_clearAbortController() {\n this.abortController = null;\n }\n\n /**\n * Generates a request identifier based on the requestKey or URL\n * @param {string} url - The URL of the request\n * @param {string|number|Function} requestKey - Optional key to generate a deterministic ID.\n * If provided, requests with the same key will share the same ID.\n * If null or undefined, the cleaned URL will be used as the key.\n * @param {boolean} noCancel - If true, generates a unique ID to prevent cancellation\n * @returns {string} A unique request identifier\n * @private\n */\n #_generateRequestId(url, requestKey = null, noCancel = false) {\n if (noCancel) { // Generate a unique ID to prevent cancellation\n return `request_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n }\n if (requestKey !== null && requestKey !== undefined) {\n if (typeof requestKey === 'function') {\n try {\n requestKey = requestKey();\n } catch (error) {\n requestKey = null;\n }\n }\n if (requestKey !== null && requestKey !== undefined) return `request_${String(requestKey)}`;\n }\n // Use cleaned URL as key when requestKey is null/undefined\n let cleanedUrl = url || '';\n let hasProtocol = cleanedUrl.includes('://');\n if (hasProtocol) cleanedUrl = cleanedUrl.split('://')[1];\n let hasParams = cleanedUrl.includes('?');\n if (hasParams) cleanedUrl = cleanedUrl.split('?')[0];\n let hasHash = cleanedUrl.includes('#');\n if (hasHash) cleanedUrl = cleanedUrl.split('#')[0];\n return `request_${cleanedUrl}`;\n }\n\n /**\n * Prepares fetch options by merging options and removing custom properties\n * @param {Object} options - Configuration options\n * @param {AbortSignal} signal - Abort signal to add to fetch options\n * @param {Object} additionalOptions - Additional options to merge\n * @returns {Object} Prepared fetch options\n * @private\n */\n #_prepareFetchOptions(options, signal, additionalOptions = {}) {\n const fetchOptions = Object.assign({}, additionalOptions);\n const customOptions = ['abortController', 'cancelToken', 'requestKey', 'noCancel'];\n Object.keys(options).forEach(key => {\n if (customOptions.includes(key)) return;\n fetchOptions[key] = options[key];\n });\n fetchOptions.signal = signal;\n return fetchOptions;\n }\n\n /**\n * Internal method that handles the core request logic.\n * \n * @param {string} requestId - Unique identifier for the request\n * @param {Promise|Function|string} requestPromise - The request promise, function, or URL string\n * @param {Object} options - Configuration options\n * @param {AbortController} options.abortController - AbortController instance\n * @param {Function} options.cancelToken - Cancel token or cancel function\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * @private\n */\n #_request(requestId, requestPromise, options = {}) {\n this.#_setRequestOptions(options);\n if (!options.abortController) this.#_clearAbortController(); // Clear any existing abortController to ensure each request gets a fresh one\n this.#_flushRequestOptions();\n const abortController = options.abortController || this.getAbortController();\n\n // Handle different types of requestPromise inputs\n // Priority: Function (Custom logic) > String (URL) > Promise (axios, fetch, etc.)\n if (typeof requestPromise === 'function') {\n // Function: custom logic for any library (axios, ajax, etc.)\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = requestPromise({ options: fetchOptions });\n } else if (typeof requestPromise === 'string') {\n // String (URL): make fetch internally\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = fetch(requestPromise, fetchOptions);\n }\n\n // Cancel previous request with the same ID if it exists\n if (!options.noCancel) this.cancel(requestId);\n\n // Create a wrapper promise that will be resolved/rejected based on the request\n let resolveWrapper, rejectWrapper;\n const wrapperPromise = new Promise((resolve, reject) => {\n resolveWrapper = resolve;\n rejectWrapper = reject;\n });\n\n // Store the request information\n const requestInfo = {\n promise: requestPromise,\n abortController: abortController,\n cancelToken: options.cancelToken || null,\n wrapperPromise: wrapperPromise,\n resolveWrapper: resolveWrapper,\n rejectWrapper: rejectWrapper,\n isCancelled: false,\n verbose: this.verbose\n };\n\n this.activeRequests.set(requestId, requestInfo);\n\n // Handle request promise completion\n if (requestPromise && typeof requestPromise.then === 'function') {\n try {\n let req = requestPromise.then((result) => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(result);\n }\n });\n if (req.catch) req.catch((error) => {\n onError(this, error);\n });\n } catch (error) {\n onError(this, error);\n }\n function onError(scope, error) {\n // Check if this requestInfo is still the active one, or if it was cancelled\n const currentRequestInfo = scope.activeRequests.get(requestId);\n if (currentRequestInfo !== requestInfo) return;\n // Only delete if this is still the active request\n scope.activeRequests.delete(requestId);\n if (!requestInfo.isCancelled) rejectWrapper(error);\n else if (requestInfo.isCancelled && requestInfo.verbose) rejectWrapper(new Error('Request was cancelled'));\n }\n } else {\n // If requestPromise is not a promise, we can't track its completion automatically\n // This can happen with libraries like ExtJS that return request objects instead of promises\n // In this case, the user should handle the request object themselves\n // We'll resolve the wrapper promise immediately to prevent it from hanging\n // The user can still use the request object returned by the library\n setTimeout(() => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(requestPromise); // Resolve with the request object so the user can use it\n }\n }, 0);\n }\n return wrapperPromise;\n }\n\n /**\n * Executes an HTTP request, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Promise|Function} requestPromise - The request promise or function that returns a promise\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Request with Promise\n * requestManager.request('/api/users', axios.get('/api/users', { cancelToken: axios.CancelToken.source().token }));\n * \n * @example\n * // Request with Function\n * requestManager.request('/api/users', ({ options }) => fetch('/api/users', { signal: options.signal, ...options }));\n * \n * @example\n * // Request with Promise and custom cancellation grouping with requestKey\n * const options = {\n * requestKey: 'get-users',\n * cancelToken: axios.CancelToken.source().cancel\n * }\n * requestManager.request('/api/users', axios.get('/api/users', options), options);\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.request('/api/lazy?load=1', fetch('/api/lazy?load=1'), { noCancel: true });\n * requestManager.request('/api/lazy?load=2', fetch('/api/lazy?load=2'), { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n request(url, requestPromise, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, requestPromise, requestOptions);\n }\n\n /**\n * Executes an HTTP request using fetch, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to fetch\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.fetch('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.fetch('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.fetch('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.fetch('/api/lazy?load=1', { noCancel: true });\n * requestManager.fetch('/api/lazy?load=2', { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n fetch(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, url, requestOptions);\n }\n\n /**\n * Executes an HTTP request using axios, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as axios options (method, headers, params, data, etc.)\n * @param {Object} axiosInstance - Optional axios instance to use. If not provided, uses global axios.\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request (uses global axios)\n * requestManager.axios('/api/users');\n * \n * @example\n * // With custom axios instance\n * const myAxios = axios.create({ baseURL: 'https://api.example.com' });\n * requestManager.axios('/users', {}, myAxios);\n * \n * @example\n * // POST request with options\n * requestManager.axios('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.axios('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.axios('/api/lazy?load=1', { noCancel: true });\n * requestManager.axios('/api/lazy?load=2', { noCancel: true });\n */\n axios(url, options = {}, axiosInstance = null) {\n const requestOptions = options || {};\n const axiosLib = axiosInstance || axios;\n const cancelToken = axiosLib.CancelToken.source();\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, axiosLib.get(url, { cancelToken: cancelToken.token, ...requestOptions }), {\n cancelToken: cancelToken,\n ...requestOptions\n });\n }\n\n /**\n * Executes an HTTP request using jQuery.ajax, cancelling any previous request with the same identifier.\n * \n * @param {Function} ajaxMethod - A function that receives { url, ...options } and returns a Promise\n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed to the ajax method function\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.ajax(ajaxMethod, '/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * requestKey: 'get-users'\n * });\n */\n ajax(ajaxMethod, url, options = {}) {\n if (typeof ajaxMethod !== 'function') throw new Error('ajaxMethod must be a function');\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n try {\n const req = ajaxMethod({ url, ...requestOptions });\n this.addAbortListener(req.abort, this.getSignal());\n return this.#_request(requestId, req, requestOptions);\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n /**\n * Executes an HTTP request using XMLHttpRequest, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string} options.method - HTTP method (GET, POST, PUT, DELETE, etc.). Defaults to 'GET'.\n * @param {Object} options.headers - Headers object to set on the request\n * @param {string|FormData|Blob|ArrayBuffer} options.body - Request body\n * @param {string} options.responseType - Response type ('text', 'json', 'blob', 'arraybuffer', 'document'). Defaults to 'text'.\n * @param {boolean} options.withCredentials - Whether to send credentials with the request\n * @param {number} options.timeout - Request timeout in milliseconds\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.xhr('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.xhr('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping\n * requestManager.xhr('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.xhr('/api/lazy?load=1', { noCancel: true });\n * requestManager.xhr('/api/lazy?load=2', { noCancel: true });\n */\n xhr(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n const xhrFunction = ({ options: fetchOptions }) => {\n // Create XMLHttpRequest\n const xhr = new XMLHttpRequest();\n const method = (requestOptions.method || 'GET').toUpperCase();\n // Create a promise that wraps the XHR request\n const xhrPromise = new Promise((resolve, reject) => {\n xhr.onload = function() {\n if (xhr.status >= 200 && xhr.status < 300) {\n let response = xhr.response;\n if (requestOptions.responseType === 'json' ||\n (xhr.getResponseHeader('Content-Type') && xhr.getResponseHeader('Content-Type').includes('application/json'))) {\n try {\n response = JSON.parse(xhr.responseText);\n } catch (e) {\n response = xhr.responseText;\n }\n }\n resolve({\n data: response,\n status: xhr.status,\n statusText: xhr.statusText,\n headers: xhr.getAllResponseHeaders(),\n xhr: xhr\n });\n } else {\n reject({\n message: `Request failed with status ${xhr.status}`,\n status: xhr.status,\n statusText: xhr.statusText,\n xhr: xhr\n });\n }\n };\n xhr.onerror = function() {\n reject({\n message: 'Network error',\n xhr: xhr\n });\n };\n xhr.ontimeout = function() {\n reject({\n message: 'Request timeout',\n xhr: xhr\n });\n };\n\n // Open the request\n xhr.open(method, url, true);\n\n // Set response type\n if (requestOptions.responseType) xhr.responseType = requestOptions.responseType;\n // Set withCredentials\n if (requestOptions.withCredentials !== undefined) xhr.withCredentials = requestOptions.withCredentials;\n // Set timeout\n if (requestOptions.timeout !== undefined) xhr.timeout = requestOptions.timeout;\n // Set headers\n if (requestOptions.headers) Object.keys(requestOptions.headers).forEach(key => {\n xhr.setRequestHeader(key, requestOptions.headers[key]);\n });\n\n // Connect abort signal to xhr.abort()\n if (fetchOptions.signal) fetchOptions.signal.addEventListener('abort', () => xhr.abort());\n\n // Send the request\n xhr.send(requestOptions.body || null);\n });\n return xhrPromise;\n };\n return this.#_request(requestId, xhrFunction, requestOptions);\n }\n\n /**\n * Cancels a specific request by its identifier.\n * \n * @param {string} requestId - The unique identifier of the request to cancel\n * @returns {boolean} True if the request was found and cancelled, false otherwise\n */\n cancel(requestId) {\n const requestInfo = this.activeRequests.get(requestId);\n if (!requestInfo) return false;\n\n requestInfo.isCancelled = true; // Mark as cancelled\n\n // Try to abort using AbortController (for fetch)\n if (requestInfo.abortController && !requestInfo.abortController.signal.aborted) {\n try {\n requestInfo.abortController.abort('Request was cancelled');\n } catch (error) {}\n }\n\n // Try to cancel using cancel token/function (for axios and others)\n if (requestInfo.cancelToken) {\n try {\n if (typeof requestInfo.cancelToken === 'function') requestInfo.cancelToken();\n else if (requestInfo.cancelToken.cancel) requestInfo.cancelToken.cancel();\n } catch (error) {}\n }\n\n // Reject the wrapper promise\n if (requestInfo.rejectWrapper && this.verbose) {\n requestInfo.rejectWrapper(new Error('Request was cancelled'));\n }\n this.activeRequests.delete(requestId); // Remove from active requests\n return true;\n }\n\n /**\n * Link abort signal with HTTP client abort method.\n * Useful for custom HTTP clients that only support the abort method to cancel requests.\n * @param {Function} abortMethod - The abort method to call when the signal is aborted\n * @param {AbortSignal} signal - The signal to listen to\n */\n addAbortListener(abortMethod, signal) {\n if (!signal) return;\n signal.addEventListener(\"abort\", () => {\n if (typeof abortMethod === 'function') {\n try {\n abortMethod();\n } catch (error) {}\n }\n });\n }\n\n /**\n * Cancels all active requests.\n * \n * @returns {number} The number of requests that were cancelled\n */\n cancelAll() {\n const requestIds = Array.from(this.activeRequests.keys());\n let cancelledCount = 0;\n requestIds.forEach((requestId) => {\n if (this.cancel(requestId)) cancelledCount++;\n });\n return cancelledCount;\n }\n\n /**\n * Checks if a request with the given identifier is currently active.\n * \n * @param {string} requestId - The unique identifier to check\n * @returns {boolean} True if the request is active, false otherwise\n */\n isActive(requestId) {\n return this.activeRequests.has(requestId);\n }\n\n /**\n * Gets the number of active requests.\n * \n * @returns {number} The number of currently active requests\n */\n getActiveCount() {\n return this.activeRequests.size;\n }\n\n /**\n * Clears all active requests without cancelling them.\n * Use with caution - this will not cancel the underlying HTTP requests.\n */\n clear() {\n this.activeRequests.clear();\n }\n}\n\nexport default RequestManager;\n\nexport { RequestManager };\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"request-manager.cjs.js","sources":["../main.js"],"sourcesContent":["/**\n * RequestManager - A library for managing and regulating HTTP requests efficiently.\n * @license MIT\n * This library allows you to manage HTTP requests from any library (ajax, Ext.Ajax, axios, fetch, etc.)\n * by accepting Promises as parameters. When a request is repeated with the same identifier,\n * the previous request is automatically cancelled and the new one is executed, giving priority to the most recent requests.\n\n * @param {Object} managerOptions - The options for the manager\n * @param {boolean} managerOptions.verbose - If true, cancellation errors will include messages\n * @returns {RequestManager} A new RequestManager instance\n*/\nclass RequestManager {\n constructor(managerOptions = {}) {\n /**\n * Map to store active requests by their unique identifier.\n * Each entry contains:\n * - promise: The original promise\n * - abortController: AbortController instance (if available)\n * - cancelToken: Cancel token (for axios compatibility)\n * - wrapperPromise: The promise that wraps the request\n * - resolveWrapper: The function to resolve the wrapper promise\n * - rejectWrapper: The function to reject the wrapper promise\n * - isCancelled: Whether the request has been cancelled\n * - verbose: Whether to include verbose messages in the cancellation error\n */\n this.activeRequests = new Map();\n /**\n * Verbose mode: if true, cancellation errors will include messages\n * @type {boolean}\n */\n this.verbose = managerOptions.verbose || false;\n /**\n * Manager options: the options that were passed to the constructor\n * @type {Object}\n */\n this.managerOptions = managerOptions;\n /**\n * Options for the current request: will be flushed after the request is completed\n * @type {Object}\n */\n this.options = {};\n /**\n * AbortController instance for the current request: will be flushed after the request is completed\n * @type {AbortController}\n */\n this.abortController = null;\n }\n\n /**\n * Flushes the options for the current request\n * @private\n */\n #_flushRequestOptions() {\n this.options = {};\n }\n\n /**\n * Gets the manager options\n * @returns {Object} Manager options\n */\n getOptions() {\n return this.managerOptions;\n }\n\n /**\n * Sets the manager options\n * @param {Object} options - The options to set\n */\n setOptions(options) {\n this.managerOptions = options;\n if (options.verbose !== undefined) {\n this.verbose = options.verbose;\n }\n }\n\n /**\n * Sets the options for the current request\n * @param {Object} options - The options to set\n * @private\n */\n #_setRequestOptions(options) {\n this.options = options;\n }\n\n /**\n * Creates an AbortController and returns its signal.\n * The AbortController is stored internally and will be used by the next request() call.\n * This allows users to get the signal before creating the request.\n * \n * @returns {AbortSignal} The signal from a new AbortController\n * \n * @example\n * const signal = requestManager.getSignal();\n * requestManager.request('/api/users', fetch('/api/users', { signal }));\n */\n getSignal() {\n return this.getAbortController().signal;\n }\n\n /**\n * Gets the current AbortController instance\n * Creates a new AbortController if none exists or if the current one is aborted\n * @returns {AbortController} The current AbortController instance\n */\n getAbortController() {\n // Create a new AbortController if none exists or if the current one is aborted\n if (!this.abortController || this.abortController.signal.aborted) {\n this.abortController = new AbortController();\n }\n return this.abortController;\n }\n\n /**\n * Clears the current AbortController\n * @private\n */\n #_clearAbortController() {\n this.abortController = null;\n }\n\n /**\n * Generates a request identifier based on the requestKey or URL\n * @param {string} url - The URL of the request\n * @param {string|number|Function} requestKey - Optional key to generate a deterministic ID.\n * If provided, requests with the same key will share the same ID.\n * If null or undefined, the cleaned URL will be used as the key.\n * @param {boolean} noCancel - If true, generates a unique ID to prevent cancellation\n * @returns {string} A unique request identifier\n * @private\n */\n #_generateRequestId(url, requestKey = null, noCancel = false) {\n if (noCancel) { // Generate a unique ID to prevent cancellation\n return `request_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n }\n if (requestKey !== null && requestKey !== undefined) {\n if (typeof requestKey === 'function') {\n try {\n requestKey = requestKey();\n } catch (error) {\n requestKey = null;\n }\n }\n if (requestKey !== null && requestKey !== undefined) return `request_${String(requestKey)}`;\n }\n // Use cleaned URL as key when requestKey is null/undefined\n let cleanedUrl = url || '';\n let hasProtocol = cleanedUrl.includes('://');\n if (hasProtocol) cleanedUrl = cleanedUrl.split('://')[1];\n let hasParams = cleanedUrl.includes('?');\n if (hasParams) cleanedUrl = cleanedUrl.split('?')[0];\n let hasHash = cleanedUrl.includes('#');\n if (hasHash) cleanedUrl = cleanedUrl.split('#')[0];\n return `request_${cleanedUrl}`;\n }\n\n /**\n * Prepares fetch options by merging options and removing custom properties\n * @param {Object} options - Configuration options\n * @param {AbortSignal} signal - Abort signal to add to fetch options\n * @param {Object} additionalOptions - Additional options to merge\n * @returns {Object} Prepared fetch options\n * @private\n */\n #_prepareFetchOptions(options, signal, additionalOptions = {}) {\n const fetchOptions = Object.assign({}, additionalOptions);\n const customOptions = ['abortController', 'cancelToken', 'requestKey', 'noCancel'];\n Object.keys(options).forEach(key => {\n if (customOptions.includes(key)) return;\n fetchOptions[key] = options[key];\n });\n fetchOptions.signal = signal;\n return fetchOptions;\n }\n\n /**\n * Internal method that handles the core request logic.\n * \n * @param {string} requestId - Unique identifier for the request\n * @param {Promise|Function|string} requestPromise - The request promise, function, or URL string\n * @param {Object} options - Configuration options\n * @param {AbortController} options.abortController - AbortController instance\n * @param {Function} options.cancelToken - Cancel token or cancel function\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * @private\n */\n #_request(requestId, requestPromise, options = {}) {\n this.#_setRequestOptions(options);\n if (!options.abortController) this.#_clearAbortController(); // Clear any existing abortController to ensure each request gets a fresh one\n this.#_flushRequestOptions();\n const abortController = options.abortController || this.getAbortController();\n\n // Handle different types of requestPromise inputs\n // Priority: Function (Custom logic) > String (URL) > Promise (axios, fetch, etc.)\n if (typeof requestPromise === 'function') {\n // Function: custom logic for any library (axios, ajax, etc.)\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = requestPromise({ options: fetchOptions });\n } else if (typeof requestPromise === 'string') {\n // String (URL): make fetch internally\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = fetch(requestPromise, fetchOptions);\n }\n\n // Cancel previous request with the same ID if it exists\n if (!options.noCancel) this.cancel(requestId);\n\n // Create a wrapper promise that will be resolved/rejected based on the request\n let resolveWrapper, rejectWrapper;\n const wrapperPromise = new Promise((resolve, reject) => {\n resolveWrapper = resolve;\n rejectWrapper = reject;\n });\n\n // Store the request information\n const requestInfo = {\n promise: requestPromise,\n abortController: abortController,\n cancelToken: options.cancelToken || null,\n wrapperPromise: wrapperPromise,\n resolveWrapper: resolveWrapper,\n rejectWrapper: rejectWrapper,\n isCancelled: false,\n verbose: this.verbose\n };\n\n this.activeRequests.set(requestId, requestInfo);\n\n // Handle request promise completion\n if (requestPromise && typeof requestPromise.then === 'function') {\n try {\n let req = requestPromise.then((result) => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(result);\n }\n });\n if (req.catch) req.catch((error) => {\n onError(this, error);\n });\n } catch (error) {\n onError(this, error);\n }\n function onError(scope, error) {\n // Check if this requestInfo is still the active one, or if it was cancelled\n const currentRequestInfo = scope.activeRequests.get(requestId);\n if (currentRequestInfo !== requestInfo) return;\n // Only delete if this is still the active request\n scope.activeRequests.delete(requestId);\n if (!requestInfo.isCancelled) rejectWrapper(error);\n else if (requestInfo.isCancelled && requestInfo.verbose) rejectWrapper(new Error('Request was cancelled'));\n }\n } else {\n // If requestPromise is not a promise, we can't track its completion automatically\n // This can happen with libraries like ExtJS that return request objects instead of promises\n // In this case, the user should handle the request object themselves\n // We'll resolve the wrapper promise immediately to prevent it from hanging\n // The user can still use the request object returned by the library\n setTimeout(() => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(requestPromise); // Resolve with the request object so the user can use it\n }\n }, 0);\n }\n return wrapperPromise;\n }\n\n /**\n * Executes an HTTP request, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Promise|Function} requestPromise - The request promise or function that returns a promise\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Request with Promise\n * requestManager.request('/api/users', axios.get('/api/users', { cancelToken: axios.CancelToken.source().token }));\n * \n * @example\n * // Request with Function\n * requestManager.request('/api/users', ({ options }) => fetch('/api/users', { signal: options.signal, ...options }));\n * \n * @example\n * // Request with Promise and custom cancellation grouping with requestKey\n * const options = {\n * requestKey: 'get-users',\n * cancelToken: axios.CancelToken.source().cancel\n * }\n * requestManager.request('/api/users', axios.get('/api/users', options), options);\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.request('/api/lazy?load=1', fetch('/api/lazy?load=1'), { noCancel: true });\n * requestManager.request('/api/lazy?load=2', fetch('/api/lazy?load=2'), { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n request(url, requestPromise, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, requestPromise, requestOptions);\n }\n\n /**\n * Executes an HTTP request using fetch, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to fetch\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.fetch('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.fetch('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.fetch('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.fetch('/api/lazy?load=1', { noCancel: true });\n * requestManager.fetch('/api/lazy?load=2', { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n fetch(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, url, requestOptions);\n }\n\n /**\n * Executes an HTTP request using axios, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as axios options (method, headers, params, data, etc.)\n * @param {Object} axiosInstance - Optional axios instance to use. If not provided, uses global axios.\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request (uses global axios)\n * requestManager.axios('/api/users');\n * \n * @example\n * // With custom axios instance\n * const myAxios = axios.create({ baseURL: 'https://api.example.com' });\n * requestManager.axios('/users', {}, myAxios);\n * \n * @example\n * // POST request with options\n * requestManager.axios('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.axios('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.axios('/api/lazy?load=1', { noCancel: true });\n * requestManager.axios('/api/lazy?load=2', { noCancel: true });\n */\n axios(url, options = {}, axiosInstance = null) {\n const requestOptions = options || {};\n const axiosLib = axiosInstance || axios;\n const cancelToken = axiosLib.CancelToken.source();\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, axiosLib.get(url, { cancelToken: cancelToken.token, ...requestOptions }), {\n cancelToken: cancelToken,\n ...requestOptions\n });\n }\n\n /**\n * Executes an HTTP request using jQuery.ajax, cancelling any previous request with the same identifier.\n * \n * @param {Function} ajaxMethod - A function that receives { url, ...options } and returns a Promise\n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed to the ajax method function\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.ajax(ajaxMethod, '/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * requestKey: 'get-users'\n * });\n */\n ajax(ajaxMethod, url, options = {}) {\n if (typeof ajaxMethod !== 'function') throw new Error('ajaxMethod must be a function');\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n try {\n const req = ajaxMethod({ url, ...requestOptions });\n this.addAbortListener(req.abort, this.getSignal());\n return this.#_request(requestId, req, requestOptions);\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n /**\n * Executes an HTTP request using XMLHttpRequest, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string} options.method - HTTP method (GET, POST, PUT, DELETE, etc.). Defaults to 'GET'.\n * @param {Object} options.headers - Headers object to set on the request\n * @param {string|FormData|Blob|ArrayBuffer} options.body - Request body\n * @param {string} options.responseType - Response type ('text', 'json', 'blob', 'arraybuffer', 'document'). Defaults to 'text'.\n * @param {boolean} options.withCredentials - Whether to send credentials with the request\n * @param {number} options.timeout - Request timeout in milliseconds\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.xhr('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.xhr('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping\n * requestManager.xhr('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.xhr('/api/lazy?load=1', { noCancel: true });\n * requestManager.xhr('/api/lazy?load=2', { noCancel: true });\n */\n xhr(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n const xhrFunction = ({ options: fetchOptions }) => {\n // Create XMLHttpRequest\n const xhr = new XMLHttpRequest();\n const method = (requestOptions.method || 'GET').toUpperCase();\n // Create a promise that wraps the XHR request\n const xhrPromise = new Promise((resolve, reject) => {\n xhr.onload = function() {\n if (xhr.status >= 200 && xhr.status < 300) {\n let response = xhr.response;\n if (requestOptions.responseType === 'json' ||\n (xhr.getResponseHeader('Content-Type') && xhr.getResponseHeader('Content-Type').includes('application/json'))) {\n try {\n response = JSON.parse(xhr.responseText);\n } catch (e) {\n response = xhr.responseText;\n }\n }\n resolve({\n data: response,\n status: xhr.status,\n statusText: xhr.statusText,\n headers: xhr.getAllResponseHeaders(),\n xhr: xhr\n });\n } else {\n reject({\n message: `Request failed with status ${xhr.status}`,\n status: xhr.status,\n statusText: xhr.statusText,\n xhr: xhr\n });\n }\n };\n xhr.onerror = function() {\n reject({\n message: 'Network error',\n xhr: xhr\n });\n };\n xhr.ontimeout = function() {\n reject({\n message: 'Request timeout',\n xhr: xhr\n });\n };\n\n // Open the request\n xhr.open(method, url, true);\n\n // Set response type\n if (requestOptions.responseType) xhr.responseType = requestOptions.responseType;\n // Set withCredentials\n if (requestOptions.withCredentials !== undefined) xhr.withCredentials = requestOptions.withCredentials;\n // Set timeout\n if (requestOptions.timeout !== undefined) xhr.timeout = requestOptions.timeout;\n // Set headers\n if (requestOptions.headers) Object.keys(requestOptions.headers).forEach(key => {\n xhr.setRequestHeader(key, requestOptions.headers[key]);\n });\n\n // Connect abort signal to xhr.abort()\n if (fetchOptions.signal) fetchOptions.signal.addEventListener('abort', () => xhr.abort());\n\n // Send the request\n xhr.send(requestOptions.body || null);\n });\n return xhrPromise;\n };\n return this.#_request(requestId, xhrFunction, requestOptions);\n }\n\n /**\n * Cancels a specific request by its identifier.\n * \n * @param {string} requestId - The unique identifier of the request to cancel\n * @returns {boolean} True if the request was found and cancelled, false otherwise\n */\n cancel(requestId) {\n const requestInfo = this.activeRequests.get(requestId);\n if (!requestInfo) return false;\n\n requestInfo.isCancelled = true; // Mark as cancelled\n\n // Try to abort using AbortController (for fetch)\n if (requestInfo.abortController && !requestInfo.abortController.signal.aborted) {\n try {\n requestInfo.abortController.abort('Request was cancelled');\n } catch (error) {}\n }\n\n // Try to cancel using cancel token/function (for axios and others)\n if (requestInfo.cancelToken) {\n try {\n if (typeof requestInfo.cancelToken === 'function') requestInfo.cancelToken();\n else if (requestInfo.cancelToken.cancel) requestInfo.cancelToken.cancel();\n } catch (error) {}\n }\n\n // Reject the wrapper promise\n if (requestInfo.rejectWrapper && this.verbose) {\n requestInfo.rejectWrapper(new Error('Request was cancelled'));\n }\n this.activeRequests.delete(requestId); // Remove from active requests\n return true;\n }\n\n /**\n * Link abort signal with HTTP client abort method.\n * Useful for custom HTTP clients that only support the abort method to cancel requests.\n * @param {Function} abortMethod - The abort method to call when the signal is aborted\n * @param {AbortSignal} signal - The signal to listen to\n */\n addAbortListener(abortMethod, signal) {\n if (!signal) return;\n signal.addEventListener(\"abort\", () => {\n if (typeof abortMethod === 'function') {\n try {\n abortMethod();\n } catch (error) {}\n }\n });\n }\n\n /**\n * Cancels all active requests.\n * \n * @returns {number} The number of requests that were cancelled\n */\n cancelAll() {\n const requestIds = Array.from(this.activeRequests.keys());\n let cancelledCount = 0;\n requestIds.forEach((requestId) => {\n if (this.cancel(requestId)) cancelledCount++;\n });\n return cancelledCount;\n }\n\n /**\n * Checks if a request with the given identifier is currently active.\n * \n * @param {string} requestId - The unique identifier to check\n * @returns {boolean} True if the request is active, false otherwise\n */\n isActive(requestId) {\n return this.activeRequests.has(requestId);\n }\n\n /**\n * Gets the number of active requests.\n * \n * @returns {number} The number of currently active requests\n */\n getActiveCount() {\n return this.activeRequests.size;\n }\n\n /**\n * Clears all active requests without cancelling them.\n * Use with caution - this will not cancel the underlying HTTP requests.\n */\n clear() {\n this.activeRequests.clear();\n }\n}\n\nexport default RequestManager;\n\nexport { RequestManager };\n"],"names":[],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM,cAAc,CAAC;AACrB,IAAI,WAAW,CAAC,cAAc,GAAG,EAAE,EAAE;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAE;AACvC;AACA;AACA;AACA;AACA,QAAQ,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC,OAAO,IAAI,KAAK;AACtD;AACA;AACA;AACA;AACA,QAAQ,IAAI,CAAC,cAAc,GAAG,cAAc;AAC5C;AACA;AACA;AACA;AACA,QAAQ,IAAI,CAAC,OAAO,GAAG,EAAE;AACzB;AACA;AACA;AACA;AACA,QAAQ,IAAI,CAAC,eAAe,GAAG,IAAI;AACnC,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI,qBAAqB,GAAG;AAC5B,QAAQ,IAAI,CAAC,OAAO,GAAG,EAAE;AACzB,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI,UAAU,GAAG;AACjB,QAAQ,OAAO,IAAI,CAAC,cAAc;AAClC,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI,UAAU,CAAC,OAAO,EAAE;AACxB,QAAQ,IAAI,CAAC,cAAc,GAAG,OAAO;AACrC,QAAQ,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;AAC3C,YAAY,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO;AAC1C,QAAQ;AACR,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI,mBAAmB,CAAC,OAAO,EAAE;AACjC,QAAQ,IAAI,CAAC,OAAO,GAAG,OAAO;AAC9B,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,GAAG;AAChB,QAAQ,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC,MAAM;AAC/C,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAkB,GAAG;AACzB;AACA,QAAQ,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE;AAC1E,YAAY,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE;AACxD,QAAQ;AACR,QAAQ,OAAO,IAAI,CAAC,eAAe;AACnC,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI,sBAAsB,GAAG;AAC7B,QAAQ,IAAI,CAAC,eAAe,GAAG,IAAI;AACnC,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE;AAClE,QAAQ,IAAI,QAAQ,EAAE;AACtB,YAAY,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACrF,QAAQ;AACR,QAAQ,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE;AAC7D,YAAY,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE;AAClD,gBAAgB,IAAI;AACpB,oBAAoB,UAAU,GAAG,UAAU,EAAE;AAC7C,gBAAgB,CAAC,CAAC,OAAO,KAAK,EAAE;AAChC,oBAAoB,UAAU,GAAG,IAAI;AACrC,gBAAgB;AAChB,YAAY;AACZ,YAAY,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AACvG,QAAQ;AACR;AACA,QAAQ,IAAI,UAAU,GAAG,GAAG,IAAI,EAAE;AAClC,QAAQ,IAAI,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;AACpD,QAAQ,IAAI,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChE,QAAQ,IAAI,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;AAChD,QAAQ,IAAI,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5D,QAAQ,IAAI,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;AAC9C,QAAQ,IAAI,OAAO,EAAE,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1D,QAAQ,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AACtC,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,GAAG,EAAE,EAAE;AACnE,QAAQ,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,iBAAiB,CAAC;AACjE,QAAQ,MAAM,aAAa,GAAG,CAAC,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC;AAC1F,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI;AAC5C,YAAY,IAAI,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC7C,YAAY,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;AAC5C,QAAQ,CAAC,CAAC;AACV,QAAQ,YAAY,CAAC,MAAM,GAAG,MAAM;AACpC,QAAQ,OAAO,YAAY;AAC3B,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,GAAG,EAAE,EAAE;AACvD,QAAQ,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;AACzC,QAAQ,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,sBAAsB,EAAE,CAAC;AACpE,QAAQ,IAAI,CAAC,qBAAqB,EAAE;AACpC,QAAQ,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,kBAAkB,EAAE;;AAEpF;AACA;AACA,QAAQ,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE;AAClD;AACA,YAAY,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;AAC5F,YAAY,cAAc,GAAG,cAAc,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACtE,QAAQ,CAAC,MAAM,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE;AACvD;AACA,YAAY,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;AAC5F,YAAY,cAAc,GAAG,KAAK,CAAC,cAAc,EAAE,YAAY,CAAC;AAChE,QAAQ;;AAER;AACA,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;;AAErD;AACA,QAAQ,IAAI,cAAc,EAAE,aAAa;AACzC,QAAQ,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAChE,YAAY,cAAc,GAAG,OAAO;AACpC,YAAY,aAAa,GAAG,MAAM;AAClC,QAAQ,CAAC,CAAC;;AAEV;AACA,QAAQ,MAAM,WAAW,GAAG;AAC5B,YAAY,OAAO,EAAE,cAAc;AACnC,YAAY,eAAe,EAAE,eAAe;AAC5C,YAAY,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;AACpD,YAAY,cAAc,EAAE,cAAc;AAC1C,YAAY,cAAc,EAAE,cAAc;AAC1C,YAAY,aAAa,EAAE,aAAa;AACxC,YAAY,WAAW,EAAE,KAAK;AAC9B,YAAY,OAAO,EAAE,IAAI,CAAC;AAC1B,SAAS;;AAET,QAAQ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC;;AAEvD;AACA,QAAQ,IAAI,cAAc,IAAI,OAAO,cAAc,CAAC,IAAI,KAAK,UAAU,EAAE;AACzE,YAAY,IAAI;AAChB,gBAAgB,IAAI,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK;AAC1D,oBAAoB,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,WAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE;AACxG,wBAAwB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC;AAC7D,wBAAwB,cAAc,CAAC,MAAM,CAAC;AAC9C,oBAAoB;AACpB,gBAAgB,CAAC,CAAC;AAClB,gBAAgB,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK;AACpD,oBAAoB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;AACxC,gBAAgB,CAAC,CAAC;AAClB,YAAY,CAAC,CAAC,OAAO,KAAK,EAAE;AAC5B,gBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;AACpC,YAAY;AACZ,YAAY,SAAS,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE;AAC3C;AACA,gBAAgB,MAAM,kBAAkB,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9E,gBAAgB,IAAI,kBAAkB,KAAK,WAAW,EAAE;AACxD;AACA,gBAAgB,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC;AACtD,gBAAgB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,aAAa,CAAC,KAAK,CAAC;AAClE,qBAAqB,IAAI,WAAW,CAAC,WAAW,IAAI,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AAC1H,YAAY;AACZ,QAAQ,CAAC,MAAM;AACf;AACA;AACA;AACA;AACA;AACA,YAAY,UAAU,CAAC,MAAM;AAC7B,gBAAgB,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,WAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE;AACpG,oBAAoB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC;AACzD,oBAAoB,cAAc,CAAC,cAAc,CAAC,CAAC;AACnD,gBAAgB;AAChB,YAAY,CAAC,EAAE,CAAC,CAAC;AACjB,QAAQ;AACR,QAAQ,OAAO,cAAc;AAC7B,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,GAAG,EAAE,EAAE;AAC/C,QAAQ,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE;AAC5C,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC;AAC3G,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,cAAc,CAAC;AACxE,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE;AAC7B,QAAQ,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE;AAC5C,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC;AAC3G,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,cAAc,CAAC;AAC7D,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,aAAa,GAAG,IAAI,EAAE;AACnD,QAAQ,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE;AAC5C,QAAQ,MAAM,QAAQ,GAAG,aAAa,IAAI,KAAK;AAC/C,QAAQ,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE;AACzD,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC;AAC3G,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,GAAG,cAAc,EAAE,CAAC,EAAE;AACnH,YAAY,WAAW,EAAE,WAAW;AACpC,YAAY,GAAG;AACf,SAAS,CAAC;AACV,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE;AACxC,QAAQ,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC;AAC9F,QAAQ,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE;AAC5C,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC;AAC3G,QAAQ,IAAI;AACZ,YAAY,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;AAC9D,YAAY,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;AAC9D,YAAY,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,cAAc,CAAC;AACjE,QAAQ,CAAC,CAAC,OAAO,KAAK,EAAE;AACxB,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;AACxC,QAAQ;AACR,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE;AAC3B,QAAQ,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE;AAC5C,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC;AAC3G,QAAQ,MAAM,WAAW,GAAG,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK;AAC3D;AACA,YAAY,MAAM,GAAG,GAAG,IAAI,cAAc,EAAE;AAC5C,YAAY,MAAM,MAAM,GAAG,CAAC,cAAc,CAAC,MAAM,IAAI,KAAK,EAAE,WAAW,EAAE;AACzE;AACA,YAAY,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAChE,gBAAgB,GAAG,CAAC,MAAM,GAAG,WAAW;AACxC,oBAAoB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;AAC/D,wBAAwB,IAAI,QAAQ,GAAG,GAAG,CAAC,QAAQ;AACnD,wBAAwB,IAAI,cAAc,CAAC,YAAY,KAAK,MAAM;AAClE,6BAA6B,GAAG,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,EAAE;AAC3I,4BAA4B,IAAI;AAChC,gCAAgC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;AACvE,4BAA4B,CAAC,CAAC,OAAO,CAAC,EAAE;AACxC,gCAAgC,QAAQ,GAAG,GAAG,CAAC,YAAY;AAC3D,4BAA4B;AAC5B,wBAAwB;AACxB,wBAAwB,OAAO,CAAC;AAChC,4BAA4B,IAAI,EAAE,QAAQ;AAC1C,4BAA4B,MAAM,EAAE,GAAG,CAAC,MAAM;AAC9C,4BAA4B,UAAU,EAAE,GAAG,CAAC,UAAU;AACtD,4BAA4B,OAAO,EAAE,GAAG,CAAC,qBAAqB,EAAE;AAChE,4BAA4B,GAAG,EAAE;AACjC,yBAAyB,CAAC;AAC1B,oBAAoB,CAAC,MAAM;AAC3B,wBAAwB,MAAM,CAAC;AAC/B,4BAA4B,OAAO,EAAE,CAAC,2BAA2B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AAC/E,4BAA4B,MAAM,EAAE,GAAG,CAAC,MAAM;AAC9C,4BAA4B,UAAU,EAAE,GAAG,CAAC,UAAU;AACtD,4BAA4B,GAAG,EAAE;AACjC,yBAAyB,CAAC;AAC1B,oBAAoB;AACpB,gBAAgB,CAAC;AACjB,gBAAgB,GAAG,CAAC,OAAO,GAAG,WAAW;AACzC,oBAAoB,MAAM,CAAC;AAC3B,wBAAwB,OAAO,EAAE,eAAe;AAChD,wBAAwB,GAAG,EAAE;AAC7B,qBAAqB,CAAC;AACtB,gBAAgB,CAAC;AACjB,gBAAgB,GAAG,CAAC,SAAS,GAAG,WAAW;AAC3C,oBAAoB,MAAM,CAAC;AAC3B,wBAAwB,OAAO,EAAE,iBAAiB;AAClD,wBAAwB,GAAG,EAAE;AAC7B,qBAAqB,CAAC;AACtB,gBAAgB,CAAC;;AAEjB;AACA,gBAAgB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;;AAE3C;AACA,gBAAgB,IAAI,cAAc,CAAC,YAAY,EAAE,GAAG,CAAC,YAAY,GAAG,cAAc,CAAC,YAAY;AAC/F;AACA,gBAAgB,IAAI,cAAc,CAAC,eAAe,KAAK,SAAS,EAAE,GAAG,CAAC,eAAe,GAAG,cAAc,CAAC,eAAe;AACtH;AACA,gBAAgB,IAAI,cAAc,CAAC,OAAO,KAAK,SAAS,EAAE,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC,OAAO;AAC9F;AACA,gBAAgB,IAAI,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI;AAC/F,oBAAoB,GAAG,CAAC,gBAAgB,CAAC,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC1E,gBAAgB,CAAC,CAAC;;AAElB;AACA,gBAAgB,IAAI,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;;AAEzG;AACA,gBAAgB,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,IAAI,CAAC;AACrD,YAAY,CAAC,CAAC;AACd,YAAY,OAAO,UAAU;AAC7B,QAAQ,CAAC;AACT,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC;AACrE,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,CAAC,SAAS,EAAE;AACtB,QAAQ,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9D,QAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,KAAK;;AAEtC,QAAQ,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC;;AAEvC;AACA,QAAQ,IAAI,WAAW,CAAC,eAAe,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE;AACxF,YAAY,IAAI;AAChB,gBAAgB,WAAW,CAAC,eAAe,CAAC,KAAK,CAAC,uBAAuB,CAAC;AAC1E,YAAY,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC;AAC7B,QAAQ;;AAER;AACA,QAAQ,IAAI,WAAW,CAAC,WAAW,EAAE;AACrC,YAAY,IAAI;AAChB,gBAAgB,IAAI,OAAO,WAAW,CAAC,WAAW,KAAK,UAAU,EAAE,WAAW,CAAC,WAAW,EAAE;AAC5F,qBAAqB,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE;AACzF,YAAY,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC;AAC7B,QAAQ;;AAER;AACA,QAAQ,IAAI,WAAW,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE;AACvD,YAAY,WAAW,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AACzE,QAAQ;AACR,QAAQ,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC9C,QAAQ,OAAO,IAAI;AACnB,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE;AAC1C,QAAQ,IAAI,CAAC,MAAM,EAAE;AACrB,QAAQ,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM;AAC/C,YAAY,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE;AACnD,gBAAgB,IAAI;AACpB,oBAAoB,WAAW,EAAE;AACjC,gBAAgB,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC;AACjC,YAAY;AACZ,QAAQ,CAAC,CAAC;AACV,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,GAAG;AAChB,QAAQ,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;AACjE,QAAQ,IAAI,cAAc,GAAG,CAAC;AAC9B,QAAQ,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK;AAC1C,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE;AACxD,QAAQ,CAAC,CAAC;AACV,QAAQ,OAAO,cAAc;AAC7B,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,QAAQ,CAAC,SAAS,EAAE;AACxB,QAAQ,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC;AACjD,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI,cAAc,GAAG;AACrB,QAAQ,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI;AACvC,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI,KAAK,GAAG;AACZ,QAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;AACnC,IAAI;AACJ;;;;;"}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RequestManager - A library for managing and regulating HTTP requests efficiently.
|
|
3
|
-
* @license MIT
|
|
4
|
-
*/
|
|
5
1
|
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});
|
|
6
2
|
/**
|
|
7
3
|
* RequestManager - A library for managing and regulating HTTP requests efficiently.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-manager.cjs.min.js","sources":["../main.js"],"sourcesContent":["/**\n * RequestManager - A library for managing and regulating HTTP requests efficiently.\n * @license MIT\n * This library allows you to manage HTTP requests from any library (ajax, Ext.Ajax, axios, fetch, etc.)\n * by accepting Promises as parameters. When a request is repeated with the same identifier,\n * the previous request is automatically cancelled and the new one is executed, giving priority to the most recent requests.\n\n * @param {Object} managerOptions - The options for the manager\n * @param {boolean} managerOptions.verbose - If true, cancellation errors will include messages\n * @returns {RequestManager} A new RequestManager instance\n*/\nclass RequestManager {\n constructor(managerOptions = {}) {\n /**\n * Map to store active requests by their unique identifier.\n * Each entry contains:\n * - promise: The original promise\n * - abortController: AbortController instance (if available)\n * - cancelToken: Cancel token (for axios compatibility)\n * - wrapperPromise: The promise that wraps the request\n * - resolveWrapper: The function to resolve the wrapper promise\n * - rejectWrapper: The function to reject the wrapper promise\n * - isCancelled: Whether the request has been cancelled\n * - verbose: Whether to include verbose messages in the cancellation error\n */\n this.activeRequests = new Map();\n /**\n * Verbose mode: if true, cancellation errors will include messages\n * @type {boolean}\n */\n this.verbose = managerOptions.verbose || false;\n /**\n * Manager options: the options that were passed to the constructor\n * @type {Object}\n */\n this.managerOptions = managerOptions;\n /**\n * Options for the current request: will be flushed after the request is completed\n * @type {Object}\n */\n this.options = {};\n /**\n * AbortController instance for the current request: will be flushed after the request is completed\n * @type {AbortController}\n */\n this.abortController = null;\n }\n\n /**\n * Flushes the options for the current request\n * @private\n */\n #_flushRequestOptions() {\n this.options = {};\n }\n\n /**\n * Gets the manager options\n * @returns {Object} Manager options\n */\n getOptions() {\n return this.managerOptions;\n }\n\n /**\n * Sets the manager options\n * @param {Object} options - The options to set\n */\n setOptions(options) {\n this.managerOptions = options;\n if (options.verbose !== undefined) {\n this.verbose = options.verbose;\n }\n }\n\n /**\n * Sets the options for the current request\n * @param {Object} options - The options to set\n * @private\n */\n #_setRequestOptions(options) {\n this.options = options;\n }\n\n /**\n * Creates an AbortController and returns its signal.\n * The AbortController is stored internally and will be used by the next request() call.\n * This allows users to get the signal before creating the request.\n * \n * @returns {AbortSignal} The signal from a new AbortController\n * \n * @example\n * const signal = requestManager.getSignal();\n * requestManager.request('/api/users', fetch('/api/users', { signal }));\n */\n getSignal() {\n return this.getAbortController().signal;\n }\n\n /**\n * Gets the current AbortController instance\n * Creates a new AbortController if none exists or if the current one is aborted\n * @returns {AbortController} The current AbortController instance\n */\n getAbortController() {\n // Create a new AbortController if none exists or if the current one is aborted\n if (!this.abortController || this.abortController.signal.aborted) {\n this.abortController = new AbortController();\n }\n return this.abortController;\n }\n\n /**\n * Clears the current AbortController\n * @private\n */\n #_clearAbortController() {\n this.abortController = null;\n }\n\n /**\n * Generates a request identifier based on the requestKey or URL\n * @param {string} url - The URL of the request\n * @param {string|number|Function} requestKey - Optional key to generate a deterministic ID.\n * If provided, requests with the same key will share the same ID.\n * If null or undefined, the cleaned URL will be used as the key.\n * @param {boolean} noCancel - If true, generates a unique ID to prevent cancellation\n * @returns {string} A unique request identifier\n * @private\n */\n #_generateRequestId(url, requestKey = null, noCancel = false) {\n if (noCancel) { // Generate a unique ID to prevent cancellation\n return `request_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n }\n if (requestKey !== null && requestKey !== undefined) {\n if (typeof requestKey === 'function') {\n try {\n requestKey = requestKey();\n } catch (error) {\n requestKey = null;\n }\n }\n if (requestKey !== null && requestKey !== undefined) return `request_${String(requestKey)}`;\n }\n // Use cleaned URL as key when requestKey is null/undefined\n let cleanedUrl = url || '';\n let hasProtocol = cleanedUrl.includes('://');\n if (hasProtocol) cleanedUrl = cleanedUrl.split('://')[1];\n let hasParams = cleanedUrl.includes('?');\n if (hasParams) cleanedUrl = cleanedUrl.split('?')[0];\n let hasHash = cleanedUrl.includes('#');\n if (hasHash) cleanedUrl = cleanedUrl.split('#')[0];\n return `request_${cleanedUrl}`;\n }\n\n /**\n * Prepares fetch options by merging options and removing custom properties\n * @param {Object} options - Configuration options\n * @param {AbortSignal} signal - Abort signal to add to fetch options\n * @param {Object} additionalOptions - Additional options to merge\n * @returns {Object} Prepared fetch options\n * @private\n */\n #_prepareFetchOptions(options, signal, additionalOptions = {}) {\n const fetchOptions = Object.assign({}, additionalOptions);\n const customOptions = ['abortController', 'cancelToken', 'requestKey', 'noCancel'];\n Object.keys(options).forEach(key => {\n if (customOptions.includes(key)) return;\n fetchOptions[key] = options[key];\n });\n fetchOptions.signal = signal;\n return fetchOptions;\n }\n\n /**\n * Internal method that handles the core request logic.\n * \n * @param {string} requestId - Unique identifier for the request\n * @param {Promise|Function|string} requestPromise - The request promise, function, or URL string\n * @param {Object} options - Configuration options\n * @param {AbortController} options.abortController - AbortController instance\n * @param {Function} options.cancelToken - Cancel token or cancel function\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * @private\n */\n #_request(requestId, requestPromise, options = {}) {\n this.#_setRequestOptions(options);\n if (!options.abortController) this.#_clearAbortController(); // Clear any existing abortController to ensure each request gets a fresh one\n this.#_flushRequestOptions();\n const abortController = options.abortController || this.getAbortController();\n\n // Handle different types of requestPromise inputs\n // Priority: Function (Custom logic) > String (URL) > Promise (axios, fetch, etc.)\n if (typeof requestPromise === 'function') {\n // Function: custom logic for any library (axios, ajax, etc.)\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = requestPromise({ options: fetchOptions });\n } else if (typeof requestPromise === 'string') {\n // String (URL): make fetch internally\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = fetch(requestPromise, fetchOptions);\n }\n\n // Cancel previous request with the same ID if it exists\n if (!options.noCancel) this.cancel(requestId);\n\n // Create a wrapper promise that will be resolved/rejected based on the request\n let resolveWrapper, rejectWrapper;\n const wrapperPromise = new Promise((resolve, reject) => {\n resolveWrapper = resolve;\n rejectWrapper = reject;\n });\n\n // Store the request information\n const requestInfo = {\n promise: requestPromise,\n abortController: abortController,\n cancelToken: options.cancelToken || null,\n wrapperPromise: wrapperPromise,\n resolveWrapper: resolveWrapper,\n rejectWrapper: rejectWrapper,\n isCancelled: false,\n verbose: this.verbose\n };\n\n this.activeRequests.set(requestId, requestInfo);\n\n // Handle request promise completion\n if (requestPromise && typeof requestPromise.then === 'function') {\n try {\n let req = requestPromise.then((result) => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(result);\n }\n });\n if (req.catch) req.catch((error) => {\n onError(this, error);\n });\n } catch (error) {\n onError(this, error);\n }\n function onError(scope, error) {\n // Check if this requestInfo is still the active one, or if it was cancelled\n const currentRequestInfo = scope.activeRequests.get(requestId);\n if (currentRequestInfo !== requestInfo) return;\n // Only delete if this is still the active request\n scope.activeRequests.delete(requestId);\n if (!requestInfo.isCancelled) rejectWrapper(error);\n else if (requestInfo.isCancelled && requestInfo.verbose) rejectWrapper(new Error('Request was cancelled'));\n }\n } else {\n // If requestPromise is not a promise, we can't track its completion automatically\n // This can happen with libraries like ExtJS that return request objects instead of promises\n // In this case, the user should handle the request object themselves\n // We'll resolve the wrapper promise immediately to prevent it from hanging\n // The user can still use the request object returned by the library\n setTimeout(() => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(requestPromise); // Resolve with the request object so the user can use it\n }\n }, 0);\n }\n return wrapperPromise;\n }\n\n /**\n * Executes an HTTP request, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Promise|Function} requestPromise - The request promise or function that returns a promise\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Request with Promise\n * requestManager.request('/api/users', axios.get('/api/users', { cancelToken: axios.CancelToken.source().token }));\n * \n * @example\n * // Request with Function\n * requestManager.request('/api/users', ({ options }) => fetch('/api/users', { signal: options.signal, ...options }));\n * \n * @example\n * // Request with Promise and custom cancellation grouping with requestKey\n * const options = {\n * requestKey: 'get-users',\n * cancelToken: axios.CancelToken.source().cancel\n * }\n * requestManager.request('/api/users', axios.get('/api/users', options), options);\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.request('/api/lazy?load=1', fetch('/api/lazy?load=1'), { noCancel: true });\n * requestManager.request('/api/lazy?load=2', fetch('/api/lazy?load=2'), { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n request(url, requestPromise, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, requestPromise, requestOptions);\n }\n\n /**\n * Executes an HTTP request using fetch, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to fetch\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.fetch('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.fetch('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.fetch('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.fetch('/api/lazy?load=1', { noCancel: true });\n * requestManager.fetch('/api/lazy?load=2', { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n fetch(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, url, requestOptions);\n }\n\n /**\n * Executes an HTTP request using axios, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as axios options (method, headers, params, data, etc.)\n * @param {Object} axiosInstance - Optional axios instance to use. If not provided, uses global axios.\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request (uses global axios)\n * requestManager.axios('/api/users');\n * \n * @example\n * // With custom axios instance\n * const myAxios = axios.create({ baseURL: 'https://api.example.com' });\n * requestManager.axios('/users', {}, myAxios);\n * \n * @example\n * // POST request with options\n * requestManager.axios('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.axios('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.axios('/api/lazy?load=1', { noCancel: true });\n * requestManager.axios('/api/lazy?load=2', { noCancel: true });\n */\n axios(url, options = {}, axiosInstance = null) {\n const requestOptions = options || {};\n const axiosLib = axiosInstance || axios;\n const cancelToken = axiosLib.CancelToken.source();\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, axiosLib.get(url, { cancelToken: cancelToken.token, ...requestOptions }), {\n cancelToken: cancelToken,\n ...requestOptions\n });\n }\n\n /**\n * Executes an HTTP request using jQuery.ajax, cancelling any previous request with the same identifier.\n * \n * @param {Function} ajaxMethod - A function that receives { url, ...options } and returns a Promise\n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed to the ajax method function\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.ajax(ajaxMethod, '/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * requestKey: 'get-users'\n * });\n */\n ajax(ajaxMethod, url, options = {}) {\n if (typeof ajaxMethod !== 'function') throw new Error('ajaxMethod must be a function');\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n try {\n const req = ajaxMethod({ url, ...requestOptions });\n this.addAbortListener(req.abort, this.getSignal());\n return this.#_request(requestId, req, requestOptions);\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n /**\n * Executes an HTTP request using XMLHttpRequest, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string} options.method - HTTP method (GET, POST, PUT, DELETE, etc.). Defaults to 'GET'.\n * @param {Object} options.headers - Headers object to set on the request\n * @param {string|FormData|Blob|ArrayBuffer} options.body - Request body\n * @param {string} options.responseType - Response type ('text', 'json', 'blob', 'arraybuffer', 'document'). Defaults to 'text'.\n * @param {boolean} options.withCredentials - Whether to send credentials with the request\n * @param {number} options.timeout - Request timeout in milliseconds\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.xhr('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.xhr('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping\n * requestManager.xhr('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.xhr('/api/lazy?load=1', { noCancel: true });\n * requestManager.xhr('/api/lazy?load=2', { noCancel: true });\n */\n xhr(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n const xhrFunction = ({ options: fetchOptions }) => {\n // Create XMLHttpRequest\n const xhr = new XMLHttpRequest();\n const method = (requestOptions.method || 'GET').toUpperCase();\n // Create a promise that wraps the XHR request\n const xhrPromise = new Promise((resolve, reject) => {\n xhr.onload = function() {\n if (xhr.status >= 200 && xhr.status < 300) {\n let response = xhr.response;\n if (requestOptions.responseType === 'json' ||\n (xhr.getResponseHeader('Content-Type') && xhr.getResponseHeader('Content-Type').includes('application/json'))) {\n try {\n response = JSON.parse(xhr.responseText);\n } catch (e) {\n response = xhr.responseText;\n }\n }\n resolve({\n data: response,\n status: xhr.status,\n statusText: xhr.statusText,\n headers: xhr.getAllResponseHeaders(),\n xhr: xhr\n });\n } else {\n reject({\n message: `Request failed with status ${xhr.status}`,\n status: xhr.status,\n statusText: xhr.statusText,\n xhr: xhr\n });\n }\n };\n xhr.onerror = function() {\n reject({\n message: 'Network error',\n xhr: xhr\n });\n };\n xhr.ontimeout = function() {\n reject({\n message: 'Request timeout',\n xhr: xhr\n });\n };\n\n // Open the request\n xhr.open(method, url, true);\n\n // Set response type\n if (requestOptions.responseType) xhr.responseType = requestOptions.responseType;\n // Set withCredentials\n if (requestOptions.withCredentials !== undefined) xhr.withCredentials = requestOptions.withCredentials;\n // Set timeout\n if (requestOptions.timeout !== undefined) xhr.timeout = requestOptions.timeout;\n // Set headers\n if (requestOptions.headers) Object.keys(requestOptions.headers).forEach(key => {\n xhr.setRequestHeader(key, requestOptions.headers[key]);\n });\n\n // Connect abort signal to xhr.abort()\n if (fetchOptions.signal) fetchOptions.signal.addEventListener('abort', () => xhr.abort());\n\n // Send the request\n xhr.send(requestOptions.body || null);\n });\n return xhrPromise;\n };\n return this.#_request(requestId, xhrFunction, requestOptions);\n }\n\n /**\n * Cancels a specific request by its identifier.\n * \n * @param {string} requestId - The unique identifier of the request to cancel\n * @returns {boolean} True if the request was found and cancelled, false otherwise\n */\n cancel(requestId) {\n const requestInfo = this.activeRequests.get(requestId);\n if (!requestInfo) return false;\n\n requestInfo.isCancelled = true; // Mark as cancelled\n\n // Try to abort using AbortController (for fetch)\n if (requestInfo.abortController && !requestInfo.abortController.signal.aborted) {\n try {\n requestInfo.abortController.abort('Request was cancelled');\n } catch (error) {}\n }\n\n // Try to cancel using cancel token/function (for axios and others)\n if (requestInfo.cancelToken) {\n try {\n if (typeof requestInfo.cancelToken === 'function') requestInfo.cancelToken();\n else if (requestInfo.cancelToken.cancel) requestInfo.cancelToken.cancel();\n } catch (error) {}\n }\n\n // Reject the wrapper promise\n if (requestInfo.rejectWrapper && this.verbose) {\n requestInfo.rejectWrapper(new Error('Request was cancelled'));\n }\n this.activeRequests.delete(requestId); // Remove from active requests\n return true;\n }\n\n /**\n * Link abort signal with HTTP client abort method.\n * Useful for custom HTTP clients that only support the abort method to cancel requests.\n * @param {Function} abortMethod - The abort method to call when the signal is aborted\n * @param {AbortSignal} signal - The signal to listen to\n */\n addAbortListener(abortMethod, signal) {\n if (!signal) return;\n signal.addEventListener(\"abort\", () => {\n if (typeof abortMethod === 'function') {\n try {\n abortMethod();\n } catch (error) {}\n }\n });\n }\n\n /**\n * Cancels all active requests.\n * \n * @returns {number} The number of requests that were cancelled\n */\n cancelAll() {\n const requestIds = Array.from(this.activeRequests.keys());\n let cancelledCount = 0;\n requestIds.forEach((requestId) => {\n if (this.cancel(requestId)) cancelledCount++;\n });\n return cancelledCount;\n }\n\n /**\n * Checks if a request with the given identifier is currently active.\n * \n * @param {string} requestId - The unique identifier to check\n * @returns {boolean} True if the request is active, false otherwise\n */\n isActive(requestId) {\n return this.activeRequests.has(requestId);\n }\n\n /**\n * Gets the number of active requests.\n * \n * @returns {number} The number of currently active requests\n */\n getActiveCount() {\n return this.activeRequests.size;\n }\n\n /**\n * Clears all active requests without cancelling them.\n * Use with caution - this will not cancel the underlying HTTP requests.\n */\n clear() {\n this.activeRequests.clear();\n }\n}\n\nexport default RequestManager;\n\nexport { RequestManager };\n"],"names":["RequestManager","constructor","managerOptions","this","activeRequests","Map","verbose","options","abortController","_flushRequestOptions","getOptions","setOptions","undefined","_setRequestOptions","getSignal","getAbortController","signal","aborted","AbortController","_clearAbortController","_generateRequestId","url","requestKey","noCancel","Date","now","Math","random","toString","slice","error","String","cleanedUrl","includes","split","_prepareFetchOptions","additionalOptions","fetchOptions","Object","assign","customOptions","keys","forEach","key","_request","requestId","requestPromise","fetch","resolveWrapper","rejectWrapper","cancel","wrapperPromise","Promise","resolve","reject","requestInfo","promise","cancelToken","isCancelled","set","then","req","result","get","delete","catch","onError","scope","Error","setTimeout","request","requestOptions","axios","axiosInstance","axiosLib","CancelToken","source","token","ajax","ajaxMethod","addAbortListener","abort","xhr","XMLHttpRequest","method","toUpperCase","onload","status","response","responseType","getResponseHeader","JSON","parse","responseText","e","data","statusText","headers","getAllResponseHeaders","message","onerror","ontimeout","open","withCredentials","timeout","setRequestHeader","addEventListener","send","body","abortMethod","cancelAll","requestIds","Array","from","cancelledCount","isActive","has","getActiveCount","size","clear"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"request-manager.cjs.min.js","sources":["../main.js"],"sourcesContent":["/**\n * RequestManager - A library for managing and regulating HTTP requests efficiently.\n * @license MIT\n * This library allows you to manage HTTP requests from any library (ajax, Ext.Ajax, axios, fetch, etc.)\n * by accepting Promises as parameters. When a request is repeated with the same identifier,\n * the previous request is automatically cancelled and the new one is executed, giving priority to the most recent requests.\n\n * @param {Object} managerOptions - The options for the manager\n * @param {boolean} managerOptions.verbose - If true, cancellation errors will include messages\n * @returns {RequestManager} A new RequestManager instance\n*/\nclass RequestManager {\n constructor(managerOptions = {}) {\n /**\n * Map to store active requests by their unique identifier.\n * Each entry contains:\n * - promise: The original promise\n * - abortController: AbortController instance (if available)\n * - cancelToken: Cancel token (for axios compatibility)\n * - wrapperPromise: The promise that wraps the request\n * - resolveWrapper: The function to resolve the wrapper promise\n * - rejectWrapper: The function to reject the wrapper promise\n * - isCancelled: Whether the request has been cancelled\n * - verbose: Whether to include verbose messages in the cancellation error\n */\n this.activeRequests = new Map();\n /**\n * Verbose mode: if true, cancellation errors will include messages\n * @type {boolean}\n */\n this.verbose = managerOptions.verbose || false;\n /**\n * Manager options: the options that were passed to the constructor\n * @type {Object}\n */\n this.managerOptions = managerOptions;\n /**\n * Options for the current request: will be flushed after the request is completed\n * @type {Object}\n */\n this.options = {};\n /**\n * AbortController instance for the current request: will be flushed after the request is completed\n * @type {AbortController}\n */\n this.abortController = null;\n }\n\n /**\n * Flushes the options for the current request\n * @private\n */\n #_flushRequestOptions() {\n this.options = {};\n }\n\n /**\n * Gets the manager options\n * @returns {Object} Manager options\n */\n getOptions() {\n return this.managerOptions;\n }\n\n /**\n * Sets the manager options\n * @param {Object} options - The options to set\n */\n setOptions(options) {\n this.managerOptions = options;\n if (options.verbose !== undefined) {\n this.verbose = options.verbose;\n }\n }\n\n /**\n * Sets the options for the current request\n * @param {Object} options - The options to set\n * @private\n */\n #_setRequestOptions(options) {\n this.options = options;\n }\n\n /**\n * Creates an AbortController and returns its signal.\n * The AbortController is stored internally and will be used by the next request() call.\n * This allows users to get the signal before creating the request.\n * \n * @returns {AbortSignal} The signal from a new AbortController\n * \n * @example\n * const signal = requestManager.getSignal();\n * requestManager.request('/api/users', fetch('/api/users', { signal }));\n */\n getSignal() {\n return this.getAbortController().signal;\n }\n\n /**\n * Gets the current AbortController instance\n * Creates a new AbortController if none exists or if the current one is aborted\n * @returns {AbortController} The current AbortController instance\n */\n getAbortController() {\n // Create a new AbortController if none exists or if the current one is aborted\n if (!this.abortController || this.abortController.signal.aborted) {\n this.abortController = new AbortController();\n }\n return this.abortController;\n }\n\n /**\n * Clears the current AbortController\n * @private\n */\n #_clearAbortController() {\n this.abortController = null;\n }\n\n /**\n * Generates a request identifier based on the requestKey or URL\n * @param {string} url - The URL of the request\n * @param {string|number|Function} requestKey - Optional key to generate a deterministic ID.\n * If provided, requests with the same key will share the same ID.\n * If null or undefined, the cleaned URL will be used as the key.\n * @param {boolean} noCancel - If true, generates a unique ID to prevent cancellation\n * @returns {string} A unique request identifier\n * @private\n */\n #_generateRequestId(url, requestKey = null, noCancel = false) {\n if (noCancel) { // Generate a unique ID to prevent cancellation\n return `request_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n }\n if (requestKey !== null && requestKey !== undefined) {\n if (typeof requestKey === 'function') {\n try {\n requestKey = requestKey();\n } catch (error) {\n requestKey = null;\n }\n }\n if (requestKey !== null && requestKey !== undefined) return `request_${String(requestKey)}`;\n }\n // Use cleaned URL as key when requestKey is null/undefined\n let cleanedUrl = url || '';\n let hasProtocol = cleanedUrl.includes('://');\n if (hasProtocol) cleanedUrl = cleanedUrl.split('://')[1];\n let hasParams = cleanedUrl.includes('?');\n if (hasParams) cleanedUrl = cleanedUrl.split('?')[0];\n let hasHash = cleanedUrl.includes('#');\n if (hasHash) cleanedUrl = cleanedUrl.split('#')[0];\n return `request_${cleanedUrl}`;\n }\n\n /**\n * Prepares fetch options by merging options and removing custom properties\n * @param {Object} options - Configuration options\n * @param {AbortSignal} signal - Abort signal to add to fetch options\n * @param {Object} additionalOptions - Additional options to merge\n * @returns {Object} Prepared fetch options\n * @private\n */\n #_prepareFetchOptions(options, signal, additionalOptions = {}) {\n const fetchOptions = Object.assign({}, additionalOptions);\n const customOptions = ['abortController', 'cancelToken', 'requestKey', 'noCancel'];\n Object.keys(options).forEach(key => {\n if (customOptions.includes(key)) return;\n fetchOptions[key] = options[key];\n });\n fetchOptions.signal = signal;\n return fetchOptions;\n }\n\n /**\n * Internal method that handles the core request logic.\n * \n * @param {string} requestId - Unique identifier for the request\n * @param {Promise|Function|string} requestPromise - The request promise, function, or URL string\n * @param {Object} options - Configuration options\n * @param {AbortController} options.abortController - AbortController instance\n * @param {Function} options.cancelToken - Cancel token or cancel function\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * @private\n */\n #_request(requestId, requestPromise, options = {}) {\n this.#_setRequestOptions(options);\n if (!options.abortController) this.#_clearAbortController(); // Clear any existing abortController to ensure each request gets a fresh one\n this.#_flushRequestOptions();\n const abortController = options.abortController || this.getAbortController();\n\n // Handle different types of requestPromise inputs\n // Priority: Function (Custom logic) > String (URL) > Promise (axios, fetch, etc.)\n if (typeof requestPromise === 'function') {\n // Function: custom logic for any library (axios, ajax, etc.)\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = requestPromise({ options: fetchOptions });\n } else if (typeof requestPromise === 'string') {\n // String (URL): make fetch internally\n const fetchOptions = this.#_prepareFetchOptions(options, abortController.signal);\n requestPromise = fetch(requestPromise, fetchOptions);\n }\n\n // Cancel previous request with the same ID if it exists\n if (!options.noCancel) this.cancel(requestId);\n\n // Create a wrapper promise that will be resolved/rejected based on the request\n let resolveWrapper, rejectWrapper;\n const wrapperPromise = new Promise((resolve, reject) => {\n resolveWrapper = resolve;\n rejectWrapper = reject;\n });\n\n // Store the request information\n const requestInfo = {\n promise: requestPromise,\n abortController: abortController,\n cancelToken: options.cancelToken || null,\n wrapperPromise: wrapperPromise,\n resolveWrapper: resolveWrapper,\n rejectWrapper: rejectWrapper,\n isCancelled: false,\n verbose: this.verbose\n };\n\n this.activeRequests.set(requestId, requestInfo);\n\n // Handle request promise completion\n if (requestPromise && typeof requestPromise.then === 'function') {\n try {\n let req = requestPromise.then((result) => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(result);\n }\n });\n if (req.catch) req.catch((error) => {\n onError(this, error);\n });\n } catch (error) {\n onError(this, error);\n }\n function onError(scope, error) {\n // Check if this requestInfo is still the active one, or if it was cancelled\n const currentRequestInfo = scope.activeRequests.get(requestId);\n if (currentRequestInfo !== requestInfo) return;\n // Only delete if this is still the active request\n scope.activeRequests.delete(requestId);\n if (!requestInfo.isCancelled) rejectWrapper(error);\n else if (requestInfo.isCancelled && requestInfo.verbose) rejectWrapper(new Error('Request was cancelled'));\n }\n } else {\n // If requestPromise is not a promise, we can't track its completion automatically\n // This can happen with libraries like ExtJS that return request objects instead of promises\n // In this case, the user should handle the request object themselves\n // We'll resolve the wrapper promise immediately to prevent it from hanging\n // The user can still use the request object returned by the library\n setTimeout(() => {\n if (this.activeRequests.get(requestId) === requestInfo && !requestInfo.isCancelled) {\n this.activeRequests.delete(requestId);\n resolveWrapper(requestPromise); // Resolve with the request object so the user can use it\n }\n }, 0);\n }\n return wrapperPromise;\n }\n\n /**\n * Executes an HTTP request, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Promise|Function} requestPromise - The request promise or function that returns a promise\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Request with Promise\n * requestManager.request('/api/users', axios.get('/api/users', { cancelToken: axios.CancelToken.source().token }));\n * \n * @example\n * // Request with Function\n * requestManager.request('/api/users', ({ options }) => fetch('/api/users', { signal: options.signal, ...options }));\n * \n * @example\n * // Request with Promise and custom cancellation grouping with requestKey\n * const options = {\n * requestKey: 'get-users',\n * cancelToken: axios.CancelToken.source().cancel\n * }\n * requestManager.request('/api/users', axios.get('/api/users', options), options);\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.request('/api/lazy?load=1', fetch('/api/lazy?load=1'), { noCancel: true });\n * requestManager.request('/api/lazy?load=2', fetch('/api/lazy?load=2'), { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n request(url, requestPromise, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, requestPromise, requestOptions);\n }\n\n /**\n * Executes an HTTP request using fetch, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to fetch\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {AbortController} options.abortController - AbortController instance (created automatically if not provided)\n * @param {Function} options.cancelToken - Cancel token or cancel function for other libraries\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as fetch options (method, headers, body, etc.)\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.fetch('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.fetch('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.fetch('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests (e.g., lazy loading)\n * requestManager.fetch('/api/lazy?load=1', { noCancel: true });\n * requestManager.fetch('/api/lazy?load=2', { noCancel: true });\n * // Both requests will execute concurrently without canceling each other\n */\n fetch(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, url, requestOptions);\n }\n\n /**\n * Executes an HTTP request using axios, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed as axios options (method, headers, params, data, etc.)\n * @param {Object} axiosInstance - Optional axios instance to use. If not provided, uses global axios.\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request (uses global axios)\n * requestManager.axios('/api/users');\n * \n * @example\n * // With custom axios instance\n * const myAxios = axios.create({ baseURL: 'https://api.example.com' });\n * requestManager.axios('/users', {}, myAxios);\n * \n * @example\n * // POST request with options\n * requestManager.axios('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.axios('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.axios('/api/lazy?load=1', { noCancel: true });\n * requestManager.axios('/api/lazy?load=2', { noCancel: true });\n */\n axios(url, options = {}, axiosInstance = null) {\n const requestOptions = options || {};\n const axiosLib = axiosInstance || axios;\n const cancelToken = axiosLib.CancelToken.source();\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n return this.#_request(requestId, axiosLib.get(url, { cancelToken: cancelToken.token, ...requestOptions }), {\n cancelToken: cancelToken,\n ...requestOptions\n });\n }\n\n /**\n * Executes an HTTP request using jQuery.ajax, cancelling any previous request with the same identifier.\n * \n * @param {Function} ajaxMethod - A function that receives { url, ...options } and returns a Promise\n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * Any other properties are passed to the ajax method function\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.ajax(ajaxMethod, '/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping with requestKey\n * requestManager.ajax(ajaxMethod, '/api/users', {\n * requestKey: 'get-users'\n * });\n */\n ajax(ajaxMethod, url, options = {}) {\n if (typeof ajaxMethod !== 'function') throw new Error('ajaxMethod must be a function');\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n try {\n const req = ajaxMethod({ url, ...requestOptions });\n this.addAbortListener(req.abort, this.getSignal());\n return this.#_request(requestId, req, requestOptions);\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n /**\n * Executes an HTTP request using XMLHttpRequest, cancelling any previous request with the same identifier.\n * \n * @param {string} url - The URL to request\n * @param {Object} options - Optional configuration\n * @param {string} options.method - HTTP method (GET, POST, PUT, DELETE, etc.). Defaults to 'GET'.\n * @param {Object} options.headers - Headers object to set on the request\n * @param {string|FormData|Blob|ArrayBuffer} options.body - Request body\n * @param {string} options.responseType - Response type ('text', 'json', 'blob', 'arraybuffer', 'document'). Defaults to 'text'.\n * @param {boolean} options.withCredentials - Whether to send credentials with the request\n * @param {number} options.timeout - Request timeout in milliseconds\n * @param {string|number|Function} options.requestKey - Key to identify duplicate requests.\n * If provided, requests with the same key will cancel previous ones.\n * Can be a string, number, or function that returns a key.\n * @param {boolean} options.noCancel - If true, this request will not cancel previous requests with the same ID, allowing concurrent requests\n * @returns {Promise} A Promise that resolves/rejects based on the most recent request\n * \n * @example\n * // Simple GET request\n * requestManager.xhr('/api/users');\n * \n * @example\n * // POST request with options\n * requestManager.xhr('/api/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'John' })\n * });\n * \n * @example\n * // Request with requestKey for custom cancellation grouping\n * requestManager.xhr('/api/users', {\n * requestKey: 'get-users'\n * });\n * \n * @example\n * // Request with noCancel to allow concurrent requests\n * requestManager.xhr('/api/lazy?load=1', { noCancel: true });\n * requestManager.xhr('/api/lazy?load=2', { noCancel: true });\n */\n xhr(url, options = {}) {\n const requestOptions = options || {};\n const requestId = this.#_generateRequestId(url, requestOptions.requestKey, requestOptions.noCancel);\n const xhrFunction = ({ options: fetchOptions }) => {\n // Create XMLHttpRequest\n const xhr = new XMLHttpRequest();\n const method = (requestOptions.method || 'GET').toUpperCase();\n // Create a promise that wraps the XHR request\n const xhrPromise = new Promise((resolve, reject) => {\n xhr.onload = function() {\n if (xhr.status >= 200 && xhr.status < 300) {\n let response = xhr.response;\n if (requestOptions.responseType === 'json' ||\n (xhr.getResponseHeader('Content-Type') && xhr.getResponseHeader('Content-Type').includes('application/json'))) {\n try {\n response = JSON.parse(xhr.responseText);\n } catch (e) {\n response = xhr.responseText;\n }\n }\n resolve({\n data: response,\n status: xhr.status,\n statusText: xhr.statusText,\n headers: xhr.getAllResponseHeaders(),\n xhr: xhr\n });\n } else {\n reject({\n message: `Request failed with status ${xhr.status}`,\n status: xhr.status,\n statusText: xhr.statusText,\n xhr: xhr\n });\n }\n };\n xhr.onerror = function() {\n reject({\n message: 'Network error',\n xhr: xhr\n });\n };\n xhr.ontimeout = function() {\n reject({\n message: 'Request timeout',\n xhr: xhr\n });\n };\n\n // Open the request\n xhr.open(method, url, true);\n\n // Set response type\n if (requestOptions.responseType) xhr.responseType = requestOptions.responseType;\n // Set withCredentials\n if (requestOptions.withCredentials !== undefined) xhr.withCredentials = requestOptions.withCredentials;\n // Set timeout\n if (requestOptions.timeout !== undefined) xhr.timeout = requestOptions.timeout;\n // Set headers\n if (requestOptions.headers) Object.keys(requestOptions.headers).forEach(key => {\n xhr.setRequestHeader(key, requestOptions.headers[key]);\n });\n\n // Connect abort signal to xhr.abort()\n if (fetchOptions.signal) fetchOptions.signal.addEventListener('abort', () => xhr.abort());\n\n // Send the request\n xhr.send(requestOptions.body || null);\n });\n return xhrPromise;\n };\n return this.#_request(requestId, xhrFunction, requestOptions);\n }\n\n /**\n * Cancels a specific request by its identifier.\n * \n * @param {string} requestId - The unique identifier of the request to cancel\n * @returns {boolean} True if the request was found and cancelled, false otherwise\n */\n cancel(requestId) {\n const requestInfo = this.activeRequests.get(requestId);\n if (!requestInfo) return false;\n\n requestInfo.isCancelled = true; // Mark as cancelled\n\n // Try to abort using AbortController (for fetch)\n if (requestInfo.abortController && !requestInfo.abortController.signal.aborted) {\n try {\n requestInfo.abortController.abort('Request was cancelled');\n } catch (error) {}\n }\n\n // Try to cancel using cancel token/function (for axios and others)\n if (requestInfo.cancelToken) {\n try {\n if (typeof requestInfo.cancelToken === 'function') requestInfo.cancelToken();\n else if (requestInfo.cancelToken.cancel) requestInfo.cancelToken.cancel();\n } catch (error) {}\n }\n\n // Reject the wrapper promise\n if (requestInfo.rejectWrapper && this.verbose) {\n requestInfo.rejectWrapper(new Error('Request was cancelled'));\n }\n this.activeRequests.delete(requestId); // Remove from active requests\n return true;\n }\n\n /**\n * Link abort signal with HTTP client abort method.\n * Useful for custom HTTP clients that only support the abort method to cancel requests.\n * @param {Function} abortMethod - The abort method to call when the signal is aborted\n * @param {AbortSignal} signal - The signal to listen to\n */\n addAbortListener(abortMethod, signal) {\n if (!signal) return;\n signal.addEventListener(\"abort\", () => {\n if (typeof abortMethod === 'function') {\n try {\n abortMethod();\n } catch (error) {}\n }\n });\n }\n\n /**\n * Cancels all active requests.\n * \n * @returns {number} The number of requests that were cancelled\n */\n cancelAll() {\n const requestIds = Array.from(this.activeRequests.keys());\n let cancelledCount = 0;\n requestIds.forEach((requestId) => {\n if (this.cancel(requestId)) cancelledCount++;\n });\n return cancelledCount;\n }\n\n /**\n * Checks if a request with the given identifier is currently active.\n * \n * @param {string} requestId - The unique identifier to check\n * @returns {boolean} True if the request is active, false otherwise\n */\n isActive(requestId) {\n return this.activeRequests.has(requestId);\n }\n\n /**\n * Gets the number of active requests.\n * \n * @returns {number} The number of currently active requests\n */\n getActiveCount() {\n return this.activeRequests.size;\n }\n\n /**\n * Clears all active requests without cancelling them.\n * Use with caution - this will not cancel the underlying HTTP requests.\n */\n clear() {\n this.activeRequests.clear();\n }\n}\n\nexport default RequestManager;\n\nexport { RequestManager };\n"],"names":["RequestManager","constructor","managerOptions","this","activeRequests","Map","verbose","options","abortController","_flushRequestOptions","getOptions","setOptions","undefined","_setRequestOptions","getSignal","getAbortController","signal","aborted","AbortController","_clearAbortController","_generateRequestId","url","requestKey","noCancel","Date","now","Math","random","toString","slice","error","String","cleanedUrl","includes","split","_prepareFetchOptions","additionalOptions","fetchOptions","Object","assign","customOptions","keys","forEach","key","_request","requestId","requestPromise","fetch","resolveWrapper","rejectWrapper","cancel","wrapperPromise","Promise","resolve","reject","requestInfo","promise","cancelToken","isCancelled","set","then","req","result","get","delete","catch","onError","scope","Error","setTimeout","request","requestOptions","axios","axiosInstance","axiosLib","CancelToken","source","token","ajax","ajaxMethod","addAbortListener","abort","xhr","XMLHttpRequest","method","toUpperCase","onload","status","response","responseType","getResponseHeader","JSON","parse","responseText","e","data","statusText","headers","getAllResponseHeaders","message","onerror","ontimeout","open","withCredentials","timeout","setRequestHeader","addEventListener","send","body","abortMethod","cancelAll","requestIds","Array","from","cancelledCount","isActive","has","getActiveCount","size","clear"],"mappings":"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"}
|