@thi.ng/transducers-async
Version:
Async versions of various highly composable transducers, reducers and iterators
55 lines (54 loc) • 1.33 kB
JavaScript
import { __inflightIters, __iterNext, __iterRemove } from "./internal/iter.js";
async function* sync(src, opts) {
let iters = Object.entries(src).map(([key, v], id) => ({
key,
id,
iter: v[Symbol.asyncIterator]()
}));
const $initial = async () => {
const res = await Promise.all(iters.map(({ iter }) => iter.next()));
for (let i = 0, n = iters.length; i < n; ) {
if (res[i].done) {
res.splice(i, 1);
if (__iterRemove(iters, i)) return;
n--;
} else i++;
}
return res.reduce(
(acc, x, i) => (acc[iters[i].key] = x.value, acc),
{}
);
};
if (opts?.reset) {
let tuple;
let curr;
while (curr = await $initial()) {
tuple = { ...tuple, ...curr };
yield tuple;
}
} else {
let tuple;
if (opts?.mergeOnly) {
tuple = {};
} else {
tuple = await $initial();
if (!tuple) return;
yield { ...tuple };
}
const promises = __inflightIters(iters);
while (true) {
const { iter, res } = await Promise.race(promises);
if (res.done) {
promises.splice(iter.id, 1);
if (__iterRemove(iters, iter.id)) return;
} else {
tuple[iter.key] = res.value;
yield { ...tuple };
__iterNext(promises, iter);
}
}
}
}
export {
sync
};