import { AlertInstanceMeta , AlertInstanceState , RawAlertInstance , rawAlertInstance , AlertInstanceContext , DefaultActionGroupId , } from '../../common' ; import { parseDuration } from '../lib' ; interface ScheduledExecutionOptions < State extends AlertInstanceState , Context extends AlertInstanceContext , ActionGroupIds extends string = DefaultActionGroupId > { actionGroup : ActionGroupIds ; subgroup ? : string ; context : Context ; state : State ; } export type PublicAlertInstance < State extends AlertInstanceState = AlertInstanceState , Context extends AlertInstanceContext = AlertInstanceContext , ActionGroupIds extends string = DefaultActionGroupId > = Pick < AlertInstance < State , Context , ActionGroupIds > , 'getState' | 'replaceState' | 'scheduleActions' | 'scheduleActionsWithSubGroup' > ; export class AlertInstance < State extends AlertInstanceState = AlertInstanceState , Context extends AlertInstanceContext = AlertInstanceContext , ActionGroupIds extends string = never > { private scheduledExecutionOptions ? : ScheduledExecutionOptions < State , Context , ActionGroupIds > ; private meta : AlertInstanceMeta ; private state : State ; constructor ( { state , meta = { } } = { } ) { this . state = ( state || { } ) as State ; this . meta = meta ; } hasScheduledActions ( ) { return this . scheduledExecutionOptions !== undefined ; } isThrottled ( throttle ) { if ( this . scheduledExecutionOptions === undefined ) { return false ; } const throttleMills = throttle ? parseDuration ( throttle ) : 0 ; if ( this . meta . lastScheduledActions && this . scheduledActionGroupIsUnchanged ( this . meta . lastScheduledActions , this . scheduledExecutionOptions ) && this . scheduledActionSubgroupIsUnchanged ( this . meta . lastScheduledActions , this . scheduledExecutionOptions ) && this . meta . lastScheduledActions . date . getTime ( ) + throttleMills > Date . now ( ) ) { return true ; } return false ; } scheduledActionGroupOrSubgroupHasChanged ( ) { if ( ! this . meta . lastScheduledActions && this . scheduledExecutionOptions ) { return true ; } if ( this . meta . lastScheduledActions && this . scheduledExecutionOptions ) { return ( ! this . scheduledActionGroupIsUnchanged ( this . meta . lastScheduledActions , this . scheduledExecutionOptions ) || ! this . scheduledActionSubgroupIsUnchanged ( this . meta . lastScheduledActions , this . scheduledExecutionOptions ) ) ; } return false ; } private scheduledActionGroupIsUnchanged ( lastScheduledActions , scheduledExecutionOptions ) { return lastScheduledActions . group === scheduledExecutionOptions . actionGroup ; } private scheduledActionSubgroupIsUnchanged ( lastScheduledActions , scheduledExecutionOptions ) { return lastScheduledActions . subgroup && scheduledExecutionOptions . subgroup ? lastScheduledActions . subgroup === scheduledExecutionOptions . subgroup : true ; } getLastScheduledActions ( ) { return this . meta . lastScheduledActions ; } getScheduledActionOptions ( ) { return this . scheduledExecutionOptions ; } unscheduleActions ( ) { this . scheduledExecutionOptions = undefined ; return this ; } getState ( ) { return this . state ; } scheduleActions ( actionGroup , context = { } as Context ) { this . ensureHasNoScheduledActions ( ) ; this . scheduledExecutionOptions = { actionGroup , context , state : this . state , } ; return this ; } scheduleActionsWithSubGroup ( actionGroup , subgroup , context = { } as Context ) { this . ensureHasNoScheduledActions ( ) ; this . scheduledExecutionOptions = { actionGroup , subgroup , context , state : this . state , } ; return this ; } private ensureHasNoScheduledActions ( ) { if ( this . hasScheduledActions ( ) ) { throw new Error ( 'Alert instance execution has already been scheduled, cannot schedule twice' ) ; } } replaceState ( state ) { this . state = state ; return this ; } updateLastScheduledActions ( group , subgroup ? ) { this . meta . lastScheduledActions = { group , subgroup , date : new Date ( ) } ; } /**
     * Used to serialize alert instance state
     */ toJSON ( ) { return rawAlertInstance . encode ( this . toRaw ( ) ) ; } toRaw ( ) { return { state : this . state , meta : this . meta , } ; } }