combine-async-iterators
Advanced tools
Comparing version 2.0.1 to 2.1.0
@@ -0,0 +0,0 @@ declare function combineAsyncIterators( |
89
index.js
@@ -1,58 +0,55 @@ | ||
"use strict"; | ||
function getNextAsyncIteratorFactory(options) { | ||
return async(asyncIterator, index) => { | ||
try { | ||
const iterator = await asyncIterator.next(); | ||
return async(asyncIterator, index) => { | ||
try { | ||
const iterator = await asyncIterator.next(); | ||
return { index, iterator }; | ||
} | ||
catch (err) { | ||
if (options.errorCallback) { | ||
options.errorCallback(err, index); | ||
} | ||
if (options.throwError !== false) { | ||
return Promise.reject(err); | ||
} | ||
return { index, iterator }; | ||
} | ||
catch (err) { | ||
if (options.errorCallback) { | ||
options.errorCallback(err, index); | ||
} | ||
if (options.throwError !== false) { | ||
return Promise.reject(err); | ||
} | ||
return { index, iterator: { done: true } }; | ||
} | ||
}; | ||
return { index, iterator: { done: true } }; | ||
} | ||
}; | ||
} | ||
async function* combineAsyncIterators(...iterators) { | ||
let [options] = iterators; | ||
if (typeof options.next === "function") { | ||
options = Object.create(null); | ||
} | ||
else { | ||
iterators.shift(); | ||
} | ||
let [options] = iterators; | ||
if (options && typeof options.next === "function") { | ||
options = Object.create(null); | ||
} | ||
else { | ||
iterators.shift(); | ||
} | ||
// Return if iterators is empty (avoid infinite loop). | ||
if (iterators.length === 0) { | ||
return; | ||
} | ||
const getNextAsyncIteratorValue = getNextAsyncIteratorFactory(options); | ||
// Return if iterators is empty (avoid infinite loop). | ||
if (iterators.length === 0) { | ||
return; | ||
} | ||
const getNextAsyncIteratorValue = getNextAsyncIteratorFactory(options); | ||
try { | ||
const asyncIteratorsValues = new Map(iterators.map((it, idx) => [idx, getNextAsyncIteratorValue(it, idx)])); | ||
try { | ||
const asyncIteratorsValues = new Map(iterators.map((it, idx) => [idx, getNextAsyncIteratorValue(it, idx)])); | ||
do { | ||
const { iterator, index } = await Promise.race(asyncIteratorsValues.values()); | ||
if (iterator.done) { | ||
asyncIteratorsValues.delete(index); | ||
} | ||
else { | ||
yield iterator.value; | ||
asyncIteratorsValues.set(index, getNextAsyncIteratorValue(iterators[index], index)); | ||
} | ||
} while (asyncIteratorsValues.size > 0); | ||
} | ||
finally { | ||
// TODO: replace .all with .allSettled | ||
await Promise.all(iterators.map((it) => it.return())); | ||
} | ||
do { | ||
const { iterator, index } = await Promise.race(asyncIteratorsValues.values()); | ||
if (iterator.done) { | ||
asyncIteratorsValues.delete(index); | ||
} | ||
else { | ||
yield iterator.value; | ||
asyncIteratorsValues.set(index, getNextAsyncIteratorValue(iterators[index], index)); | ||
} | ||
} while (asyncIteratorsValues.size > 0); | ||
} | ||
finally { | ||
await Promise.all(iterators.flatMap((it) => (it.return ? [it.return()] : []))); | ||
} | ||
} | ||
module.exports = combineAsyncIterators; |
{ | ||
"name": "combine-async-iterators", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"description": "Combine Multiple Asynchronous Iterators in one (not a sequence)", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node test/test.js" | ||
"test-only": "node --test ./test", | ||
"test": "c8 --all -r html npm run test-only" | ||
}, | ||
"engines": { | ||
"node": ">=12" | ||
"node": ">=16" | ||
}, | ||
@@ -39,8 +40,7 @@ "repository": { | ||
"devDependencies": { | ||
"@slimio/eslint-config": "^4.1.0", | ||
"@slimio/is": "^1.5.1", | ||
"@types/node": "^16.11.6", | ||
"japa": "^4.0.0", | ||
"sinon": "^11.1.2" | ||
"@matteo.collina/tspl": "^0.1.0", | ||
"@nodesecure/eslint-config": "^1.8.0", | ||
"@types/node": "^20.6.0", | ||
"c8": "^8.0.1" | ||
} | ||
} |
@@ -9,6 +9,7 @@ # Combine-async-iterators | ||
> ⚠️ This package was mainly built to work with native Asynchronous Generators (Iterators). | ||
> [!IMPORTANT] | ||
> This package was mainly built to work with native Asynchronous Generators (Iterators). | ||
## Requirements | ||
- [Node.js](https://nodejs.org/en/) version 12 or higher | ||
- [Node.js](https://nodejs.org/en/) version 16 or higher | ||
@@ -27,10 +28,8 @@ ## Getting Started | ||
```js | ||
const { promisify } = require("util"); | ||
const timers = require("node:times/promises"); | ||
const combineAsyncIterators = require("combine-async-iterators"); | ||
const sleep = promisify(setTimeout); | ||
async function* getValues(id) { | ||
for (let count = 0; count < 5; count++) { | ||
await sleep(Math.ceil(Math.random() * 1000)); | ||
await timers.setTimeout(Math.ceil(Math.random() * 1000)); | ||
yield `${id}_${count}`; | ||
@@ -85,4 +84,30 @@ } | ||
## Contributors ✨ | ||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) | ||
<!-- ALL-CONTRIBUTORS-BADGE:END --> | ||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
<!-- prettier-ignore-start --> | ||
<!-- markdownlint-disable --> | ||
<table> | ||
<tbody> | ||
<tr> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fraxken"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt="Thomas.G"/><br /><sub><b>Thomas.G</b></sub></a><br /><a href="https://github.com/fraxken/combine-async-iterators/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/fraxken/combine-async-iterators/issues?q=author%3Afraxken" title="Bug reports">🐛</a> <a href="#security-fraxken" title="Security">🛡️</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Farenheith"><img src="https://avatars.githubusercontent.com/u/5713887?v=4?s=100" width="100px;" alt="Thiago Oliveira Santos"/><br /><sub><b>Thiago Oliveira Santos</b></sub></a><br /><a href="https://github.com/fraxken/combine-async-iterators/commits?author=Farenheith" title="Code">💻</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://leozhang.me"><img src="https://avatars.githubusercontent.com/u/2092654?v=4?s=100" width="100px;" alt="Leo Zhang"/><br /><sub><b>Leo Zhang</b></sub></a><br /><a href="https://github.com/fraxken/combine-async-iterators/issues?q=author%3Aelldritch" title="Bug reports">🐛</a></td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
<!-- markdownlint-restore --> | ||
<!-- prettier-ignore-end --> | ||
<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
## Licence | ||
MIT | ||
Sorry, the diff of this file is not supported yet
9124
4
111
62