UNPKG

@johngw/stream

Version:

Reactive programming tools using the WHATWG Streams API.

72 lines (65 loc) 1.75 kB
import { isArrayLike, isAsyncIterable, isIterable, } from '@johngw/stream-common/Object' /** * Deeply flattens `Iterable`s, `AsyncIterable`s & `ArrayLike`s. * * @group Transformers * @example * ``` * --[1]--2----[3,[4]]---| * * flat() * * --1----2-----3-4------| * ``` */ export function flat<T>() { return new TransformStream(new FlatTransformer<T>()) } type Flattened<T> = T extends string ? T : T extends ArrayLike<infer V> ? Flattened<V> : T extends Iterable<infer V> ? Flattened<V> : T extends AsyncIterable<infer V> ? Flattened<V> : T class FlatTransformer<T> implements Transformer<T, Flattened<T>> { transform( chunk: T, controller: TransformStreamDefaultController<Flattened<T>> ) { return typeof chunk === 'string' ? controller.enqueue(chunk as Flattened<T>) : isIterable<T>(chunk) ? this.#transformIterator(chunk, controller) : isAsyncIterable<T>(chunk) ? this.#transformAsyncIterator(chunk, controller) : isArrayLike<T>(chunk) ? this.#transformArrayLike(chunk, controller) : controller.enqueue(chunk as Flattened<T>) } async #transformIterator( chunk: Iterable<T>, controller: TransformStreamDefaultController<Flattened<T>> ) { for (const x of chunk) await this.transform(x, controller) } async #transformAsyncIterator( chunk: AsyncIterable<T>, controller: TransformStreamDefaultController<Flattened<T>> ) { for await (const x of chunk) await this.transform(x, controller) } async #transformArrayLike( chunk: ArrayLike<T>, controller: TransformStreamDefaultController<Flattened<T>> ) { for (let i = 0; i < chunk.length; i++) await this.transform(chunk[i], controller) } }