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 createReducer from './create-reducer'; import middlewares from './middlewares'; 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, // history?: History, // 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, initialState, serviceOptions = {}, middlewares: sideMiddlewares = [], enhancers: sideEnhancers = [], reducers: sideReducers = {}, sagas: sideSagas = [] }) { const sagaOptions = { services: servicesCreator(null, serviceOptions) }; const enhancers = [ applyMiddleware( ...middlewares, ...sideMiddlewares, ...[ ...sagas, ...sideSagas].map(saga => saga(sagaOptions)), ), // 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); // createRouteProps({ // location: LocationDescriptor, // history: History, // routes: Object // }) => Observable return createRouteProps({ routes, location, history }) .map(([ nextLocation, props ]) => ({ nextLocation, props, reducer, store })); }