export type StateUpdater < T > = ( val : T , bitmask : number ) => void ; export type BitmaskFactory < T > = ( a : T , b : T ) => number ; export interface ContextValueEmitter < T > { register : ( updater : StateUpdater < T > ) => void ; unregister : ( updater : StateUpdater < T > ) => void ; val : ( value ? : T ) => T ; } export function createEmitter < T > ( initialValue , bitmaskFactory ) { let registeredUpdaters = [ ] ; let value = initialValue ; const diff = ( newValue ) => bitmaskFactory ( value , newValue ) | 0 ; return { register ( updater ) { registeredUpdaters . push ( updater ) ; updater ( value , diff ( value ) ) ; } , unregister ( updater ) { registeredUpdaters = registeredUpdaters . filter ( i => i !== updater ) ; } , val ( newValue ? ) { if ( newValue === undefined || newValue == value ) { return value ; } const bitmask = diff ( newValue ) ; value = newValue ; registeredUpdaters . forEach ( up => up ( newValue , bitmask ) ) ; return value ; } } ; } export const noopEmitter = { register ( _ ) { console . warn ( "Consumer used without a Provider" ) ; } , unregister ( _ ) { } , val ( _ ) { } } ;