UNPKG

sflow

Version:

sflow is a powerful and highly-extensible library designed for processing and manipulating streams of data effortlessly. Inspired by the functional programming paradigm, it provides a rich set of utilities for transforming streams, including chunking, fil

49 lines (45 loc) 1.35 kB
import type { Awaitable } from "./Awaitable"; type asyncMapOptions = { concurrency?: number; }; /* map a stream by parallel, return them in execute finished order (return faster return first) */ export const asyncMaps: { <T, R>( fn: (x: T, i: number) => Awaitable<R>, options?: { concurrency?: number }, ): TransformStream<T, R>; <T, R>(fn: (x: T, i: number) => Awaitable<R>): TransformStream<T, R>; } = <T, R>( fn: (x: T, i: number) => Awaitable<R>, options: asyncMapOptions = {}, ) => { let i = 0; let tasks = new Map<number, Awaitable<{ id: number; data: R }>>(); return new TransformStream<T, R>({ transform: async (chunk, ctrl) => { const id = i++; // enqueue tasks.set( id, (async function () { return fn(chunk, id); })().then((data) => ({ id, data })), ); // TODO: allow emit on tasks not full // emit fastest when tasks full if (tasks.size >= (options.concurrency ?? Infinity)) { const { id, data } = await Promise.race(tasks.values()); tasks.delete(id); ctrl.enqueue(data); } }, flush: async (ctrl) => { // emit fastest while (tasks.size) { const { id, data } = await Promise.race(tasks.values()); tasks.delete(id); ctrl.enqueue(data); } }, }); };