import { pushable } from 'it-pushable' ; import merge from 'it-merge' ; import type * as it from 'it-stream-types' ; export const rawPipe = ( ... fns ) => { let res ; while ( fns . length > 0 ) { res = fns . shift ( ) ( res ) ; } return res ; } ; export const isIterable = ( obj ) : obj is it . Source < any > => { return obj != null && ( typeof obj [ Symbol . asyncIterator ] === 'function' || typeof obj [ Symbol . iterator ] === 'function' || typeof obj . next === 'function' ) ; } ; export const isDuplex = < TSource , TSink = TSource , RSink = Promise < void > > ( obj ) : obj is it . Duplex < TSource , TSink , RSink > => { return obj != null && typeof obj . sink === 'function' && isIterable ( obj . source ) ; } ; const duplexPipelineFn = < TSource > ( duplex ) => { return ( source ) : it . Source < TSource > => { const p = duplex . sink ( source ) ; if ( p . then != null ) { const stream = pushable < TSource > ( ) ; p . then ( ( ) => { stream . end ( ) ; } , ( err ) => { stream . end ( err ) ; } ) ; const sourceWrap = async function * ( ) { yield * duplex . source ; stream . end ( ) ; } ; return merge ( stream , sourceWrap ( ) ) ; } return duplex . source ; } ; } ; export type Source < A > = it . Source < A > | ( ( ) => it . Source < A > ) | it . Duplex < A , any , any > ; export type Transform < A , B > = it . Transform < A , B > | it . Duplex < B , A , any > ; export type Sink < A , B > = it . Sink < A , B > | it . Duplex < A , any , B > ; export function pipe < A > ( first ) ; export function pipe < A , B > ( first , second ) ; export function pipe < A , B , C > ( first , second , third ) ; export function pipe < A , B , C , D > ( first , second , third , fourth ) ; export function pipe < A , B , C , D , E > ( first , second , third , fourth , fifth ) ; export function pipe < A , B , C , D , E , F > ( first , second , third , fourth , fifth , sixth ) ; export function pipe < A , B , C , D , E , F , G > ( first , second , third , fourth , fifth , sixth , seventh ) ; export function pipe < A , B , C , D , E , F , G , H > ( first , second , third , fourth , fifth , sixth , seventh , eighth ) ; export function pipe < A , B , C , D , E , F , G , H , I > ( first , second , third , fourth , fifth , sixth , seventh , eighth , ninth ) ; export function pipe < A , B , C , D , E , F , G , H , I , J > ( first , second , third , fourth , fifth , sixth , seventh , eighth , ninth , tenth ) ; export function pipe ( first , ... rest ) { if ( isDuplex ( first ) ) { const duplex = first ; first = ( ) => duplex . source ; } else if ( isIterable ( first ) ) { const source = first ; first = ( ) => source ; } const fns = [ first , ... rest ] ; if ( fns . length > 1 ) { if ( isDuplex ( fns [ fns . length - 1 ] ) ) { fns [ fns . length - 1 ] = fns [ fns . length - 1 ] . sink ; } } if ( fns . length > 2 ) { for ( let i = 1 ; i < fns . length - 1 ; i ++ ) { if ( isDuplex ( fns [ i ] ) ) { fns [ i ] = duplexPipelineFn ( fns [ i ] ) ; } } } return rawPipe ( ... fns ) ; }