import { expect } from '@flood/element-report' ; type TimingRec = { start : number ; end : number ; thinkTime : number ; } ; type TimingSegmentName = 'beforeStep' | 'step' | 'afterStep' ; export class Timing { private segments : Map < TimingSegmentName , TimingRec > ; constructor ( public epoch = new Date ( ) ) { this . segments = new Map ( ) ; } start ( segmentName ) { const now = new Date ( ) . valueOf ( ) ; this . segments . set ( segmentName , { start : now , end : 0 , thinkTime : 0 } ) ; } end ( segmentName ) { const seg = expect ( this . segments . get ( segmentName ) , `No timing started for ${ segmentName }` ) ; const now = new Date ( ) . valueOf ( ) ; seg . end = now ; this . segments . set ( segmentName , seg ) ; } getDurationForSegment ( segmentName , fromNow ? ) { const seg = expect ( this . segments . get ( segmentName ) , `No timing started for ${ segmentName }` ) ; if ( fromNow ) { return new Date ( ) . valueOf ( ) - seg . start ; } return seg . end - seg . start ; } getThinkTimeForSegment ( segmentName ) { const { thinkTime } = expect ( this . segments . get ( segmentName ) , `No timing started for ${ segmentName }` ) ; return thinkTime ; } getDurationWithoutThinkTimeForSegment ( segmentName , fromNow ? ) { return ( this . getDurationForSegment ( segmentName , fromNow ) - this . getThinkTimeForSegment ( segmentName ) ) ; } async measureThinkTime ( segmentName , func , ... args ) { const seg = expect ( this . segments . get ( segmentName ) , `No timing started for ${ segmentName }` ) ; const start = new Date ( ) ; await func . apply ( this , ... args ) ; const end = new Date ( ) ; seg . thinkTime += end . valueOf ( ) - start . valueOf ( ) ; } reset ( ) { this . segments . clear ( ) ; } }