import { Callback } from "@siteimprove/alfa-callback" ; import { Emitter } from "@siteimprove/alfa-emitter" ; import { Serializable } from "@siteimprove/alfa-json" ; import * as json from "@siteimprove/alfa-json" ; import { now } from "./now" ; public export class Performance < T > implements AsyncIterable < Performance . Entry < T > > , Serializable < Performance . JSON > { public static of < T = string > ( ) { return new Performance ( ) ; } private readonly _epoch = now ( ) ; private readonly _emitter = Emitter . of < Performance . Entry < T > > ( ) ; private constructor ( ) { } public get epoch ( ) : number { return this . _epoch ; } public now ( ) { return now ( ) - this . _epoch ; } public elapsed ( now ? ) { return now ? now - this . _epoch : this . now ( ) ; } public mark ( data , start = this . now ( ) ) { if ( typeof start !== "number" ) { start = start . start ; } return this . _emit ( Performance . mark ( data , start ) ) ; } public measure ( data , start = this . _epoch , end = this . now ( ) ) { if ( typeof start !== "number" ) { start = start . start ; } if ( typeof end !== "number" ) { end = end . start ; } return this . _emit ( Performance . measure ( data , start , end - start ) ) ; } public on ( listener ) { this . _emitter . on ( listener ) ; } public once ( ) ; public once ( listener ) ; public once ( listener ? ) { if ( listener ) { this . _emitter . once ( listener ) ; return this ; } else { return this . _emitter . once ( ) ; } } public off ( listener ) { this . _emitter . off ( listener ) ; } public asyncIterator ( ) { return this . _emitter . asyncIterator ( ) ; } public [ Symbol . asyncIterator ] ( ) { return this . asyncIterator ( ) ; } public toJSON ( ) { return { } ; } private _emit < E extends Performance . Entry < T > > ( entry ) { this . _emitter . emit ( entry ) ; return entry ; } } public export namespace Performance { export interface JSON { [ key ] : json . JSON ; } export function isPerformance < T > ( value ) { return value instanceof Performance ; } export type Entry < T > = Mark < T > | Measure < T > ; export namespace Entry { export type JSON < T > = Mark . JSON < T > | Measure . JSON < T > ; } export class Mark < T > implements Serializable < Mark . JSON < T > > { public static of < T > ( data , start ) { return new Mark ( data , start ) ; } private readonly _data : T ; private readonly _start : number ; private constructor ( data , start ) { this . _data = data ; this . _start = start ; } public get type ( ) : "mark" { return "mark" ; } public get data ( ) : T { return this . _data ; } public get start ( ) : number { return this . _start ; } public toJSON ( ) { return { type : "mark" , data : Serializable . toJSON ( this . _data ) , start : this . _start , } ; } } export namespace Mark { export interface JSON < T > { [ key ] : json . JSON | undefined ; type : "mark" ; data : Serializable . ToJSON < T > ; start : number ; } export function isMark < T > ( value ) { return value instanceof Mark ; } } export const { of : mark , isMark } = Mark ; export class Measure < T > implements Serializable < Measure . JSON < T > > { public static of < T > ( data , start , duration ) { return new Measure ( data , start , duration ) ; } private readonly _data : T ; private readonly _start : number ; private readonly _duration : number ; private constructor ( data , start , duration ) { this . _data = data ; this . _start = start ; this . _duration = duration ; } public get type ( ) : "measure" { return "measure" ; } public get data ( ) : T { return this . _data ; } public get start ( ) : number { return this . _start ; } public get duration ( ) : number { return this . _duration ; } public toJSON ( ) { return { type : "measure" , data : Serializable . toJSON ( this . _data ) , start : this . _start , duration : this . _duration , } ; } } export namespace Measure { export interface JSON < T > { [ key ] : json . JSON | undefined ; type : "measure" ; data : Serializable . ToJSON < T > ; start : number ; duration : number ; } export function isMeasure < T > ( value ) { return value instanceof Measure ; } } export const { of : measure , isMeasure } = Measure ; }