diff --git a/package.json b/package.json index 9bc8a9e184..87280d8fea 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "react-select": "1.0.0-rc.1", "react-transform-catch-errors": "1.0.2", "redbox-react": "1.2.4", - "redux-devtools": "3.1.1", + "redux-devtools": "3.3.2", "redux-devtools-dock-monitor": "1.1.1", "redux-devtools-log-monitor": "1.0.11", "redux-immutable-state-invariant": "1.2.3", @@ -130,12 +130,14 @@ "react-spinkit": "1.1.6", "react-swipeable-views": "0.6.3", "react-widgets": "3.1.7", - "redux": "3.1.3", + "redux": "3.6.0", "redux-logger": "2.6.1", + "redux-observable": "0.13.0", "redux-persist": "3.1.1", "redux-thunk": "0.1.0", "redux-undo": "0.5.0", "reselect": "2.5.1", + "rxjs": "5.1.1", "shpjs": "3.3.2", "turf-bbox": "3.0.10", "turf-buffer": "3.0.10", diff --git a/web/client/stores/StandardStore.js b/web/client/stores/StandardStore.js index 5ee43d734a..90f07dfe7b 100644 --- a/web/client/stores/StandardStore.js +++ b/web/client/stores/StandardStore.js @@ -15,11 +15,12 @@ const layers = require('../reducers/layers'); const mapConfig = require('../reducers/config'); const DebugUtils = require('../utils/DebugUtils'); -const {combineReducers} = require('../utils/PluginsUtils'); +const {combineReducers, combineEpics} = require('../utils/PluginsUtils'); const LayersUtils = require('../utils/LayersUtils'); const {CHANGE_BROWSER_PROPERTIES} = require('../actions/browser'); const {persistStore, autoRehydrate} = require('redux-persist'); +const {createEpicMiddleware} = require('redux-observable'); const SecurityUtils = require('../utils/SecurityUtils'); @@ -35,9 +36,10 @@ module.exports = (initialState = {defaultState: {}, mobile: {}}, appReducers = { mapInitialConfig: () => {return null; }, layers: () => {return null; } }); + const rootEpic = combineEpics(plugins); const defaultState = initialState.defaultState; const mobileOverride = initialState.mobile; - + const epicMiddleware = createEpicMiddleware(rootEpic); const rootReducer = (state, action) => { let mapState = createHistory(LayersUtils.splitMapAndLayers(mapConfig(state, action))); let newState = { @@ -56,10 +58,10 @@ module.exports = (initialState = {defaultState: {}, mobile: {}}, appReducers = { }; let store; if (storeOpts && storeOpts.persist) { - store = DebugUtils.createDebugStore(rootReducer, defaultState, [], autoRehydrate()); + store = DebugUtils.createDebugStore(rootReducer, defaultState, [epicMiddleware], autoRehydrate()); persistStore(store, storeOpts.persist, storeOpts.onPersist); } else { - store = DebugUtils.createDebugStore(rootReducer, defaultState); + store = DebugUtils.createDebugStore(rootReducer, defaultState, [epicMiddleware]); } SecurityUtils.setStore(store); return store; diff --git a/web/client/utils/DebugUtils.js b/web/client/utils/DebugUtils.js index 46a54c02a9..0722cf7258 100644 --- a/web/client/utils/DebugUtils.js +++ b/web/client/utils/DebugUtils.js @@ -27,17 +27,18 @@ var DebugUtils = { if (__DEVTOOLS__ && urlQuery.debug) { let logger = require('redux-logger')(); let immutable = require('redux-immutable-state-invariant')(); - let middlewares = (userMiddlewares || []).concat([immutable, thunkMiddleware, logger]); + let middlewares = ([immutable, thunkMiddleware, logger]).concat(userMiddlewares || []); const {persistState} = require('redux-devtools'); const DevTools = require('../components/development/DevTools'); finalCreateStore = compose( applyMiddleware.apply(null, middlewares), - window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument(), - persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)) + persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)), + window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument() + )(createStore); } else { - let middlewares = (userMiddlewares || []).concat([thunkMiddleware]); + let middlewares = ([thunkMiddleware]).concat(userMiddlewares || []); finalCreateStore = applyMiddleware.apply(null, middlewares)(createStore); } return finalCreateStore(reducer, initialState, enhancer); diff --git a/web/client/utils/PluginsUtils.js b/web/client/utils/PluginsUtils.js index d9f2f63190..d2c3ceddb6 100644 --- a/web/client/utils/PluginsUtils.js +++ b/web/client/utils/PluginsUtils.js @@ -9,6 +9,7 @@ const assign = require('object-assign'); const {omit, isObject, head, isArray, isString} = require('lodash'); const {combineReducers} = require('redux'); +const {combineEpics} = require('redux-observable'); const {memoize, get} = require('lodash'); @@ -118,12 +119,17 @@ const getPluginItems = (state, plugins, pluginsConfig, name, id, isDefault, load const getReducers = (plugins) => Object.keys(plugins).map((name) => plugins[name].reducers) .reduce((previous, current) => assign({}, previous, current), {}); - +const getEpics = (plugins) => Object.keys(plugins).map((name) => plugins[name].epics) + .reduce((previous = [], current = []) => [ ...previous, ...current], []); const PluginsUtils = { combineReducers: (plugins, reducers) => { const pluginsReducers = getReducers(plugins); return combineReducers(assign({}, reducers, pluginsReducers)); }, + combineEpics: (plugins, epics = []) => { + const pluginEpics = getEpics(plugins); + return combineEpics(...[ ...pluginEpics, ...epics]); + }, getReducers, filterState, getPlugins: (plugins) => Object.keys(plugins).map((name) => plugins[name])