type Callback = ( event : Event ) => void ; class Emitter { private readonly listeners : { [ type ] : Callback [ ] ; } ; public constructor ( ) { this . listeners = { } ; } public addEventListener ( type , callback ) { if ( ! ( type in this . listeners ) ) { this . listeners [ type ] = [ ] ; } this . listeners [ type ] . push ( callback ) ; } public removeEventListener ( type , callback ) { if ( ! ( type in this . listeners ) ) { return ; } const stack = this . listeners [ type ] ; for ( let i = 0 , l = stack . length ; i < l ; i += 1 ) { if ( stack [ i ] === callback ) { stack . splice ( i , 1 ) ; return ; } } } public dispatchEvent ( event ) { if ( ! ( event . type in this . listeners ) ) { return ; } const debounce = ( callback ) => { setTimeout ( ( ) => callback . call ( this , event ) ) ; } ; const stack = this . listeners [ event . type ] ; for ( let i = 0 , l = stack . length ; i < l ; i += 1 ) { debounce ( stack [ i ] ) ; } } } export class AbortSignal extends Emitter { public aborted : boolean ; public onabort : ( ( event : Event ) => void ) | null ; public constructor ( ) { super ( ) ; this . aborted = false ; this . onabort = null ; } public toString ( ) { return '[object AbortSignal]' ; } public dispatchEvent ( event ) { if ( event . type === 'abort' ) { this . aborted = true ; if ( typeof this . onabort === 'function' ) { this . onabort . call ( this , event ) ; } } super . dispatchEvent ( event ) ; } } export class AbortController { public readonly signal : AbortSignal ; public constructor ( ) { this . signal = new AbortSignal ( ) ; } public abort ( ) { let event ; try { event = new Event ( 'abort' ) ; } catch { if ( typeof document !== 'undefined' ) { event = document . createEvent ( 'Event' ) ; event . initEvent ( 'abort' , false , false ) ; } else { event = { type : 'abort' , bubbles : false , cancelable : false } ; } } this . signal . dispatchEvent ( event as any ) ; } public toString ( ) { return '[object AbortController]' ; } } if ( typeof Symbol !== 'undefined' && Symbol . toStringTag ) { Object . defineProperty ( AbortController . prototype , Symbol . toStringTag , { configurable : true , value : 'AbortController' } ) ; Object . defineProperty ( AbortSignal . prototype , Symbol . toStringTag , { configurable : true , value : 'AbortSignal' } ) ; }