UNPKG

stream-chain

Version:

Chain functions, generators, Node streams, and Web streams into a pipeline with backpressure support.

360 lines (336 loc) 11.6 kB
/** * Special symbol that indicates that a function produced no value. * Effectively, the rest of the pipeline is not used. */ export declare const none: unique symbol; /** * Special symbol that indicates that the pipeline should be stopped. * Just like {@link none}, it produces no value. */ export declare const stop: unique symbol; /** Used internally to mark a value as a final value. */ export declare const finalSymbol: unique symbol; /** Used internally to mark a value as multiple values. */ export declare const manySymbol: unique symbol; /** Used internally to mark a function as capable of being flushed. */ export declare const flushSymbol: unique symbol; /** Used internally to mark a function as being derived from a function list. */ export declare const fListSymbol: unique symbol; /** * An exception that indicates that the pipeline should be stopped. */ export declare class Stop extends Error {} /** * Interface for a value that has been marked as a final value. */ export interface FinalValue<T = unknown> { [finalSymbol]: 1; value: T; } /** * Type predicate for `FinalValue`. * @param o object to test * @returns `true` if `o` is a `FinalValue` */ export declare function isFinalValue(o: unknown): o is FinalValue; /** * Creates a `FinalValue` * @param value the wrapped value * @returns a `FinalValue` */ export declare function finalValue<T>(value: T): FinalValue<T>; /** * Retrieves the value of a `FinalValue` * @param o a `FinalValue` object * @returns the wrapped value */ export declare function getFinalValue<T>(o: FinalValue<T>): T; /** * Alias for {@link finalValue} */ export declare const final: typeof finalValue; /** * Interface for a value that has been marked as multiple values. * It is used to return multiple values from a regular (non-generator) function. */ export interface Many<T = unknown> { [manySymbol]: 1; values: T[]; } /** * Type predicate for `Many`. * @param o object to test * @returns `true` if `o` is a `Many` */ export declare function isMany(o: unknown): o is Many; /** * Creates a `Many` * @param values the wrapped values * @returns a `Many` */ export declare function many<T>(values: T[]): Many<T>; /** * Retrieves the values of a `Many` * @param o a `Many` object * @returns the wrapped values */ export declare function getManyValues<T>(o: Many<T>): T[]; /** * Interface for a function that can be flushed. * If it is marked as flushable, it will be called with the special {@link none} value * when the pipeline is stopped so it can produce the last value. */ export interface Flushable<I = unknown, O = unknown> { (value: I, ...rest: any[]): O; [flushSymbol]: 1; } /** * Type predicate for `Flushable`. * @param o function to test * @returns `true` if `o` is a `Flushable` */ export declare function isFlushable<I, O>(o: (value: I, ...rest: any[]) => O): o is Flushable<I, O>; /** * Creates a `Flushable` * @param write function to be marked as flushable * @param final an optional function to be called when the pipeline is stopped * @returns a `Flushable` * @remarks If `final` is not provided, `write` will be called with {@link none} when the pipeline is stopped */ export declare function flushable<I, O>( write: (value: I, ...rest: any[]) => O, final?: () => O ): Flushable<I, O>; /** * Interface for a function that can be derived from a function list. * `chain` can use the list instead of the original function. */ export interface FunctionList< T extends (...args: readonly any[]) => unknown, I = unknown, O = unknown > { (value: I, ...rest: any[]): O; [fListSymbol]: 1; fList: T[]; } /** * Type predicate for `FunctionList`. * @param o function to test * @returns `true` if `o` is a `FunctionList` */ export declare function isFunctionList<I, O>( o: (value: I, ...rest: readonly any[]) => O ): o is FunctionList<(...args: readonly any[]) => unknown, I, O>; /** * Sets a function list creating a `FunctionList` structure. * @param o function to be marked as a function list * @param fns function list * @returns `o` as a `FunctionList` */ export declare function setFunctionList< T extends (...args: readonly any[]) => unknown, F extends (...args: readonly any[]) => unknown >( o: F, fns: T[] ): F extends (value: infer I, ...rest: any[]) => infer O ? FunctionList<T, I, O> : never; /** * Retrieves the function list of a `FunctionList` * @param o a `FunctionList` object * @returns the function list */ export declare function getFunctionList< T extends (...args: readonly any[]) => unknown, I = unknown, O = unknown >(o: FunctionList<T, I, O>): T[]; /** * Clears the function list from a `FunctionList` * @param o a `FunctionList` object * @returns `o` as a `FunctionList` */ export declare function clearFunctionList< T extends (...args: readonly any[]) => unknown, I = unknown, O = unknown >(o: FunctionList<T, I, O>): (value: I, ...rest: any[]) => O; /** * Convert a value to `Many`. * @param value the value to convert * @returns a `Many` containing the value * @remarks `Many` is used to return multiple values from a regular (non-generator) function. */ export declare function toMany<T>(value: Many<T>): Many<T>; export declare function toMany(value: typeof none): Many<never>; export declare function toMany<T>(value: T): Many<T>; /** * Normalize a value by unbundling it if it is a `Many`. * @param value the value to normalize * @returns the normalized value */ export declare function normalizeMany(value: unknown): unknown; /** * Extracts the element type from a `combineMany`/`combineManyMut` argument. * `none` contributes nothing, `Many<T>` contributes `T`, anything else contributes itself. */ export type CombineManyItem<T> = T extends typeof none ? never : T extends Many<infer U> ? U : T; /** * Combine values into a `Many`. * @param args values to combine * @returns a `Many` containing all values */ export declare function combineMany<T extends unknown[]>( ...args: T ): Many<CombineManyItem<T[number]>>; /** * Combine values into a `Many` mutably. * @param a the first value (may be modified in-place if it is a `Many`) * @param args additional values to combine * @returns a `Many` containing all values * @remarks only the first argument may be modified in-place */ export declare function combineManyMut<A, T extends unknown[]>( a: A, ...args: T ): Many<CombineManyItem<A> | CombineManyItem<T[number]>>; // Stream type guards (Web + Node, shape-based — neither imports `node:stream`) /** * Type predicate for a Web Streams `ReadableStream`. Shape-based — checks for * `getReader` and `pipeTo` methods, which Node Streams do not expose. */ export declare function isReadableWebStream(x: unknown): x is ReadableStream; /** * Type predicate for a Web Streams `WritableStream`. Shape-based — checks for * `getWriter` and `abort` methods, which Node Streams do not expose. */ export declare function isWritableWebStream(x: unknown): x is WritableStream; /** * Type predicate for a Web Streams duplex pair `{readable, writable}` (the * shape returned by `TransformStream` and `asWebStream`). */ export declare function isDuplexWebStream( x: unknown ): x is {readable: ReadableStream; writable: WritableStream}; /** * Type predicate for a Node `Readable` (including `Duplex`/`Transform`). * Shape-based — checks for `.pipe` / `.on` and `_readableState`. Does not * import `node:stream`, so browser-safe to call. */ export declare function isReadableNodeStream(x: unknown): boolean; /** * Type predicate for a Node `Writable` (including `Duplex`/`Transform`). * Shape-based — checks for `.write` / `.on` and `_writableState`. */ export declare function isWritableNodeStream(x: unknown): boolean; /** * Type predicate for a Node `Duplex`/`Transform`. Shape-based — combines the * readable and writable checks plus the `_readableState` marker. */ export declare function isDuplexNodeStream(x: unknown): boolean; // generic utilities: unpacking types /** * Generic utility for getting the return type of a function including async and generators. * Naked-T conditional so it distributes over unions — needed when a function returns a * shape like `Many<R> | Promise<Many<R>>` (the surface of `fun(...)`'s output). Without * distribution the whole-union `extends Promise<unknown>` test fails on `Many<R>` alone, * `Promise<Many<R>>` falls through unwrapped, and the inner `Many` leaks downstream. */ export type UnpackReturnType<F extends (...args: readonly any[]) => unknown> = UnpackReturnTypeOf< ReturnType<F> >; type UnpackReturnTypeOf<T> = T extends AsyncGenerator<infer O, unknown, unknown> ? O : T extends Generator<infer O, unknown, unknown> ? O : T extends Promise<infer U> ? UnpackReturnTypeOf<U> : T; /** * `stream-chain`-specific utility for getting the type from functions used in a function list. */ export type UnpackType<T> = T extends Many<infer U> ? U : T extends FinalValue<infer U> ? U : Exclude<T, typeof none | typeof stop>; /** * Unpacking the return type of a function as a combination of {@link UnpackType} and {@link UnpackReturnType}. */ export type OutputType<F extends (...args: readonly any[]) => unknown> = UnpackType< UnpackReturnType<F> >; // generic utilities: working with tuples /** * Returns the first element of a tuple or `never`. */ export type First<L extends readonly unknown[]> = L extends readonly [ infer T, ...(readonly unknown[]) ] ? T : never; /** * Returns the last element of a tuple or `never`. */ export type Last<L extends readonly unknown[]> = L extends readonly [ ...(readonly unknown[]), infer T ] ? T : never; /** * Flattens a tuple of tuples recursively returning a flat tuple. */ export type Flatten<L extends readonly unknown[]> = L extends readonly [infer T, ...infer R] ? T extends readonly unknown[] ? readonly [...Flatten<T>, ...Flatten<R>] : readonly [T, ...Flatten<R>] : L; /** * Filters a tuple removing all elements of a specified type returning a filtered tuple. */ export type Filter<L extends readonly unknown[], X> = L extends readonly [infer T, ...infer R] ? T extends X ? Filter<R, X> : readonly [T, ...Filter<R, X>] : L; /** * Flattens and filters a tuple. See {@link Flatten} and {@link Filter}. */ export type AsFlatList<L extends readonly unknown[]> = Filter<Flatten<L>, null | undefined>; // generic utilities: working with functions /** * A generic one-argument function. Used internally. */ export type Fn = (arg: any, ...args: readonly unknown[]) => unknown; /** * Returns the first argument of a function or a function list or `never`. */ export type Arg0<F> = F extends readonly unknown[] ? AsFlatList<F> extends readonly [infer F1, ...(readonly unknown[])] ? Arg0<F1> : AsFlatList<F> extends readonly [] ? unknown : AsFlatList<F> extends readonly (infer F1)[] ? Arg0<F1> : never : F extends (...args: readonly any[]) => unknown ? Parameters<F>[0] : never; /** * Returns the unpacked return type of a function or a function list or `never`. */ export type Ret<F, Default = unknown> = 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;