export type HookCallback < T extends any [ ] > = ( ... args : T ) => void ; export class Hook < T extends any [ ] > { protected listeners : Array < HookCallback < T > > = [ ] ; tap ( fn ) { this . listeners . push ( fn ) ; return ( ) => this . revoke ( fn ) ; } revoke ( fn ) { const i = this . listeners . indexOf ( fn ) ; if ( i >= 0 ) this . listeners . splice ( i , 1 ) ; } revokeAll ( ) { this . listeners . splice ( 0 ) ; } call ( ... args ) { for ( const fn of this . listeners ) { fn ( ... args ) ; } } }