import { Observable } from 'rx'; import { match } from 'react-router'; import { compose, createStore, applyMiddleware } from 'redux'; // main app import App from './App.jsx'; // app routes import childRoutes from './routes'; // redux import { createEpic } from 'redux-epic'; import createReducer from './create-reducer'; import sagas from './sagas'; // general utils import servicesCreator from '../utils/services-creator'; const createRouteProps = Observable.fromNodeCallback(match); const routes = { components: App, ...childRoutes }; // // createApp(settings: { // location?: Location|String, // history?: History, // syncHistoryWithStore?: ((history, store) => history) = (x) => x, // initialState?: Object|Void, // serviceOptions?: Object, // middlewares?: Function[], // sideReducers?: Object // enhancers?: Function[], // sagas?: Function[], // }) => Observable // // Either location or history must be defined export default function createApp({ location, history, syncHistoryWithStore = (x) => x, syncOptions = {}, initialState, serviceOptions = {}, middlewares: sideMiddlewares = [], enhancers: sideEnhancers = [], reducers: sideReducers = {}, sagas: sideSagas = [], sagaOptions: sideSagaOptions = {} }) { const sagaOptions = { ...sideSagaOptions, services: servicesCreator(null, serviceOptions) }; const sagaMiddleware = createEpic( sagaOptions, ...sagas, ...sideSagas ); const enhancers = [ applyMiddleware( ...sideMiddlewares, sagaMiddleware ), // enhancers must come after middlewares // on client side these are things like Redux DevTools ...sideEnhancers ]; const reducer = createReducer(sideReducers); // create composed store enhancer // use store enhancer function to enhance `createStore` function // call enhanced createStore function with reducer and initialState // to create store const store = compose(...enhancers)(createStore)(reducer, initialState); // sync history client side with store. // server side this is an identity function and history is undefined history = syncHistoryWithStore(history, store, syncOptions); // createRouteProps({ // redirect: LocationDescriptor, // history: History, // routes: Object // }) => Observable return createRouteProps({ routes, location, history }) .map(([ redirect, props ]) => ({ redirect, props, reducer, store, epic: sagaMiddleware })); }