import { Lifecycle } from "./Lifecycle" ; import { LifecycleEvent } from "../api/LifecycleEvent" ; import { MessageDispatcher } from "./MessageDispatcher" ; import { safelyCallBack } from "./safelyCallBack" ; private export class LifecycleTransition { private _fromStates : string [ ] = [ ] ; private _dispatcher : MessageDispatcher = new MessageDispatcher ( ) ; private _callbacks : any [ ] = [ ] ; private _name : string ; private _lifecycle : Lifecycle ; private _transitionState : string ; private _finalState : string ; private _preTransitionEvent : string ; private _transitionEvent : string ; private _postTransitionEvent : string ; private _reverse : boolean = false ; param name param lifecycle constructor ( name , lifecycle ) { this . _name = name ; this . _lifecycle = lifecycle ; } param states return public fromStates ( ... states ) { states . forEach ( ( state ) => { this . _fromStates . push ( state ) ; } ) ; return this ; } param transitionState param finalState return public toStates ( transitionState , finalState ) { this . _transitionState = transitionState ; this . _finalState = finalState ; return this ; } param preTransitionEvent param transitionEvent param postTransitionEvent return public withEvents ( preTransitionEvent , transitionEvent , postTransitionEvent ) { this . _preTransitionEvent = preTransitionEvent ; this . _transitionEvent = transitionEvent ; this . _postTransitionEvent = postTransitionEvent ; if ( this . _reverse ) { this . _lifecycle . addReversedEventTypes ( preTransitionEvent , transitionEvent , postTransitionEvent ) ; } return this ; } return public inReverse ( ) { this . _reverse = true ; this . _lifecycle . addReversedEventTypes ( this . _preTransitionEvent , this . _transitionEvent , this . _postTransitionEvent ) ; return this ; } param handler return public addBeforeHandler ( handler ) { this . _dispatcher . addMessageHandler ( this . _name , handler ) ; return this ; } param callback public enter ( callback ? ) { if ( this . _lifecycle . state === this . _finalState ) { if ( callback ) { safelyCallBack ( callback , null , this . _name ) ; } return ; } if ( this . _lifecycle . state === this . _transitionState ) { if ( callback ) { this . _callbacks . push ( callback ) ; } return ; } if ( this . invalidTransition ( ) ) { this . reportError ( "Invalid transition" , [ callback ] ) ; return ; } let initialState = this . _lifecycle . state ; if ( callback ) { this . _callbacks . push ( callback ) ; } this . setState ( this . _transitionState ) ; this . _dispatcher . dispatchMessage ( this . _name , ( error ) : void => { if ( error ) { this . setState ( initialState ) ; this . reportError ( error , this . _callbacks ) ; return ; } this . dispatch ( this . _preTransitionEvent ) ; this . dispatch ( this . _transitionEvent ) ; this . setState ( this . _finalState ) ; let callbacks = this . _callbacks . concat ( ) ; this . _callbacks . length = 0 ; callbacks . forEach ( ( callbackChild ) => { safelyCallBack ( callbackChild , null , this . _name ) ; } ) ; this . dispatch ( this . _postTransitionEvent ) ; } , this . _reverse ) ; } private invalidTransition ( ) { return this . _fromStates . length > 0 && this . _fromStates . indexOf ( this . _lifecycle . state ) === - 1 ; } private setState ( state ) { if ( state ) { this . _lifecycle . setCurrentState ( state ) ; } } private dispatch ( type ) { if ( type && this . _lifecycle . hasEventListener ( type ) ) { this . _lifecycle . dispatchEvent ( new LifecycleEvent ( type ) ) ; } } private reportError ( message , callbacks ? ) { let error = message instanceof Error ? < Error > message : new Error ( message ) ; if ( this . _lifecycle . hasEventListener ( LifecycleEvent . ERROR ) ) { let event = new LifecycleEvent ( LifecycleEvent . ERROR , error ) ; this . _lifecycle . dispatchEvent ( event ) ; if ( callbacks ) { callbacks . forEach ( ( callback ) => { if ( callback ) { safelyCallBack ( callback , error , this . _name ) ; } } ) ; callbacks . length = 0 ; } } else { throw error ; } } }