{
  "version": 3,
  "sources": ["../src/shared/inputValidation.js", "../src/retryEngine/index.js", "../src/index.js"],
  "sourcesContent": [
    "/**\n * input validation\n * @param {unknown} input The input you want to test\n * @param {string} type The type you want the input to be\n * @param {boolean} required Whether the input is required or not\n *\n */\nconst inputValidation = (input, type, required) => {\n    if (required && !input && input !== 0) {\n        throw new SyntaxError(\"input is required\");\n    }\n    if (input && typeof input !== type) {\n        throw new TypeError(`input must be a ${type}, but got ${typeof input}`);\n    }\n};\nexport default inputValidation;\n",
    "\"use strict\";\nimport inputValidation from \"../shared/inputValidation\";\n/**\n * @namespace RetryEngine\n */\n\nexport default class RetryEngine {\n    #retries = new WeakMap();\n    #errorsOnRetries = new WeakMap();\n    maxRetries = 0;\n\n    /**\n     * Create a retry engine\n     *\n     * @memberof RetryEngine\n     * @param {number} [maxRetries] - The max amount of retries that needs to be attempted\n     */\n    constructor(maxRetries) {\n        inputValidation(maxRetries, \"number\", true);\n        this.maxRetries = maxRetries;\n    }\n\n    /**\n     * Set the max amount of times a promise can be retried after a failure\n     * By default the queue will not retry a failed promise.\n     *\n     * @memberof RetryEngine\n     * @param {number} maxRetries - The max amount of promises to run concurrently\n     */\n    setRetries(maxRetries) {\n        inputValidation(maxRetries, \"number\", true);\n        this.maxRetries = maxRetries;\n    }\n    /**\n     * @callback retryCallback\n     * @param {Error} maxReachedErr err returned when the max retries have been reached\n     *\n     */\n\n    /**\n     * handleErrorWithRetryEngine\n     *\n     * @memberof RetryEngine\n     * @param {Function} fn The fn that retruns the promise added by user\n     * @param {unknown} err The error that the promise returned\n     * @param {retryCallback} callback the callback that the engine runs on completion\n     *\n     */\n    handleErrorWithRetryEngine(fn, err, callback) {\n        this.#errorsOnRetriesHandler(fn, err);\n        this.#retryRunner(fn, callback);\n    }\n\n    #errorsOnRetriesHandler(fn, err) {\n        if (this.#errorsOnRetries.has(fn)) {\n            this.#updateErrorsOnRetriesMap(fn, err);\n        } else {\n            this.#errorsOnRetries.set(fn, [err]);\n        }\n    }\n\n    #updateErrorsOnRetriesMap(fn, err) {\n        const pastErrors = this.#errorsOnRetries.get(fn);\n        const updatedErrorsList = RetryEngine.#resizeArray(\n            pastErrors,\n            pastErrors.length + 1,\n        );\n        updatedErrorsList[pastErrors.length] = err;\n        this.#errorsOnRetries.set(fn, updatedErrorsList);\n    }\n\n    #retryRunner(fn, callback) {\n        if (!this.#retries.has(fn)) {\n            this.#retries.set(fn, 1);\n        }\n        if (this.maxRetries > this.#retries.get(fn)) {\n            this.#setRetryTimeout().then(() => {\n                this.#createRetry(fn, callback);\n            });\n        } else {\n            callback(\n                new AggregateError(\n                    this.#errorsOnRetries.get(fn),\n                    \"max retries reached\",\n                ),\n            );\n        }\n    }\n\n    #setRetryTimeout() {\n        return new Promise((resolve) => {\n            setTimeout(resolve, RetryEngine.#getBackOffDelay(this.#retries));\n        });\n    }\n\n    #createRetry(fn, callback) {\n        const pastTries = this.#retries.get(fn);\n        this.#retries.set(fn, pastTries + 1);\n        callback();\n    }\n\n    static #resizeArray(oldArray, newArrayLength) {\n        const newArray = new Array(newArrayLength);\n        for (let i = 0; i < newArrayLength; i++) {\n            newArray[i] = oldArray[i];\n        }\n        return newArray;\n    }\n\n    static #getBackOffDelay(retries) {\n        const baseDelayMs = 300;\n        return baseDelayMs * 2 ** retries;\n    }\n}\n",
    "\"use strict\";\nimport RetryEngine from \"./retryEngine\";\nimport inputValidation from \"./shared/inputValidation\";\n/**\n * @namespace AsyncQueue\n */\n\n/**\n */\nexport const QUEUE_ERRORS = {\n    ABORT: \"Aborted\",\n    INPUT_REQUIRED: \"input is required\",\n    MAX_RETRIES: \"max retries reached\",\n};\n\nexport class Queue {\n    #queue = new Set();\n    #running = 0;\n    #maxConcurrency = 0;\n    #timeout = 0;\n    /**\n     * @type {RetryEngine| null}\n     */\n    #retryEngine = null;\n\n    /**\n     * Create a Queue\n     *\n     * @memberof AsyncQueue\n     * @param {Object} [config] - the config for asyncrify\n     * @param {number=} config.maxConcurrency - The max amount of promises to run concurrently\n     * @param {number=} config.maxRetries - The max amount of promises to run concurrently\n     * @param {number=} config.timeout - The max amount of time in ms a promise can take to settle\n     * @example\n     *\n     * //to define a queue with a default length of 5\n     * const queue = new Queue()\n     *\n     * @example\n     * //to define a queue with a specified length of 3\n     * const queue = new Queue({maxConcurrency: 3})\n     */\n    constructor(config) {\n        inputValidation(config, \"object\", false);\n        if (config) {\n            inputValidation(config.maxConcurrency, \"number\", false);\n            inputValidation(config.maxRetries, \"number\", false);\n            inputValidation(config.timeout, \"number\", false);\n            if (config.maxConcurrency) this.#maxConcurrency = config.maxConcurrency;\n            if (config.maxRetries) {\n                this.#retryEngine = new RetryEngine(config.maxRetries);\n            }\n            if (config.timeout) this.#timeout = config.timeout;\n        }\n    }\n\n    /**\n     * Set the max amount of promises to run concurrently after queue initialization\n     *\n     * @memberof AsyncQueue\n     * @param {number} maxConcurrency - The max amount of promises to run concurrently\n     */\n    setMaxConcurrency(maxConcurrency) {\n        inputValidation(maxConcurrency, \"number\", true);\n        this.#maxConcurrency = maxConcurrency;\n    }\n\n    /**\n     * Set the max amount of times a promise can be retried after a failure\n     * By default the queue will not retry a failed promise.\n     *\n     * @memberof AsyncQueue\n     * @param {number} maxRetries - The max amount of promises to run concurrently\n     *@example\n     * const queue = new Queue()\n     *\n     * //setting retries to 3\n     * queue.setRetries(3)\n     *\n     * const pets = () =>{\n     *   return new Promise((resolve, reject) =>{\n     *     setTimeout(reject('rejected'), 100)\n     *   })\n     * }\n     *\n     * const callback = (res) => {\n     *   //do something with data\n     * }\n     *\n     * const errCallback = ( err) => {\n     *   console.log(err.message) // output: 'max retries reached'\n     *   console.log(err.errors) //  output: list of errors\n     * }\n     *\n     * queue.add(pets, callback, errCallback)\n     */\n    setMaxRetries(maxRetries) {\n        inputValidation(maxRetries, \"number\", true);\n        if (!this.#retryEngine) {\n            this.#retryEngine = new RetryEngine(maxRetries);\n        } else {\n            this.#retryEngine.setRetries(maxRetries);\n        }\n    }\n\n    /**\n     * Set the max amount of time a promise can take to settle\n     * By default the queue will not monitor the promise time to settle\n     * a signal must be handled in the promise for the timeout to abort the promise\n     *\n     * @memberof AsyncQueue\n     * @param {number} timeout - The max amount of time in ms a promise can take to settle\n     * @todo implement abort controller to kill promise when timeout is reached\n     * @example\n     * const queue = new Queue()\n     *\n     * //setting timeout for promises to 100ms\n     * queue.setPromiseTimeout(100)\n     *\n     * //function returns the promise we want to add to queue\n     * const pets = (signal) =>{\n     *   return new Promise((resolve, reject) =>{\n     *   signal.addEventListener(\"abort\", () => {\n     *    reject(\"Aborted\")\n     *   }\n     *     setTimeout(resolve, 500) //note that the timeout in the promise is larger than the set promise timeout\n     *   })\n     * }\n     *\n     * //the callback that is ran on the resolution of the promise\n     * const callback = (res ) => {\n     *   //do something with data\n     * }\n     *\n     * //the callback that is ran on the rejection of the promise\n     * const errCallback = (err) => {\n     * console.log(err) //output: \"Request timed out\"\n     * }\n     *\n     * //Adding the promise to the queue\n     * queue.add(pets, callback, errCallback)\n     */\n    setPromiseTimeout(timeout) {\n        inputValidation(timeout, \"number\", true);\n        this.#timeout = timeout;\n    }\n\n    /**\n     * @callback resCallback\n     *\n     * @param {Object} res - The response from the promise\n     * @return {void}\n     * @todo add support for array input\n     * @example\n     *\n     *\n     * const pets = () =>{\n     *   return new Promise((resolve, reject) =>{\n     *     setTimeout(resolve('finished'), 100)\n     *   })\n     * }\n     *\n     * const callback = (res) => {\n     *  //do something with res\n     * }\n     *\n     * queue.add(pets, callback)\n     */\n\n    /**\n     * @callback errCallback\n     *\n     * @param {Error} err - The response from the promise\n     * @return {void}\n     * @todo add support for array input\n     * @example\n     *\n     *\n     * const pets = () =>{\n     *   return new Promise((resolve, reject) =>{\n     *     setTimeout(reject('rejected'), 100)\n     *   })\n     * }\n     *\n     * const callback = (res) => {\n     *  //do something with res\n     * }\n     *\n     * const errorCallback = (err) => {\n     *  //do something with error\n     * }\n     *\n     * queue.add(pets, callback, errorCallback)\n     */\n\n    /**\n     * @callback promiseFunction\n     *\n     * @param {AbortSignal=} signal - The signal for the abort controller for the timeout to abort the promise\n     * @returns {Promise<unknown>} The promise you want to add to the queue\n     * @example\n     * const pets = (signal) =>{\n     *   return new Promise((resolve, reject) =>{\n     *   signal.addEventListener(\"abort\", () => {\n     *    reject(\"Aborted\")\n     *   }\n     *     setTimeout(resolve, 100)\n     *   })\n     * }\n     */\n\n    /**\n     * Add an function to the queue\n     * Takes in a function that returns a Promise\n     *\n     * @memberof AsyncQueue\n     * @param {promiseFunction} fn - The function that returns a promise you want to add to the queue\n     * @param {resCallback} callback - The function that is executed when the promise resolves\n     * @param {errCallback} callback - The function that is executed when the promise rejects\n     * @example\n     * const queue = new Queue()\n     *\n     * //function returns the promise we want to add to queue\n     * const pets = () =>{\n     *   return new Promise((resolve) =>{\n     *     setTimeout(resolve, 100)\n     *   })\n     * }\n     *\n     * //the callback that is ran on the settlement of the promise\n     * const callback = (res) => {\n     *   //do something with response\n     * }\n     *\n     * const error = (err) => {\n     *   throw new Error(err)\n     * }\n     *\n     * //Adding the promise to the queue\n     * queue.add(pets, callback, error)\n     */\n    add(fn, callback, err) {\n        inputValidation(err, \"function\", false);\n        inputValidation(fn, \"function\", true);\n        inputValidation(callback, \"function\", true);\n\n        if (this.#maxConcurrency !== 0 && this.#running >= this.#maxConcurrency) {\n            this.#queue.add(fn);\n        } else {\n            this.#running++;\n            this.#promiseRunner(fn, callback, err);\n        }\n    }\n\n    #promiseRunner(fn, callback, errorCallback) {\n        const promise = fn(\n            this.#timeout > 0 ? AbortSignal.timeout(this.#timeout) : null,\n        );\n        promise\n            .then(callback)\n            .catch((err) => {\n                this.#errorHandler(err, fn, errorCallback, callback);\n            })\n            .finally(() => {\n                this.#running--;\n                this.#runPromiseFromQueue(callback, errorCallback);\n            });\n    }\n\n    #runPromiseFromQueue(callback, errorCallback) {\n        if (this.#queue.size > 0) {\n            const nextPromise = this.#queue.values().next().value;\n            this.#queue.delete(nextPromise);\n            this.add(nextPromise, callback, errorCallback);\n        }\n    }\n\n    #errorHandler(err, fn, errCallback, callback) {\n        if (this.#retryEngine && this.#retryEngine.maxRetries > 0) {\n            this.#retryEngine.handleErrorWithRetryEngine(fn, err, (maxRetriesErr) => {\n                if (maxRetriesErr && errCallback) {\n                    errCallback(maxRetriesErr);\n                } else {\n                    this.add(fn, callback, errCallback);\n                }\n            });\n        } else if (errCallback) {\n            errCallback(err);\n        }\n    }\n}\n\n/**\n * abort handler for handling aborts in your promise\n * @param {AbortSignal} signal - the reject function of the promise\n * @param {RejectFunction} reject - the reject function of the promise\n * @example\n *\n * const promise = (signal) => {\n *  return new Promise((resolve, reject) => {\n *      abortHandler(signal, reject);\n *\n *      setTimeout(resolve, 5000, \"resolved\");\n *  });\n * };\n *\n * const callback = (res) {\n *   // handle res here\n * }\n * const errHandler = (err) {\n *   console.log(err.message) //output: \"Aborted\"\n * }\n *\n * queue.add(promise, callback, errHandler)\n */\nexport const abortHandler = (signal, reject) => {\n    if (signal.aborted) {\n        return reject(new Error(\"Aborted\"));\n    }\n    const abortHandler = () => {\n        reject(new Error(\"Aborted\"));\n        signal.removeEventListener(\"abort\", abortHandler);\n    };\n    signal.addEventListener(\"abort\", abortHandler);\n};\n\nexport default Queue;\n"
  ],
  "mappings": "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",
  "debugId": "C18B6056F659F70E64756E2164756E21",
  "names": []
}