UNPKG

stream-chain

Version:

Chain functions as transform streams.

283 lines (267 loc) 7.09 kB
/// <reference types="node" /> import {Duplex, DuplexOptions, Readable, Transform, Writable} from 'node:stream'; import {TypedDuplex, TypedReadable, TypedTransform, TypedWritable} from './typed-streams'; import { none, stop, Stop, finalSymbol, finalValue, final, isFinalValue, getFinalValue, manySymbol, many, isMany, getManyValues, getFunctionList, flushSymbol, flushable, isFlushable, fListSymbol, isFunctionList, setFunctionList, clearFunctionList, toMany, normalizeMany, combineMany, combineManyMut, type AsFlatList, type Fn, type OutputType } from './defs'; import gen from './gen'; import asStream from './asStream'; export = chain; /** * Represents a typed duplex stream as a pair of readable and writable streams. */ export type DuplexStream<W = any, R = any> = { readable: ReadableStream<R>; writable: WritableStream<W>; }; /** * Options for the chain function, which is based on `DuplexOptions`. */ export interface ChainOptions extends DuplexOptions { /** If `true`, no groupings will be done. Each function will be a separate stream object. */ noGroupings?: boolean; /** If `true`, event bindings to the chain stream object will be skipped. */ skipEvents?: boolean; } /** * The tuple type for a chain function with one item. */ type ChainSteams1 = [Readable | Writable | Duplex | Transform]; /** * The tuple type for a chain function with multiple items. */ type ChainSteams = [ Readable | Duplex | Transform, ...(Duplex | Transform)[], Writable | Duplex | Transform ]; /** * Represents the output of the chain function. It is based on `Duplex` with extra properties. */ export interface ChainOutput<W, R> extends Duplex { /** Internal list of streams. */ streams: ChainSteams1 | ChainSteams; /** The first stream, which can be used to feed the chain and to attach event handlers. */ input: Readable | Writable | Duplex | Transform; /** The last stream, which can be used to consume results and to attach event handlers. */ output: Readable | Writable | Duplex | Transform; } /** * Returns the first argument of a chain, a stream, or a function. */ export type Arg0<F> = F extends TypedTransform<infer W, any> ? W : F extends TypedDuplex<infer W, any> ? W : F extends TypedReadable<any> ? never : F extends TypedWritable<infer W> ? W : F extends Writable | Transform | Duplex ? any : F extends Readable ? never : F extends TransformStream<infer W, any> ? W : F extends DuplexStream<infer W, any> ? W : F extends WritableStream<infer W> ? W : F extends ReadableStream<any> ? never : F extends readonly unknown[] ? AsFlatList<F> extends readonly [infer F1, ...(readonly unknown[])] ? Arg0<F1> : AsFlatList<F> extends readonly [] ? any : AsFlatList<F> extends readonly (infer F1)[] ? Arg0<F1> : never : F extends (...args: readonly any[]) => unknown ? Parameters<F>[0] : never; /** * Returns the return type of a chain, a stream, or a function. */ export type Ret<F, Default = any> = F extends TypedTransform<any, infer R> ? R : F extends TypedDuplex<any, infer R> ? R : F extends TypedReadable<infer R> ? R : F extends TypedWritable<any> ? never : F extends Readable | Transform | Duplex ? any : F extends Writable ? never : F extends TransformStream<any, infer R> ? R : F extends DuplexStream<any, infer R> ? R : F extends ReadableStream<infer R> ? R : F extends WritableStream<any> ? never : F extends readonly unknown[] ? AsFlatList<F> extends readonly [...unknown[], infer F1] ? Ret<F1, Default> : AsFlatList<F> extends readonly [] ? Default : AsFlatList<F> extends readonly (infer F1)[] ? Ret<F1, Default> : never : F extends Fn ? OutputType<F> : never; /** * Represents an item in the chain function. * It is used to highlight mismatches between argument types and return types in a list. */ export type ChainItem<I, F> = F extends TypedTransform<infer W, infer R> ? I extends W ? F : TypedTransform<I, R> : F extends TypedDuplex<infer W, infer R> ? I extends W ? F : TypedDuplex<I, R> : F extends TypedReadable<any> ? [I] extends [never] ? F : never : F extends TypedWritable<infer W> ? I extends W ? F : TypedWritable<I> : F extends Writable | Transform | Duplex ? F : F extends Readable ? [I] extends [never] ? F : never : F extends TransformStream<infer W, infer R> ? I extends W ? F : TransformStream<I, R> : F extends DuplexStream<infer W, infer R> ? I extends W ? F : DuplexStream<I, R> : F extends ReadableStream<any> ? [I] extends [never] ? F : never : F extends WritableStream<infer W> ? I extends W ? F : WritableStream<I> : F extends readonly [infer F1, ...infer R] ? F1 extends (null | undefined) ? readonly [F1, ...ChainList<I, R>] : readonly [ChainItem<I, F1>, ...ChainList<Ret<F1, I>, R>] : F extends readonly unknown[] ? readonly [ChainItem<I, any>] : F extends Fn ? I extends Arg0<F> ? F : (arg: I, ...rest: readonly unknown[]) => ReturnType<F> : never; /** * Replicates a tuple verifying the types of the list items so arguments match returns. * The replicated tuple is used to highlight mismatches between list items. */ export type ChainList<I, L> = L extends readonly [infer F1, ...infer R] ? F1 extends (null | undefined) ? readonly [F1, ...ChainList<I, R>] : readonly [ChainItem<I, F1>, ...ChainList<Ret<F1, I>, R>] : L; /** * Takes a function or an iterable and returns the underlying function. * @param fn function or iterable * @returns the underlying function * @remarks In the case of a function, it returns the argument. For iterables it returns the function associated with `Symbol.iterator` or `Symbol.asyncIterator`. */ declare function dataSource<F>( fn: F ): F extends AsyncIterable<infer T> ? () => AsyncIterator<T> : F extends Iterable<infer T> ? () => Iterator<T> : F extends Fn ? F : never; /** * Creates a stream object out of a list of functions and streams. * @param fns array of functions, streams, or other arrays * @returns a duplex stream with additional properties * @remarks This is the main function of this library. */ declare function chain<L extends readonly unknown[]>( ...fns: ChainList<Arg0<L>, L>, options?: ChainOptions ): ChainOutput<Arg0<L>, Ret<L>>; declare function chainUnchecked<W = any, R = any>( fns: readonly any[], options?: ChainOptions ): ChainOutput<W, R>; declare namespace chain { export { none, stop, Stop, finalSymbol, finalValue, final, isFinalValue, getFinalValue, manySymbol, many, isMany, getManyValues, getFunctionList, flushSymbol, flushable, isFlushable, fListSymbol, isFunctionList, setFunctionList, clearFunctionList, toMany, normalizeMany, combineMany, combineManyMut, chain, chainUnchecked, gen, asStream, dataSource }; }