type Init < Args extends any [ ] > = ( emit : Emit < Args > ) => Cleanup ; type Emit < Args extends any [ ] > = ( ... args : Args ) => void ; type Cleanup = ( ) => void ; type Subscriber < Args extends any [ ] > = ( ... args : Args ) => void ; export function createLazyEmitter < Args extends any [ ] > ( init ) { const subscribers = new Set < Subscriber < Args > > ( ) ; let cleanup = 0 ; const emit = ( ... args ) => { subscribers . forEach ( ( subscriber ) => subscriber ( ... args ) ) ; } ; const subscribe = ( subscriber ) => { subscribers . add ( subscriber ) ; if ( cleanup === 0 ) { cleanup = init ( emit ) ; } return ( ) => { subscribers . delete ( subscriber ) ; if ( subscribers . size === 0 ) { ( cleanup as Cleanup ) ( ) ; cleanup = 0 ; } } ; } ; return subscribe ; }