@lzptec/concurrency
Version:
A Lightweight concurrency manager
1 lines • 17.9 kB
Source Map (JSON)
{"version":3,"sources":["../src/concurrency.ts"],"names":["validateOptions","options","_options","_semaphore","_promise","_Concurrency_static","loop_fn","Concurrency","SharedBase","__privateAdd","Semaphore","taskOptions","validateTask","task","forEach","__privateMethod","__spreadProps","__spreadValues","results","map","mapSettled","validatePredicate","filter","some","find","every","group","args","concurrencyInterval","__privateGet","resolve","reject","callback","loop","input","iterator","validateAndProcessInput","done","maxConcurrency","catchAndAbort","err","count","i","res","_a","interrupt","__privateSet","n","data"],"mappings":"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","file":"chunk-AAKJYGI5.cjs","sourcesContent":["import type { ConcurrencyCommonOptions, ConcurrencyPredicateOptions, ConcurrencyTaskOptions } from './base/options.js';\nimport { every, filter, find, forEach, group, interrupt, loop, map, mapSettled, some, validateAndProcessInput, validatePredicate, validateTask } from './base/shared.js';\nimport { SharedBase } from './base/shared-base.js';\nimport type { Group, Input, RunnableTask, Task } from './base/types.js';\nimport { Semaphore } from './semaphore.js';\n\nfunction validateOptions(options: ConcurrencyCommonOptions) {\n if (!Number.isInteger(options.maxConcurrency) || options.maxConcurrency < 0) {\n throw new Error('Parameter `maxConcurrency` must be a positive integer greater than 0!');\n }\n\n if (typeof options.concurrencyInterval === 'number') {\n if (isNaN(options.concurrencyInterval)) {\n throw new Error('Parameter `concurrencyInterval` invalid!');\n }\n\n if (options.concurrencyInterval < 0) {\n throw new Error('Parameter `concurrencyInterval` must be a positive number!');\n }\n }\n}\n\nexport class Concurrency extends SharedBase<ConcurrencyCommonOptions> {\n\n #options: ConcurrencyCommonOptions = undefined!;\n #semaphore: Semaphore = new Semaphore();\n #promise = Promise.resolve();\n\n static async #loop<A, B>(taskOptions: ConcurrencyTaskOptions<A, B>) {\n validateOptions(taskOptions);\n const { input, maxConcurrency, concurrencyInterval, task } = taskOptions;\n const iterator = validateAndProcessInput(input);\n let done = false;\n\n const catchAndAbort = (err: unknown) => {\n done = true;\n throw err;\n };\n\n await new Promise<void>((resolve, reject) => {\n let count = maxConcurrency;\n for (let i = 0; i < maxConcurrency; i++) {\n (async () => {\n while (!done) {\n const data = await iterator.next();\n if (data.done || done)\n break;\n\n const result = await task(await data.value);\n if (result === interrupt) {\n done = true;\n iterator.return?.();\n break;\n }\n\n if (typeof concurrencyInterval === 'number') {\n await new Promise<void>((resolve) => setTimeout(resolve, concurrencyInterval));\n }\n }\n })()\n .then(() => (--count === 0) ? resolve() : undefined)\n .catch(catchAndAbort)\n .catch(reject);\n }\n });\n }\n\n /**\n * Performs the specified `task` for each element in the `input`.\n * \n * It limits the concurrent execution to `maxConcurrency`.\n *\n * @template A\n * @param {ConcurrencyTaskOptions<A, any>} taskOptions Task Options.\n * @returns {Promise<void>}\n */\n static async forEach<A>(taskOptions: ConcurrencyTaskOptions<A, any>): Promise<void> {\n validateTask(taskOptions.task);\n const { task } = forEach(taskOptions.task);\n\n await this.\n #loop({\n ...taskOptions,\n task\n });\n }\n\n /**\n * Performs the specified `task` function on each element in the `input`, and returns an array that contains the results.\n * \n * It runs in batches with size defined by `batchSize`.\n * \n * @template A Input Type.\n * @template B Output Type.\n * @param {ConcurrencyTaskOptions<A, B>} taskOptions Task Options.\n * @returns {Promise<B[]>}\n */\n static async map<A, B>(taskOptions: ConcurrencyTaskOptions<A, B>): Promise<B[]> {\n validateTask(taskOptions.task);\n\n const { task, results } = map(taskOptions.task);\n\n await this.\n #loop({\n ...taskOptions,\n task\n });\n\n return results;\n }\n\n /**\n * Performs the specified `task` function on each element in the `input`, \n * and creates a Promise that is resolved with an array of results when all of the tasks are resolve or reject.\n * \n * It runs in batches with size defined by `batchSize`.\n * \n * @template A Input Type.\n * @template B Output Type.\n * @param {ConcurrencyTaskOptions<A, B>} taskOptions Task Options.\n * @returns {Promise<PromiseSettledResult<B>[]>}\n */\n static async mapSettled<A, B>(taskOptions: ConcurrencyTaskOptions<A, B>): Promise<PromiseSettledResult<B>[]> {\n validateTask(taskOptions.task);\n\n const { task, results } = mapSettled(taskOptions.task);\n\n await this\n .#loop({\n ...taskOptions,\n task\n });\n\n return results;\n }\n\n /**\n * Returns the elements that meet the condition specified in the `predicate` function.\n * \n * It runs in batches with size defined by `batchSize`.\n *\n * @template A Input Type.\n * @param {ConcurrencyPredicateOptions<A>} taskOptions Task Options.\n * @returns {Promise<A[]>}\n */\n static async filter<A>(taskOptions: ConcurrencyPredicateOptions<A>): Promise<A[]> {\n validatePredicate(taskOptions.predicate);\n\n const { task, results } = filter(taskOptions.predicate);\n\n await this\n .#loop({\n ...taskOptions,\n task\n });\n\n return results;\n }\n\n /**\n * Determines whether the specified `predicate` function returns true for any element of `input`.\n * \n * It runs in batches with size defined by `batchSize`.\n * \n * @template A Input Type.\n * @param {ConcurrencyPredicateOptions<A>} taskOptions Task Options.\n * @returns {Promise<boolean>}\n */\n static async some<A>(taskOptions: ConcurrencyPredicateOptions<A>): Promise<boolean> {\n validatePredicate(taskOptions.predicate);\n\n const { task, results } = some(taskOptions.predicate);\n\n await this\n .#loop({\n ...taskOptions,\n task\n });\n\n return results[0];\n }\n\n /**\n * Returns the `input` value of the first `predicate` that resolves to true, and undefined otherwise.\n * \n * It runs in batches with size defined by `batchSize`.\n * \n * @template A Input Type.\n * @param {ConcurrencyPredicateOptions<A>} taskOptions Task Options.\n * @returns {Promise<A | undefined>}\n */\n static async find<A>(taskOptions: ConcurrencyPredicateOptions<A>): Promise<A | undefined> {\n validatePredicate(taskOptions.predicate);\n\n const { task, results } = find(taskOptions.predicate);\n\n await this\n .#loop({\n ...taskOptions,\n task\n });\n\n return results[0];\n }\n\n /**\n * Determines whether all the elements of `input` satisfy the specified `predicate`.\n * \n * It runs in batches with size defined by `batchSize`.\n * \n * @template A Input Type.\n * @param {ConcurrencyPredicateOptions<A>} taskOptions Task Options.\n * @returns {Promise<boolean>}\n */\n static async every<A>(taskOptions: ConcurrencyPredicateOptions<A>): Promise<boolean> {\n validatePredicate(taskOptions.predicate);\n\n const { task, results } = every(taskOptions.predicate);\n\n await this\n .#loop({\n ...taskOptions,\n task\n });\n\n return results[0];\n }\n\n /**\n * This method groups the elements of the `input` according to the string values returned by a provided `task`.\n * \n * The returned object has separate properties for each group, containing arrays with the elements in the group.\n * \n * It runs in batches with size defined by `batchSize`.\n * \n * @template A Input Type.\n * @param {ConcurrencyTaskOptions<A, string | symbol>} taskOptions Task Options.\n * @returns {Promise<Group<A>>}\n */\n static async group<A>(taskOptions: ConcurrencyTaskOptions<A, string | symbol>): Promise<Group<A>> {\n validateTask(taskOptions.task);\n\n const { task, results } = group(taskOptions.task);\n\n await this\n .#loop({\n ...taskOptions,\n task\n });\n\n return Object.fromEntries(results[0]);\n }\n\n /**\n * \n * @param {ConcurrencyCommonOptions} options \n */\n constructor(options: ConcurrencyCommonOptions) {\n super();\n this.options = options;\n }\n\n override run<A, B>(task: RunnableTask<A, B>, ...args: A[]): Promise<B> {\n const { concurrencyInterval } = this.#options;\n\n const job = new Promise<B>((resolve, reject) => {\n const callback = () => this.#promise\n .then(() => task(...args))\n .then(resolve)\n .catch(reject)\n .then(() => {\n if (typeof concurrencyInterval === 'number')\n return new Promise<void>((resolve) => setTimeout(resolve, concurrencyInterval))\n });\n\n this.#semaphore.run(callback);\n });\n return job;\n }\n\n override async [loop]<A, B>(input: Input<A>, task: Task<A, B>): Promise<void> {\n const iterator = validateAndProcessInput(input);\n\n let done = false;\n const { maxConcurrency } = this.#options;\n\n const catchAndAbort = (err: unknown) => {\n done = true;\n throw err;\n };\n\n await new Promise<void>((resolve, reject) => {\n let count = maxConcurrency;\n for (let i = 0; i < maxConcurrency; i++) {\n this.run(async () => {\n while (true) {\n const res = await iterator.next();\n if (res.done || done)\n break;\n\n await (async () => {\n const result = await task(await res.value);\n if (result === interrupt) {\n done = true;\n iterator.return?.();\n }\n })();\n }\n })\n .then(() => (--count === 0) ? resolve() : undefined)\n .catch(catchAndAbort)\n .catch(reject);\n }\n });\n }\n\n override set options(options: ConcurrencyCommonOptions) {\n validateOptions(options);\n this.#options = { ...this.#options, ...options };\n this.#semaphore.options = this.#options;\n }\n\n override get options() {\n return { ...this.#options };\n }\n\n}\n\nObject.freeze(Concurrency);\n"]}