import { META_KEY } from './types' ; import { findAndCreateStoreMetadata } from './utils' ; import { Observable , Observer , of , throwError } from 'rxjs' ; import { map , shareReplay , catchError , exhaustMap } from 'rxjs/operators' ; import { ActionState } from './action-state' ; import { ActionContext , ActionStatus } from './actions-stream' ; export interface DecoratorActionOptions { type : string ; payload ? : any ; } /**
 * Decorates a method with a action information.
 */ export function Action ( action ? ) { return function ( target , name , descriptor ) { const meta = findAndCreateStoreMetadata ( target ) ; if ( ! action ) { action = { type : name } ; } if ( typeof action === 'string' ) { action = { type : action } ; } const type = action . type ; if ( ! action . type ) { throw new Error ( `Action ${ action . type } is missing a static "type" property` ) ; } const originalFn = descriptor . value ; meta . actions [ type ] = { fn : name , originalFn : originalFn , type } ; descriptor . value = function ( ... args ) { ActionState . changeAction ( `${ target . constructor . name }-${ name }` ) ; let result = originalFn . call ( this , ... args ) ; if ( result instanceof Observable ) { result = result . pipe ( catchError ( error => { return of ( { status : ActionStatus . Errored , action : action , error : error } ) ; } ) , shareReplay ( ) , exhaustMap ( ( result ) => { if ( result && result . status === ActionStatus . Errored ) { return throwError ( result . error ) ; } else { return of ( result ) ; } } ) ) ; result . subscribe ( ) ; } return result ; } ; } ; }