{"version":3,"sources":["jsdelivr-header.js","/npm/fetch-queue@1.0.3/index.js"],"names":[],"mappings":"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","file":"/npm/fetch-queue@1.0.3/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/fetch-queue@1.0.3/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","let debug = false\r\n\r\nconst defaultConfig = {\r\n    concurrent: 3,\r\n    retries: 3,\r\n    retryDelay: 10,\r\n    fetchOptions: {},\r\n    baseUrl: '',\r\n    retryOn: [408, 409, 418, 425, 429, '5xx']\r\n}\r\n\r\nconst defaultQueue = {\r\n    config: { ...defaultConfig },\r\n    tasks: [],\r\n    retryTimeouts: {},\r\n    running: 0,\r\n    pending: 0,\r\n    kill: null\r\n}\r\n\r\nconst clone = (obj) => {\r\n    return JSON.parse(JSON.stringify(obj))\r\n}\r\n\r\nlet queues = {\r\n    default: clone(defaultQueue)\r\n}\r\n\r\nconst log = (message, queueName, ...args) => {\r\n    if (!debug) {\r\n        return\r\n    }\r\n    console.log(message, queueName ? queues[queueName] || queueName : null, ...args)\r\n}\r\n\r\nconst createQueue = (queueName = 'default', config = {}) => {\r\n    log('Create queue', queueName)\r\n    if (queues[queueName]) {\r\n        log('Queue Exists', queueName)\r\n        return {\r\n            error: 'Queue exists. Cannot create a new one'\r\n        }\r\n    }\r\n    queues[queueName] = {\r\n        ...clone(defaultQueue),\r\n        ...{ config: { ...clone(defaultConfig), ...config } }\r\n    }\r\n    log('Queue created', queueName, queues[queueName])\r\n    return\r\n}\r\n\r\nconst killQueue = (queueName = 'default', force = false) => {\r\n    return new Promise(resolve => {\r\n        log('Kill queue', queueName)\r\n        let queue = queues[queueName] || {}\r\n        queue.kill = resolve\r\n        if (force) {\r\n            log('Force kill queue', queueName)\r\n            Object.keys(queue.retryTimeouts).forEach(timeout => clearTimeout(timeout))\r\n        }\r\n    })\r\n}\r\n\r\nconst destroyQueue = async (queueName = 'default') => {\r\n    log('Destroy queue', queueName)\r\n    await killQueue(queueName)\r\n    delete queues[queueName]\r\n    log('Queue destroyed', queueName)\r\n    if (queueName === 'default') {\r\n        log('Recreate default queue', queueName)\r\n        createQueue()\r\n    }\r\n    return\r\n}\r\n\r\nconst checkQueue = (queueName = 'default') => {\r\n    log('Check queue', queueName)\r\n    let queue = queues[queueName]\r\n    let queued = queue?.tasks?.length || 0\r\n    let pending = Object.keys(queue?.retryTimeouts || {}).length\r\n    let running = queue?.running || 0\r\n    let total = queued + pending + running\r\n    let killed = queue?.kill ? true : false\r\n    return {\r\n        queueName,\r\n        queued,\r\n        pending,\r\n        running,\r\n        total,\r\n        killed,\r\n    }\r\n}\r\n\r\nconst fetchQueue = (url, fetchOptions, queueName = 'default') => {\r\n    if (fetchOptions?.queueName) {\r\n        queueName = fetchOptions.queueName\r\n    }\r\n    log('Fetch queue', queueName)\r\n    let queue = queues[queueName]\r\n    if (!queue) {\r\n        createQueue(queueName)\r\n        queue = queues[queueName]\r\n    }\r\n    return new Promise((resolve, reject) => {\r\n        queue.tasks.push(\r\n            {\r\n                url,\r\n                fetchOptions,\r\n                resolve,\r\n                reject,\r\n                attempts: 0,\r\n                error: null\r\n            }\r\n        )\r\n        log('Task added', queueName)\r\n        processQueue(queueName)\r\n    })\r\n}\r\n\r\nconst wait = (seconds = 1, queueName) => {\r\n    return new Promise(resolve => {\r\n        log('Task wait', queueName, { seconds })\r\n        let queue = queues[queueName]\r\n        let timeout = setTimeout(() => {\r\n            log('Task done waiting', queueName, { timeout })\r\n            resolve()\r\n            if (queue) {\r\n                clearTimeout(timeout)\r\n                delete queue.retryTimeouts[timeout]\r\n            }\r\n        }, 1000 * seconds)\r\n        if (queue) {\r\n            queue.retryTimeouts[timeout] = timeout\r\n        }\r\n    })\r\n}\r\n\r\nconst processQueue = async (queueName) => {\r\n    log('Process queue', queueName)\r\n    let queue = queues[queueName]\r\n    if (!queue) {\r\n        log('Missing queue', queueName)\r\n        return\r\n    }\r\n    if (queue.kill) {\r\n        log('Queue kill requested', queueName)\r\n        let remainingTasks = queue.tasks.splice(0, queue.tasks.length)\r\n        if (remainingTasks.length) {\r\n            log('Killing tasks', queueName, { remainingTasks })\r\n            remainingTasks.forEach(task => task.reject('Queue Killed'))\r\n        }\r\n        let status = checkQueue(queueName)\r\n        if (status.total === 0) {\r\n            log('Queue killed', queueName, { status })\r\n            queue.kill()\r\n            queue.kill = null\r\n        } else {\r\n            log('Queue wrapping up tasks', queueName, { status })\r\n        }\r\n        return\r\n    }\r\n    let concurrent = queue.config.concurrent || defaultConfig.concurrent\r\n    let count = concurrent - queue.running\r\n    if (!count) {\r\n        log('Concurrency maxed out', queueName)\r\n        return\r\n    } else {\r\n        log('Concurrency allows for more tasks', queueName, { count })\r\n    }\r\n    let tasks = queue.tasks.splice(0, count)\r\n\r\n    if (!tasks.length) {\r\n        log('No tasks left', queueName)\r\n        return\r\n    }\r\n    log(`Adding ${tasks.length} tasks`, queueName)\r\n    queue.running += tasks.length\r\n    let promises = tasks.map(async task => {\r\n        task.attempts++\r\n        if (task.attempts > queue.config.retries) {\r\n            log('Task failed too many times', queueName)\r\n            queue.running--\r\n            return task.reject({\r\n                url: task.url,\r\n                fetchOptions: task.fetchOptions,\r\n                attempts: task.error,\r\n                error: task.error\r\n            })\r\n        }\r\n        let options = {\r\n            ...queue.config.fetchOptions,\r\n            ...(task.fetchOptions || {})\r\n        }\r\n        log(`Running task`, queueName)\r\n        return fetch(queue.config.baseUrl + task.url, options)\r\n            .then(resp => {\r\n                log('Task completed', queueName)\r\n                let httpErrorXX = resp.status ? resp.status.toString()[0] + 'xx' : null\r\n                if (\r\n                    !resp.ok ||\r\n                    queue.config.retryOn.indexOf(resp.status) > 1 ||\r\n                    queue.config.retryOn.indexOf(httpErrorXX) > 1) {\r\n                    log('Task did not succeed', queueName)\r\n                    throw resp\r\n                }\r\n                task.resolve(resp)\r\n                queue.running--\r\n                processQueue(queueName)\r\n                return\r\n            }).catch(async err => {\r\n                console.log(queue.running)\r\n                queue.running--\r\n                console.log(queue.running)\r\n                task.error = err\r\n                log('Task threw an error', queueName)\r\n                processQueue(queueName)\r\n                // queue.pending++\r\n                let delay = queue.kill ? 0 : queue.config.retryDelay\r\n                await wait(delay, queue)\r\n                log('Requeued task', queueName, queue)\r\n\r\n                // queue.pending--\r\n                queue.tasks.push(task)\r\n                processQueue(queueName)\r\n                return\r\n            })\r\n    })\r\n    return Promise.allSettled(promises)\r\n}\r\n\r\nconst debugQueue = () => {\r\n    debug = true\r\n}\r\n\r\nexport default fetchQueue\r\n\r\nexport {\r\n    fetchQueue,\r\n    createQueue,\r\n    checkQueue,\r\n    killQueue,\r\n    destroyQueue,\r\n    debugQueue\r\n}\r\n\r\n"]}