import 'babel-polyfill' ; import forEach from 'lodash.foreach' ; import { hasFX , fx , StateWithFx } from './helpers' ; import { combineReducers } from './combine-reducers' ; import { StoreEnhancerStoreCreator , Store , Reducer , StoreEnhancer , Action , Dispatch , createStore } from 'redux' ; import { FXReducer , FXHandler , FXParams , RegisteredFXs , QueuedFX , FXStore , StoreCreator , Effects } from './types' ; const reduxDataFX = < S , A extends Action > ( createStore ) => ( reducer , initialState ) : FXStore < S > => { let q = [ ] ; let fx = { } ; const liftReducer = ( reducer ) : Reducer < S > => ( state , action ) => { const result = reducer ( state , action ) ; if ( hasFX ( result ) ) { let { effects , state } = result ; q = q . concat ( effects ) ; return state ; } else { return result ; } } ; const store = createStore ( liftReducer ( reducer ) , initialState ) ; const dispatch = < A extends Action > ( action ) : A => { let res = store . dispatch ( action ) ; while ( q . length > 0 ) { let current = q . shift ( ) ; if ( ! current ) return res ; let { effect , ... params } = current ; if ( fx [ effect ] !== undefined ) { fx [ effect ] ( params , store . getState , store . dispatch ) ; } else { console . warn ( 'Trying to use fx: ' + effect + '. None has been registered. Doing nothing.' ) ; } } return res ; } ; const replaceEffectfulReducer = ( reducer ) => { return store . replaceReducer ( liftReducer ( reducer ) ) ; } ; return { ... store , replaceEffectfulReducer , dispatch , registerFX ( id , handler ) { fx [ id ] = handler ; } } ; } ; const createStoreFx = createStore as StoreCreator ; export { reduxDataFX , fx , createStoreFx as createStore , combineReducers } ;