@fbltd/async
Version:
Miscellaneous async utils
45 lines (44 loc) • 1.56 kB
JavaScript
import { symAI } from "../../constants.js";
import { PromiseConfiguration } from "../../promise-configuration.js";
export function raceStream(deps) {
let externalDispose = new PromiseConfiguration();
const [keys, streams] = Object
.entries(deps)
.reduce((acc, [key, dep]) => {
acc[0].push(key);
acc[1].push(dep[symAI]());
return acc;
}, [[], []]);
function isDisposed() {
return streams.some((s) => s.isDisposed);
}
return {
dispose: () => !isDisposed() && externalDispose.resolve({ done: true, value: void 0 }),
get isDisposed() {
return isDisposed();
},
[symAI]() {
const done = { done: true };
return {
next: async () => {
if (externalDispose.isFulfilled)
return done;
const res = await Promise.race([
externalDispose.promise,
...streams.map(s => s.next())
]);
if (externalDispose.isFulfilled)
return done;
externalDispose = new PromiseConfiguration();
if (res.done)
return res;
const value = keys.reduce((acc, key) => {
acc[key] = deps[key].value;
return acc;
}, {});
return { done: false, value };
}
};
}
};
}