import { isDevMode } from '@angular/core' ; import { MonoTypeOperatorFunction , UnaryFunction , Observable , of } from 'rxjs' ; import { map , filter , mergeMap } from 'rxjs/operators' ; import { pipeFromArray } from 'rxjs/internal/util/pipe' ; import { Action } from '@ngrx/store' ; import { TypedActionWithCorrelation } from './correlate-action' ; export function correlate < T , A > ( fn1 ) ; export function correlate < T , A , B > ( fn1 , fn2 ) ; export function correlate < T , A , B , C > ( fn1 , fn2 , fn3 ) ; export function correlate < T , A , B , C , D > ( fn1 , fn2 , fn3 , fn4 ) ; export function correlate < T , A , B , C , D , E > ( fn1 , fn2 , fn3 , fn4 , fn5 ) ; export function correlate < T , A , B , C , D , E , F > ( fn1 , fn2 , fn3 , fn4 , fn5 , fn6 ) ; export function correlate < T , A , B , C , D , E , F , G > ( fn1 , fn2 , fn3 , fn4 , fn5 , fn6 , fn7 ) ; export function correlate < T , A , B , C , D , E , F , G , H > ( fn1 , fn2 , fn3 , fn4 , fn5 , fn6 , fn7 , fn8 ) ; export function correlate < T , A , B , C , D , E , F , G , H , I > ( fn1 , fn2 , fn3 , fn4 , fn5 , fn6 , fn7 , fn8 , fn9 ) ; export function correlate < T , A , B , C , D , E , F , G , H , I > ( fn1 , fn2 , fn3 , fn4 , fn5 , fn6 , fn7 , fn8 , fn9 , ... fns ) ; export function correlate < R extends TypedActionWithCorrelation < string > | Action > ( ... operators ) { if ( operators . length === 0 ) { throw new TypeError ( 'Expected operators, received nothing' ) ; } return function < A extends Observable < any > > ( stream ) : Observable < R > { return stream . pipe ( mergeMap ( ( trigger ) : Observable < R > => { return of ( trigger ) . pipe ( pipeFromArray ( operators ) , map ( ( out ) : R => { if ( ! isCorrelation ( trigger ) ) { return out ; } const actionWithCorrelation = { ... out , __correlationId : trigger . __correlationId , } ; logCorrelation ( trigger , actionWithCorrelation as TypedActionWithCorrelation < string > ) ; return actionWithCorrelation ; } ) ) ; } ) ) ; } ; } export function withSameCorrelationAs < T extends string > ( action ) { return filter ( ( input ) : boolean => input . __correlationId === action . __correlationId ) ; } function isCorrelation ( action ) { return action && '__correlationId' in action ; } /**
 * Can be useful for debugging purposes -
 * Which action triggered another action?
 */ function logCorrelation < T extends TypedActionWithCorrelation < string > = TypedActionWithCorrelation < string > , O extends TypedActionWithCorrelation < string > = TypedActionWithCorrelation < string > > ( trigger , output ) { if ( isDevMode ( ) ) { const correlations = ( window as any ) . _actionCorrelations || { } ; correlations [ trigger . __correlationId ] = ( correlations [ trigger . __correlationId ] || [ trigger ] ) . concat ( output ) ; ( window as any ) . _actionCorrelations = correlations ; } }