import { Logger } from 'pino' ; import { HoldingUpdatedArg , AllocationUpdatedArg , ChannelFinalizedArg , ChallengeRegisteredArg , ChainEventSubscriberInterface , } from './types' ; /**
 * This class is a wrapper of ChainEventSubscriberInterface.
 * Purpose - 2 functions can trigger AssetHolder events to be played to ChainEventSubscriberInterface
 *    1. chainservice.getInitialHoldings
 *    2. chainservice.onAssetEvent
 * Some events can be played twice by both functions, order not predictable,
 * this class ensures each event is played once and in the right order
 */ export class EventTracker { private logger : Logger ; private eventRecordFor : Map < string , { blockNumber : number ; logIndex : number ; } > ; private managedSubscriber : ChainEventSubscriberInterface ; constructor ( managedSubscriber , logger ) { this . logger = logger ; this . managedSubscriber = managedSubscriber ; this . logger = logger ; this . eventRecordFor = new Map < string , { blockNumber : number ; logIndex : number ; } > ( ) ; } private isNewEvent ( queue , blockNumber , logIndex ) { const eventRecord = this . eventRecordFor . get ( queue ) ; this . logger . debug ( `EventTracker.isNewEvent: ${ queue }, ${ blockNumber }, ${ logIndex }, ${ JSON . stringify ( eventRecord ) }` ) ; let isNew = false ; if ( ! eventRecord ) { isNew = true ; } else if ( blockNumber > eventRecord . blockNumber ) { isNew = true ; } else if ( blockNumber === eventRecord . blockNumber ) { if ( logIndex > eventRecord . logIndex ) { isNew = true ; } } if ( isNew ) { this . eventRecordFor . set ( queue , { blockNumber : blockNumber , logIndex : logIndex } ) ; this . logger . debug ( 'Event is new' ) ; return true ; } else { this . logger . debug ( 'Event is not new' ) ; return false ; } } holdingUpdated ( arg , blockNumber , logIndex = Number . MAX_SAFE_INTEGER ) { if ( this . isNewEvent ( arg . asset , blockNumber , logIndex ) ) { this . managedSubscriber . holdingUpdated ( arg ) ; } } allocationUpdated ( arg , blockNumber , logIndex ) { if ( this . isNewEvent ( 'AllocationUpdatedQueue' , blockNumber , logIndex ) ) { this . managedSubscriber . allocationUpdated ( arg ) ; } } channelFinalized ( arg ) { this . managedSubscriber . channelFinalized ( arg ) ; } challengeRegistered ( arg ) { this . managedSubscriber . challengeRegistered ( arg ) ; } }