import { Store } from 'vuex' ; import { getGettersProxyFromModule } from '../store/utils/getters-proxy.utils' ; import { AnySimpleStateSelector , AnyStateSelector } from '../store/utils/store-emitters.utils' ; import { debounce } from '../utils/debounce' ; import { forEach } from '../utils/object' ; import { DebouncedFunction , Dictionary } from '../utils/types' ; import { XEvent } from '../wiring/events.types' ; import { AnyXModule } from '../x-modules/x-modules.types' ; import { XBus } from './x-bus.types' ; param xModule - The  XModule to register its Store Emitters.
 *  param bus param store internal export function registerStoreEmitters ( { name , storeEmitters , storeModule } , bus , store ) { const safeGettersProxy = getGettersProxyFromModule ( store . getters , name , storeModule ) ; forEach ( storeEmitters , ( event , stateSelector ) => { const { selector , immediate , filter , ... options } = normalizeStateSelector ( stateSelector , event ) ; const emit = ( value , oldValue ? ) : void => { bus . emit ( event , value , { moduleName : name , oldValue } ) ; } ; const watcherSelector = ( ) : unknown => selector ( store . state . x [ name ] , safeGettersProxy ) ; const debouncedEffect = debounceWatcherEffect ( event , ( newValue , oldValue ) => { if ( filter ( newValue , oldValue ) ) { emit ( newValue , oldValue ) ; } } ) ; store . watch ( watcherSelector , debouncedEffect , options ) ; if ( immediate ) { Promise . resolve ( ) . then ( ( ) => { emit ( watcherSelector ( ) ) ; } ) ; } } ) ; } param event - The  XEvent to emit.
 *  param watcherEffect returns function debounceWatcherEffect ( event , watcherEffect ) { let previousValue = undefined ; let watcherCallback = debounce ( ( newValue , oldValue ) : void => { watcherEffect ( newValue , oldValue ) ; previousValue = undefined ; } , 0 ) ; if ( isSecondLevelEventEmitter ( event ) ) { const previousCallback = watcherCallback ; const debouncedPreviousCallback = debounce ( previousCallback , 0 ) ; watcherCallback = ( ( n , o ) => { previousCallback . cancel ( ) ; debouncedPreviousCallback ( n , o ) ; } ) as DebouncedFunction < any > ; } return ( newValue , oldValue ) => { previousValue = previousValue !== undefined ? previousValue : oldValue ; watcherCallback ( newValue , previousValue ) ; } ; } /**
 * Transforms a  AnySimpleStateSelector into a  AnyStateSelector , and sets
 * default values for its properties.
 *
 *  param stateSelector param event returns A  AnyStateSelector with all the properties set.
 *
 *  internal function normalizeStateSelector ( stateSelector , event ) { const normalizedSelector = isSimpleSelector ( stateSelector ) ? { selector : stateSelector } : stateSelector ; return { deep : false , immediate : false , filter : isSecondLevelEventEmitter ( event ) ? ( newValue , oldValue ) => ! hasPayloadChanged ( newValue , oldValue ) : ( ) => true , ... normalizedSelector } ; } param stateSelector returns internal export function isSimpleSelector ( stateSelector ) { return typeof stateSelector === 'function' ; } const secondLevelEvents = [ /RequestChanged$/ , /UrlStateChanged$/ ] ; /**
 * Function to detect if an  XEvent is a "SecondLevelEvent", to treat it differently.
 *
 *  param event - The name of the  XEvent to check.
 *  returns internal function isSecondLevelEventEmitter ( event ) { return secondLevelEvents . some ( regex => regex . test ( event ) ) ; } /**
 * Function to filter if a payload of an  XEvent has really changed or not. It only
 * compares the first level of fields and not deeply, to avoid CPU consuming task here.
 *
 *  param request1 param request2 returns internal function hasPayloadChanged < T extends Dictionary > ( request1 ? , request2 ? ) { if ( request1 === request2 ) { return true ; } if ( ! request1 || ! request2 ) { return false ; } const keys1 = Object . keys ( request1 ) ; const keys2 = Object . keys ( request2 ) ; if ( keys1 . length !== keys2 . length ) { return false ; } return ! keys1 . some ( key => request1 [ key ] !== request2 [ key ] ) ; }