import { getEventType } from '../../helpers/getEventType/getEventType' ; import { has } from '../../helpers/has/has' ; import { isArray } from '../../helpers/is/isArray/isArray' ; import { createEvent } from '../createEvent/createEvent' ; import { AnyEventCreator , Event , EventCreators } from '../createEvent/createEvent.h' ; import { EventHandler , EventHandlers , Reducer } from './createReducer.h' ; typeparam param initialState param handlers returns { Reducer } export const createReducer = < S = { } > ( initialState , handlers = { } ) : Reducer < S > => { const innerHandlers = Object . assign ( { } , handlers ) ; const reducer = ( state = initialState , event ? ) => { if ( ! event ) { return state ; } if ( ! has ( event . type , innerHandlers ) ) { return state ; } return innerHandlers [ event . type ] ( state , event . payload , event . meta ) ; } ; const resetHandler = ( ) => initialState ; reducer . has = ( eventOrType ) => has ( getEventType ( eventOrType ) , innerHandlers ) ; reducer . on = < P , M > ( eventOrType , handler ) => { if ( isArray ( eventOrType ) ) { eventOrType . forEach ( ( event ) => reducer . on ( event , handler ) ) ; return reducer ; } innerHandlers [ getEventType ( eventOrType ) ] = handler ; return reducer ; } ; reducer . off = ( eventOrType ) => { if ( isArray ( eventOrType ) ) { eventOrType . forEach ( ( event ) => reducer . off ( event ) ) ; return reducer ; } delete innerHandlers [ getEventType ( eventOrType ) ] ; return reducer ; } ; reducer . reset = ( eventOrType ) => { if ( isArray ( eventOrType ) ) { eventOrType . forEach ( ( event ) => reducer . reset ( event ) ) ; return reducer ; } innerHandlers [ getEventType ( eventOrType ) ] = resetHandler ; return reducer ; } ; reducer . createEvents = < T extends string , P > ( model ) => { const eventNames = Object . keys ( model ) as T [ ] ; const events = { } ; eventNames . forEach ( ( eventName ) => { const handler = model [ eventName ] ; const eventCreator = createEvent < any > ( `${ eventName }` ) ; events [ eventName ] = eventCreator ; reducer . on ( eventCreator , handler ) ; } ) ; return events ; } ; return reducer ; } ;