{"id":16727941,"url":"https://github.com/ms-fadaei/async-tasks-runner","last_synced_at":"2025-03-17T01:31:39.450Z","repository":{"id":40309297,"uuid":"424994648","full_name":"ms-fadaei/async-tasks-runner","owner":"ms-fadaei","description":"Tiny (~ 1kb gzipped), side-effect free, tree shakable, zero dependencies, and fully typed Tasks Runner. Run your tasks in parallel, serial \u0026 pipeline in a more complicated and performant way.","archived":false,"fork":false,"pushed_at":"2024-02-23T21:30:24.000Z","size":346,"stargazers_count":62,"open_issues_count":12,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-24T12:25:07.867Z","etag":null,"topics":["async","parallel","pipeline","promise","serial","task-runner","tasks"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ms-fadaei.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-05T15:23:16.000Z","updated_at":"2024-07-05T03:46:51.221Z","dependencies_parsed_at":"2022-09-06T04:02:20.361Z","dependency_job_id":"adedfdd5-9bb9-4466-96dd-50928a29dbfc","html_url":"https://github.com/ms-fadaei/async-tasks-runner","commit_stats":{"total_commits":112,"total_committers":3,"mean_commits":"37.333333333333336","dds":0.3571428571428571,"last_synced_commit":"ee3c5aa0bb3db5418c9fb8c20ae40dbe4400e67b"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ms-fadaei%2Fasync-tasks-runner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ms-fadaei%2Fasync-tasks-runner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ms-fadaei%2Fasync-tasks-runner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ms-fadaei%2Fasync-tasks-runner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ms-fadaei","download_url":"https://codeload.github.com/ms-fadaei/async-tasks-runner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243836015,"owners_count":20355615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","parallel","pipeline","promise","serial","task-runner","tasks"],"created_at":"2024-10-12T23:07:56.484Z","updated_at":"2025-03-17T01:31:39.045Z","avatar_url":"https://github.com/ms-fadaei.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Async Tasks Runner\n\n[![npm version][npm-version-src]][npm-version-href]\n[![npm downloads][npm-downloads-src]][npm-downloads-href]\n[![Github Actions CI][github-actions-ci-src]][github-actions-ci-href]\n[![License][license-src]][license-href]\n\n\u003e tiny (~ 1kb gzipped), side-effect free, tree shakable, zero dependencies, and fully typed Tasks Runner. Run your tasks in parallel, serial \u0026 pipeline in a more complicated and performant way.\n\nWith this module you can run your tasks in 3 different ways:\n\n* Parallel: Run your independent tasks in parallel. The result is an array, like the `Promise.allSettled` result.\n* Serial: Run your independent tasks in sequence. The result is an array, like the `Promise.allSettled` result.\n* Pipeline: Run your dependent tasks in sequence. The result of every task will be passed to the next task.\n\n![Async Tasks Runner](https://user-images.githubusercontent.com/54557683/140879231-30adf612-9149-4a10-af9f-6af094fa9152.jpg)\n\n\n\n⚠️ Attention: This package comes without any polyfills. If you want to support an older environment, please polyfills it depending on what you need.\n* ES2015\n* ES2017 async/await\n* ES2020 Promise.allSettled (Just for the ParallelTasksRunner)\n\n\u003cimg width=\"460\" alt=\"environment support\" src=\"https://user-images.githubusercontent.com/54557683/140879289-456a341b-d272-45e8-8a6d-7d6b4ba83bf6.jpg\"\u003e\n\n\n## Setup\n\n1. Add `async-tasks-runner` dependency with `yarn` or `npm` to your project\n\n```bash\nyarn add async-tasks-runner\n\n# or\n\nnpm install async-tasks-runner\n```\n\n2. Use it everywhere you want\n```js\n// ES Module\nimport {createParallelTasksRunner, runParallelTasks, getParallelTasks} from \"async-tasks-runner\"\n\n// CJS\nconst {createParallelTasksRunner, runParallelTasks, getParallelTasks} = require(\"async-tasks-runner\")\n```\n\n## Runners\n\n| Runner | Example |\n| ------ | ------- |\n| ParallelTasksRunner | See [Examples](#parallel-tasks-runner) |\n| SerialTasksRunner | See [Examples](#serial-tasks-runner) |\n| PipelineTasksRunner | See [Examples](#pipeline-tasks-runner) |\n\n## Global Helper Functions\n\n| Functions | Description| Parameter(s) | Return Value |\n| ------ | ------- | ------ | ------- |\n| pushTasks | push tasks to the runner. [See pushTasks Section](#pushTasks) | taskRunnerObject, tasks[] | number: the new length of tasks |\n| spliceTasks | removing or replacing existing tasks and/or adding new elements in place [See spliceTasks Section](#spliceTasks) | taskRunnerObject, startIndex, deleteCount, newTasks[] | array: list of removed tasks |\n| getTasksRunnerStatus | current status of the runner. [See getTasksRunnerStatus Section](#getTasksRunnerStatus) | taskRunnerObject | string: status |\n\n### pushTasks\nWith this function, you can push new tasks to the runner (like `Array.prototype.push()`).\n```js\npushTasks(taskRunnerObject, ...newTasks[]);\n```\n\n### spliceTasks\nWith this function, you can change the contents of an array by removing or replacing existing elements and/or adding new elements in place (like `Array.prototype.splice()`).\n```js\nspliceTasks(taskRunnerObject, start, deleteCount, ...newTasks[] );\n```\n\n### getTasksRunnerStatus\nWith this function, you can get the current status of the runner.\n```js\nconst currentStatus = getTasksRunnerStatus(taskRunnerObject)\n```\n\nThis function returns 4 different statuses:\n1. `standby`: The runner is open to adding or removing tasks. This status actually present that the runner is not started yet!\n2. `pending`: Represent that the runner starts pending the tasks and in the meantime, you can't nor add/remove tasks to/from the runner neither reset the runner.\n3. `fulfilled`: Represent that the runner did its job and now you can get the result or reset the runner to add/remove tasks to/from the runner and run them again.\n4. `rejected`: In this status, the runner did its job but with an error in the process, and the whole run is rejected. Like `fulfilled` status, you can reset the runner to add/remove tasks to/from the runner and run them again.\n\n## Examples\n\n### Parallel Tasks Runner\nYou can run your tasks in parallel. the result is an array, like the `Promise.allSettled` result.\n\n#### Create\nYou can create a parallel task runner object by the calling of `createParallelTaskRunner`. The result will be an object that must be passed as the first argument to any helper functions that you want to use.\n\n```js\nimport {createParallelTasksRunner} from \"async-tasks-runner\"\nconst taskRunnerObject = createParallelTasksRunner(...tasks);\n```\n\nEvery task in the `ParallelTasksRunner` must be a function without a parameter and return a promise.\n\n```js\nconst url = \"https://google.com\";\n\nconst task1 = () =\u003e {\n    return fetch(`${url}/first`);\n}\n\nconst task2 = () =\u003e {\n    return fetch(`${url}/second`);\n}\n\nconst taskRunnerObject = createParallelTasksRunner(task1, task2);\n```\n\n#### Run\nStart pending the runner. When it is called, the status changed to `pending` and when it is done, the status changed to `fulfilled`. If you run it again, it's not starting to run again and fulfilled with the previous result unless you reset the runner. This means you can start the runner then do some heavy work and call it again to get the result without getting the process blocked! This method returns a promise that resolves after all of the given promises have either been fulfilled or rejected, with an array of objects that each describes the outcome of each promise.\n\n```js\nimport {runParallelTasks} from \"async-tasks-runner\"\nconst result = await runParallelTasks(taskRunnerObject);\n\n// [\n//   {status: \"fulfilled\", value: 33},\n//   {status: \"fulfilled\", value: 66},\n//   {status: \"fulfilled\", value: 99},\n//   {status: \"rejected\",  reason: Error: an error}\n// ]\n```\n\n#### Result of Specific Task\nAfter running the runner (no matter of status is `pending` or `fulfilled` or `rejected`), you can access a specific task with this method. The only parameter of this method is the index of the task. This method returns a Promise that resolves with the task result or is rejected with the current or previous task rejection.\n\n```js\nimport {getParallelTasks} from \"async-tasks-runner\"\nconst result = await getParallelTasks(taskRunnerObject, 0);\n```\n\n#### Clone\nYou can clone tasks of your runner and create a new tasks runner.\n\n```js\nimport {createParallelTasksRunner} from \"async-tasks-runner\"\nconst newTaskRunnerObject = createParallelTasksRunner(...taskRunnerObject.tasks);\n```\n\n### Serial Tasks Runner\nYou can run your tasks in sequence. the result is an array, like the `Promise.allSettled` result.\n\n#### Create\nYou can create a serial task runner object by the calling of `createSerialTaskRunner`. The result will be an object that must be passed as the first argument to any helper functions that you want to use.\n\n```js\nimport {createSerialTasksRunner} from \"async-tasks-runner\"\nconst taskRunnerObject = createSerialTasksRunner(...tasks);\n```\n\nEvery task in the `SerialTasksRunner` must be a function without a parameter and return a promise.\n\n```js\nconst url = \"https://google.com\";\n\nconst task1 = () =\u003e {\n    return fetch(`${url}/first`);\n}\n\nconst task2 = () =\u003e {\n    return fetch(`${url}/second`);\n}\n\nconst taskRunnerObject = createSerialTasksRunner(task1, task2);\n```\n\n#### Run\nStart pending the runner. When it is called, the status changed to `pending` and when it is done, the status changed to `fulfilled`. If you run it again, it's not starting to run again and fulfilled with the previous result unless you reset the runner. This means you can start the runner then do some heavy work and call it again to get the result without getting the process blocked! This method returns a promise that resolves after all of the given promises have either been fulfilled or rejected, with an array of objects that each describes the outcome of each promise.\n\n```js\nimport {runSerialTasks} from \"async-tasks-runner\"\nconst result = await runSerialTasks(taskRunnerObject);\n\n// [\n//   {status: \"fulfilled\", value: 33},\n//   {status: \"fulfilled\", value: 66},\n//   {status: \"fulfilled\", value: 99},\n//   {status: \"rejected\",  reason: Error: an error}\n// ]\n```\n\n#### Result of Specific Task\nAfter running the runner (no matter of status is `pending` or `fulfilled` or `rejected`), you can access a specific task with this method. The only parameter of this method is the index of the task. This method returns a Promise that resolves with the task result or is rejected with the current or previous task rejection.\n\n```js\nimport {getSerialTasks} from \"async-tasks-runner\"\nconst result = await getSerialTasks(taskRunnerObject, 0);\n```\n\n#### Clone\nYou can clone tasks of your runner and create a new tasks runner.\n\n```js\nimport {createSerialTasksRunner} from \"async-tasks-runner\"\nconst newTaskRunnerObject = createSerialTasksRunner(...taskRunnerObject.tasks);\n```\n\n### Pipeline Tasks Runner\nYou can run your tasks in sequence. The result of the currently pending task will be the argument of the next task.\n\n#### Create\nYou can create a serial task runner object by the calling of `createPipelineTaskRunner`. The result will be an object that must be passed as the first argument to any helper functions that you want to use.\n\n```js\nimport {createPipelineTasksRunner} from \"async-tasks-runner\"\nconst taskRunnerObject = createPipelineTasksRunner(...tasks);\n```\n\nEvery task in the `PipelineTasksRunner` must be a function that returns a promise. This function can accept one parameter that will be filled with the previous fulfilled task result.\n\n```js\nconst url = \"https://google.com\";\n\nconst task1 = (code) =\u003e {\n    return fetch(`${url}/${code}`);\n}\n\nconst task2 = (data) =\u003e {\n    return fetch(data.url);\n}\n\nconst taskRunnerObject = createPipelineTasksRunner(task1, task2);\n```\n\n#### Run\nWith this method, you can start pending the tasks. When it is called, the status changed to `pending` and when it is done, the status changed to `fulfilled` if all tasks run successfully or `rejected` if one of the tasks in the list get failed (and the next tasks don't get run). If you run it again, it's not starting to run again and `fulfilled` or `rejected` with the previous result unless you reset the runner. This means you can start the runner then do some heavy work and call it again to get the result without getting the process blocked! This method always returns a promise that resolves with the final task result or rejects with an error. The `runPipelineTasks` function needs an extra argument for the parameter of the first task function (initial parameter).\n\n```js\nimport {runPipelineTasks} from \"async-tasks-runner\"\nconst result = await runPipelineTasks(taskRunnerObject, firstArgument);\n\n// [\n//   {status: \"fulfilled\", value: 33},\n//   {status: \"fulfilled\", value: 66},\n//   {status: \"fulfilled\", value: 99},\n//   {status: \"rejected\",  reason: Error: an error}\n// ]\n```\n\n#### Result of Specific Task\nAfter running the runner (no matter of status is `pending` or `fulfilled` or `rejected`), you can access a specific task with this method. The only parameter of this method is an index of the task. This method returns a Promise that resolves with the task result or is rejected with the current or previous task failure error.\n\n```js\nimport {getPipelineTasks} from \"async-tasks-runner\"\nconst result = await getPipelineTasks(taskRunnerObject, 0);\n```\n\n#### Clone\nYou can clone tasks of your runner and create a new tasks runner.\n\n```js\nimport {createPipelineTasksRunner} from \"async-tasks-runner\"\nconst newTaskRunnerObject = createPipelineTasksRunner(...taskRunnerObject.tasks);\n```\n\n## Extra Helper Functions\n\n| Functions | Description| Parameter(s) | Return Value |\n| ------ | ------- | ------ | ------- |\n| createTimeoutResolve | create a delay with resolve | timeout: number, response: T, cancelToken?: Promise | promise |\n| createTimeoutReject | create a delay with reject | timeout: number, response: T, cancelToken?: Promise | promise |\n| createTaskWithTimeout | create a task with timeout | task: Task, timeout: number | Task\n\n## Contribution\n\n1. Fork this repository\n2. Install dependencies using `yarn install` or `npm install`\n3. Making your changes\n4. Run the `yarn lint` command\n5. Run the `yarn test` command\n6. Push and make a PR\n\n## License\n\n[MIT License](./LICENSE)\n\nCopyright (c) Mohammad Saleh Fadaei ([@ms-fadaei](https://github.com/ms-fadaei))\n\n\n\u003c!-- Badges --\u003e\n[npm-version-src]: https://img.shields.io/npm/v/async-tasks-runner/latest.svg\n[npm-version-href]: https://npmjs.com/package/async-tasks-runner\n\n[npm-downloads-src]: https://img.shields.io/npm/dt/async-tasks-runner.svg\n[npm-downloads-href]: https://npmjs.com/package/async-tasks-runner\n\n[github-actions-ci-src]: https://github.com/ms-fadaei/async-tasks-runner/workflows/ci/badge.svg\n[github-actions-ci-href]: https://github.com/ms-fadaei/async-tasks-runner/actions?query=workflow%3Aci\n\n[license-src]: https://img.shields.io/npm/l/async-tasks-runner.svg\n[license-href]: https://npmjs.com/package/async-tasks-runner\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fms-fadaei%2Fasync-tasks-runner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fms-fadaei%2Fasync-tasks-runner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fms-fadaei%2Fasync-tasks-runner/lists"}