abstract class TransformIterable { protected transformers: ((value: T, previous: T | undefined) => R)[] = []; constructor(protected iterable: Iterable) { } public abstract pipe

(transformer: (value: Exclude, previous: T | undefined) => P): any public [Symbol.iterator](): Iterator> { const iterator = this.iterable[Symbol.iterator](); let hasNext = true; return { next: (): any => { let previous: R | undefined = undefined; while (hasNext) { const nextValue = iterator.next(); let value: R = nextValue.value; if (nextValue.done) { hasNext = false; return { done: true, value: undefined }; } let shouldYield = true; for (const transformer of this.transformers) { const result = transformer( value as unknown as T, previous as T, ); if (result === undefined) { shouldYield = false; break; } value = result; } if (!shouldYield) continue; previous = value; return { done: false, value: value }; } return { done: true, value: undefined }; }, }; } } /** @internalexport */ export class IterableTransformer extends TransformIterable { constructor(iterable: Iterable, transformers: ((value: T) => R)[]) { super(iterable); this.transformers.push(...transformers); } public pipe

(transformer: (value: Exclude, previous: T | undefined) => P) { const iterable = this.iterable; return new IterableTransformer(iterable as any, [ ...this.transformers, transformer as any ]); } public toArray() { return [ ...this ]; } } /** @internalexport */ export class IterablePipeline extends TransformIterable { constructor(iterable: Iterable, transformers: ((value: T) => R)[]) { super(iterable); this.transformers.push(...transformers); } public pipe

(transformer: (value: Exclude, previous: T | undefined) => P) { const iterable = this.iterable; return new IterablePipeline(iterable as any, [ ...this.transformers, transformer as any ]); } public toPipeline() { return (iterable: Iterable) => { return new IterableTransformer(iterable, this.transformers as any).toArray(); }; } } type Unwrap> = T extends Iterable ? U : never; export function iterate>(): IterablePipeline, unknown> export function iterate>(iterable: T): IterableTransformer, unknown> export function iterate(iterable?: any): any { if (iterable) return new IterableTransformer(iterable, []); return new IterablePipeline([], []); }