import { createEvent } from '../createEvent/createEvent' ; import type { AnyEventCreator } from '../createEvent/createEvent.h' ; import type { EventHandler , Reducer } from './createReducer.h' ; import { SimpleEmitter } from '../stores/SimpleEmitter' ; export function createReducer < State = { } , Name extends string = string > ( name , initialState ) { const reducers = { } ; return class ReducerStore extends SimpleEmitter { static storeName = name ; private state : State ; constructor ( ) { super ( ) ; this . state = initialState ; } static handlers : Record < string , string > = { } ; static 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 < P > ( `${ eventName }` ) ; events [ eventName ] = eventCreator ; ReducerStore . on ( eventCreator , handler ) ; } ) ; return events ; } static on < P > ( eventOrType , reducer ) { if ( Array . isArray ( eventOrType ) ) { eventOrType . forEach ( ( event ) => ReducerStore . on ( event , reducer ) ) ; return ReducerStore ; } const type = eventOrType . toString ( ) ; ReducerStore . handlers [ type ] = 'handle' ; reducers [ type ] = reducer ; return ReducerStore ; } getState ( ) { return this . state ; } setState ( state ) { this . state = state ; this . emit ( 'change' ) ; } dehydrate ( ) { return this . state ; } rehydrate ( state ) { this . state = state ; } handle ( payload , eventName ) { const reducer = reducers [ eventName ] ; if ( reducer ) { this . state = reducer ( this . state , payload ) ; this . emit ( 'change' ) ; } } } ; }