/**
 * Internally used container for a slot (A callback function with a calling context).
 */ class Slot < T = unknown > { public constructor ( public callback , public context ? ) { } public call ( value ) { this . callback . call ( this . context , value ) ; } } /**
 * Light-weight and very fast signal/slot based event system. Just create a signal instance, connect slots
 * (event listeners) to it and then let the signal emit values which are then send to all connected slots.
 * Slots can be methods and it's easy to disconnect them again using the disconnect() method or calling the function
 * returned by connect().
 */ export class Signal < T = void > { private readonly slots : Slot < T > [ ] = [ ] ; private readonly onInit : ( ( signal : Signal < T > ) => ( ( ) => void ) | void ) | null ; private onDone : ( ( signal : Signal < T > ) => void ) | null = null ; param onInit public constructor ( onInit ? ) { this . onInit = onInit ?? null ; } param callback param context return public connect ( callback , context ? ) { if ( this . onInit != null && this . slots . length === 0 ) { this . onDone = this . onInit ( this ) || null ; } this . slots . push ( new Slot ( callback , context ) ) ; return ( ) => this . disconnect ( callback , context ) ; } param callback param context public disconnect ( callback , context ? ) { const index = this . slots . findIndex ( slot => slot . callback === callback && slot . context === context ) ; if ( index >= 0 ) { this . slots . splice ( index , 1 ) ; } if ( this . onDone != null && this . slots . length === 0 ) { this . onDone ( this ) ; this . onDone = null ; } } param value public emit ( value ) { this . slots . forEach ( slot => slot . call ( value ) ) ; } parm return public filter ( predicate ) { return new Signal ( signal => this . connect ( value => { if ( predicate ( value ) ) { signal . emit ( value ) ; } } ) ) ; } param mapper return public map < R > ( mapper ) { return new Signal < R > ( signal => this . connect ( value => { return signal . emit ( mapper ( value ) ) ; } ) ) ; } }