This is an automated email from the ASF dual-hosted git repository. graceguo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push: new 69e8df4 sql lab localStorage config (#6257) 69e8df4 is described below commit 69e8df404d46e35bf686cc92992d6e0415172d90 Author: Grace Guo <grace....@airbnb.com> AuthorDate: Tue Nov 6 23:12:32 2018 -0800 sql lab localStorage config (#6257) --- .../assets/spec/javascripts/sqllab/App_spec.jsx | 2 +- .../sqllab/ExploreResultsButton_spec.jsx | 10 ++--- .../{actions_spec.js => actions/sqlLab_spec.js} | 4 +- .../assets/spec/javascripts/sqllab/fixtures.js | 2 +- .../{reducers_spec.js => reducers/sqlLab_spec.js} | 52 +++++++++++----------- superset/assets/src/SqlLab/App.jsx | 27 ++++++++--- .../src/SqlLab/{actions.js => actions/sqlLab.js} | 8 ++-- superset/assets/src/SqlLab/components/App.jsx | 2 +- .../src/SqlLab/components/ExploreResultsButton.jsx | 6 +-- .../src/SqlLab/components/QueryAutoRefresh.jsx | 2 +- .../assets/src/SqlLab/components/SouthPane.jsx | 2 +- .../src/SqlLab/components/TabbedSqlEditors.jsx | 2 +- superset/assets/src/SqlLab/reducers/common.js | 3 ++ .../src/SqlLab/{ => reducers}/getInitialState.js | 7 ++- superset/assets/src/SqlLab/reducers/index.js | 11 +++++ .../src/SqlLab/{reducers.js => reducers/sqlLab.js} | 17 +++---- superset/assets/src/reduxUtils.js | 16 ++++--- 17 files changed, 101 insertions(+), 72 deletions(-) diff --git a/superset/assets/spec/javascripts/sqllab/App_spec.jsx b/superset/assets/spec/javascripts/sqllab/App_spec.jsx index 72192c0..5ba0733 100644 --- a/superset/assets/spec/javascripts/sqllab/App_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/App_spec.jsx @@ -7,7 +7,7 @@ import sinon from 'sinon'; import App from 'src/SqlLab/components/App'; import TabbedSqlEditors from 'src/SqlLab/components/TabbedSqlEditors'; -import { sqlLabReducer } from 'src/SqlLab/reducers'; +import sqlLabReducer from 'src/SqlLab/reducers/index'; describe('SqlLab App', () => { const middlewares = [thunk]; diff --git a/superset/assets/spec/javascripts/sqllab/ExploreResultsButton_spec.jsx b/superset/assets/spec/javascripts/sqllab/ExploreResultsButton_spec.jsx index 71647c8..25c899e 100644 --- a/superset/assets/spec/javascripts/sqllab/ExploreResultsButton_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/ExploreResultsButton_spec.jsx @@ -8,8 +8,8 @@ import fetchMock from 'fetch-mock'; import shortid from 'shortid'; import { queries, queryWithBadColumns } from './fixtures'; -import { sqlLabReducer } from '../../../src/SqlLab/reducers'; -import * as actions from '../../../src/SqlLab/actions'; +import sqlLabReducer from '../../../src/SqlLab/reducers/index'; +import * as actions from '../../../src/SqlLab/actions/sqlLab'; import ExploreResultsButton from '../../../src/SqlLab/components/ExploreResultsButton'; import * as exploreUtils from '../../../src/explore/exploreUtils'; import Button from '../../../src/components/Button'; @@ -23,9 +23,9 @@ describe('ExploreResultsButton', () => { const initialState = { sqlLab: { ...sqlLabReducer(undefined, {}), - common: { - conf: { SUPERSET_WEBSERVER_TIMEOUT: 45 }, - }, + }, + common: { + conf: { SUPERSET_WEBSERVER_TIMEOUT: 45 }, }, }; const store = mockStore(initialState); diff --git a/superset/assets/spec/javascripts/sqllab/actions_spec.js b/superset/assets/spec/javascripts/sqllab/actions/sqlLab_spec.js similarity index 97% rename from superset/assets/spec/javascripts/sqllab/actions_spec.js rename to superset/assets/spec/javascripts/sqllab/actions/sqlLab_spec.js index 1260621..7953d63 100644 --- a/superset/assets/spec/javascripts/sqllab/actions_spec.js +++ b/superset/assets/spec/javascripts/sqllab/actions/sqlLab_spec.js @@ -2,8 +2,8 @@ import sinon from 'sinon'; import fetchMock from 'fetch-mock'; -import * as actions from '../../../src/SqlLab/actions'; -import { query } from './fixtures'; +import * as actions from '../../../../src/SqlLab/actions/sqlLab'; +import { query } from '../fixtures'; describe('async actions', () => { let dispatch; diff --git a/superset/assets/spec/javascripts/sqllab/fixtures.js b/superset/assets/spec/javascripts/sqllab/fixtures.js index 77a4806..02a6c12 100644 --- a/superset/assets/spec/javascripts/sqllab/fixtures.js +++ b/superset/assets/spec/javascripts/sqllab/fixtures.js @@ -1,5 +1,5 @@ import sinon from 'sinon'; -import * as actions from '../../../src/SqlLab/actions'; +import * as actions from '../../../src/SqlLab/actions/sqlLab'; export const mockedActions = sinon.stub(Object.assign({}, actions)); diff --git a/superset/assets/spec/javascripts/sqllab/reducers_spec.js b/superset/assets/spec/javascripts/sqllab/reducers/sqlLab_spec.js similarity index 68% rename from superset/assets/spec/javascripts/sqllab/reducers_spec.js rename to superset/assets/spec/javascripts/sqllab/reducers/sqlLab_spec.js index 1a451f6..964daa8 100644 --- a/superset/assets/spec/javascripts/sqllab/reducers_spec.js +++ b/superset/assets/spec/javascripts/sqllab/reducers/sqlLab_spec.js @@ -1,6 +1,6 @@ -import * as r from '../../../src/SqlLab/reducers'; -import * as actions from '../../../src/SqlLab/actions'; -import { table, initialState as mockState } from './fixtures'; +import sqlLabReducer from '../../../../src/SqlLab/reducers/sqlLab'; +import * as actions from '../../../../src/SqlLab/actions/sqlLab'; +import { table, initialState as mockState } from '../fixtures'; const initialState = mockState.sqlLab; @@ -12,7 +12,7 @@ describe('sqlLabReducer', () => { queries: { [testQuery.id]: testQuery }, }; beforeEach(() => { - newState = r.sqlLabReducer(newState, actions.cloneQueryToNewTab(testQuery)); + newState = sqlLabReducer(newState, actions.cloneQueryToNewTab(testQuery)); }); it('should have at most one more tab', () => { @@ -39,7 +39,7 @@ describe('sqlLabReducer', () => { newState = { ...initialState }; defaultQueryEditor = newState.queryEditors[0]; qe = Object.assign({}, defaultQueryEditor); - newState = r.sqlLabReducer(newState, actions.addQueryEditor(qe)); + newState = sqlLabReducer(newState, actions.addQueryEditor(qe)); qe = newState.queryEditors[newState.queryEditors.length - 1]; }); it('should add a query editor', () => { @@ -47,44 +47,44 @@ describe('sqlLabReducer', () => { }); it('should remove a query editor', () => { expect(newState.queryEditors).toHaveLength(2); - newState = r.sqlLabReducer(newState, actions.removeQueryEditor(qe)); + newState = sqlLabReducer(newState, actions.removeQueryEditor(qe)); expect(newState.queryEditors).toHaveLength(1); }); it('should set q query editor active', () => { - newState = r.sqlLabReducer(newState, actions.addQueryEditor(qe)); - newState = r.sqlLabReducer(newState, actions.setActiveQueryEditor(defaultQueryEditor)); + newState = sqlLabReducer(newState, actions.addQueryEditor(qe)); + newState = sqlLabReducer(newState, actions.setActiveQueryEditor(defaultQueryEditor)); expect(newState.tabHistory[newState.tabHistory.length - 1]).toBe(defaultQueryEditor.id); }); it('should not fail while setting DB', () => { const dbId = 9; - newState = r.sqlLabReducer(newState, actions.queryEditorSetDb(qe, dbId)); + newState = sqlLabReducer(newState, actions.queryEditorSetDb(qe, dbId)); expect(newState.queryEditors[1].dbId).toBe(dbId); }); it('should not fail while setting schema', () => { const schema = 'foo'; - newState = r.sqlLabReducer(newState, actions.queryEditorSetSchema(qe, schema)); + newState = sqlLabReducer(newState, actions.queryEditorSetSchema(qe, schema)); expect(newState.queryEditors[1].schema).toBe(schema); }); it('should not fail while setting autorun ', () => { - newState = r.sqlLabReducer(newState, actions.queryEditorSetAutorun(qe, false)); + newState = sqlLabReducer(newState, actions.queryEditorSetAutorun(qe, false)); expect(newState.queryEditors[1].autorun).toBe(false); - newState = r.sqlLabReducer(newState, actions.queryEditorSetAutorun(qe, true)); + newState = sqlLabReducer(newState, actions.queryEditorSetAutorun(qe, true)); expect(newState.queryEditors[1].autorun).toBe(true); }); it('should not fail while setting title', () => { const title = 'a new title'; - newState = r.sqlLabReducer(newState, actions.queryEditorSetTitle(qe, title)); + newState = sqlLabReducer(newState, actions.queryEditorSetTitle(qe, title)); expect(newState.queryEditors[1].title).toBe(title); }); it('should not fail while setting Sql', () => { const sql = 'SELECT nothing from dev_null'; - newState = r.sqlLabReducer(newState, actions.queryEditorSetSql(qe, sql)); + newState = sqlLabReducer(newState, actions.queryEditorSetSql(qe, sql)); expect(newState.queryEditors[1].sql).toBe(sql); }); it('should set selectedText', () => { const selectedText = 'TEST'; expect(newState.queryEditors[0].selectedText).toBeNull(); - newState = r.sqlLabReducer( + newState = sqlLabReducer( newState, actions.queryEditorSetSelectedText(newState.queryEditors[0], 'TEST')); expect(newState.queryEditors[0].selectedText).toBe(selectedText); }); @@ -94,7 +94,7 @@ describe('sqlLabReducer', () => { let newTable; beforeEach(() => { newTable = Object.assign({}, table); - newState = r.sqlLabReducer(initialState, actions.mergeTable(newTable)); + newState = sqlLabReducer(initialState, actions.mergeTable(newTable)); newTable = newState.tables[0]; }); it('should add a table', () => { @@ -104,18 +104,18 @@ describe('sqlLabReducer', () => { it('should merge the table attributes', () => { // Merging the extra attribute newTable.extra = true; - newState = r.sqlLabReducer(newState, actions.mergeTable(newTable)); + newState = sqlLabReducer(newState, actions.mergeTable(newTable)); expect(newState.tables).toHaveLength(1); expect(newState.tables[0].extra).toBe(true); }); it('should expand and collapse a table', () => { - newState = r.sqlLabReducer(newState, actions.collapseTable(newTable)); + newState = sqlLabReducer(newState, actions.collapseTable(newTable)); expect(newState.tables[0].expanded).toBe(false); - newState = r.sqlLabReducer(newState, actions.expandTable(newTable)); + newState = sqlLabReducer(newState, actions.expandTable(newTable)); expect(newState.tables[0].expanded).toBe(true); }); it('should remove a table', () => { - newState = r.sqlLabReducer(newState, actions.removeTable(newTable)); + newState = sqlLabReducer(newState, actions.removeTable(newTable)); expect(newState.tables).toHaveLength(0); }); }); @@ -128,22 +128,22 @@ describe('sqlLabReducer', () => { newQuery = { ...query }; }); it('should start a query', () => { - newState = r.sqlLabReducer(newState, actions.startQuery(newQuery)); + newState = sqlLabReducer(newState, actions.startQuery(newQuery)); expect(Object.keys(newState.queries)).toHaveLength(1); }); it('should stop the query', () => { - newState = r.sqlLabReducer(newState, actions.startQuery(newQuery)); - newState = r.sqlLabReducer(newState, actions.stopQuery(newQuery)); + newState = sqlLabReducer(newState, actions.startQuery(newQuery)); + newState = sqlLabReducer(newState, actions.stopQuery(newQuery)); const q = newState.queries[Object.keys(newState.queries)[0]]; expect(q.state).toBe('stopped'); }); it('should remove a query', () => { - newState = r.sqlLabReducer(newState, actions.startQuery(newQuery)); - newState = r.sqlLabReducer(newState, actions.removeQuery(newQuery)); + newState = sqlLabReducer(newState, actions.startQuery(newQuery)); + newState = sqlLabReducer(newState, actions.removeQuery(newQuery)); expect(Object.keys(newState.queries)).toHaveLength(0); }); it('should refresh queries when polling returns empty', () => { - newState = r.sqlLabReducer(newState, actions.refreshQueries({})); + newState = sqlLabReducer(newState, actions.refreshQueries({})); }); }); }); diff --git a/superset/assets/src/SqlLab/App.jsx b/superset/assets/src/SqlLab/App.jsx index 9e242c3..bd5906a 100644 --- a/superset/assets/src/SqlLab/App.jsx +++ b/superset/assets/src/SqlLab/App.jsx @@ -5,8 +5,8 @@ import thunkMiddleware from 'redux-thunk'; import { hot } from 'react-hot-loader'; import { initFeatureFlags } from 'src/featureFlags'; -import getInitialState from './getInitialState'; -import rootReducer from './reducers'; +import getInitialState from './reducers/getInitialState'; +import rootReducer from './reducers/index'; import { initEnhancer } from '../reduxUtils'; import App from './components/App'; import setupApp from '../setup/setupApp'; @@ -20,14 +20,31 @@ setupApp(); const appContainer = document.getElementById('app'); const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap')); initFeatureFlags(bootstrapData.common.feature_flags); -const state = getInitialState(bootstrapData); +const initialState = getInitialState(bootstrapData); +const sqlLabPersistStateConfig = { + paths: ['sqlLab'], + config: { + slicer: paths => (state) => { + const subset = {}; + paths.forEach((path) => { + // this line is used to remove old data from browser localStorage. + // we used to persist all redux state into localStorage, but + // it caused configurations passed from server-side got override. + // see PR 6257 for details + delete state[path].common; // eslint-disable-line no-param-reassign + subset[path] = state[path]; + }); + return subset; + }, + }, +}; const store = createStore( rootReducer, - state, + initialState, compose( applyMiddleware(thunkMiddleware), - initEnhancer(), + initEnhancer(true, sqlLabPersistStateConfig), ), ); diff --git a/superset/assets/src/SqlLab/actions.js b/superset/assets/src/SqlLab/actions/sqlLab.js similarity index 98% rename from superset/assets/src/SqlLab/actions.js rename to superset/assets/src/SqlLab/actions/sqlLab.js index aac81d6..17e022b 100644 --- a/superset/assets/src/SqlLab/actions.js +++ b/superset/assets/src/SqlLab/actions/sqlLab.js @@ -3,14 +3,14 @@ import JSONbig from 'json-bigint'; import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/connection'; -import { now } from '../modules/dates'; +import { now } from '../../modules/dates'; import { addSuccessToast as addSuccessToastAction, addDangerToast as addDangerToastAction, addInfoToast as addInfoToastAction, -} from '../messageToasts/actions'; -import getClientErrorObject from '../utils/getClientErrorObject'; -import COMMON_ERR_MESSAGES from '../utils/errorMessages'; +} from '../../messageToasts/actions/index'; +import getClientErrorObject from '../../utils/getClientErrorObject'; +import COMMON_ERR_MESSAGES from '../../utils/errorMessages'; export const RESET_STATE = 'RESET_STATE'; export const ADD_QUERY_EDITOR = 'ADD_QUERY_EDITOR'; diff --git a/superset/assets/src/SqlLab/components/App.jsx b/superset/assets/src/SqlLab/components/App.jsx index 8a0c084..6613d07 100644 --- a/superset/assets/src/SqlLab/components/App.jsx +++ b/superset/assets/src/SqlLab/components/App.jsx @@ -8,7 +8,7 @@ import TabbedSqlEditors from './TabbedSqlEditors'; import QueryAutoRefresh from './QueryAutoRefresh'; import QuerySearch from './QuerySearch'; import ToastPresenter from '../../messageToasts/containers/ToastPresenter'; -import * as Actions from '../actions'; +import * as Actions from '../actions/sqlLab'; class App extends React.PureComponent { constructor(props) { diff --git a/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx b/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx index 06cddbc..26a246c 100644 --- a/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx +++ b/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx @@ -9,7 +9,7 @@ import { t } from '@superset-ui/translation'; import shortid from 'shortid'; import { exportChart } from '../../explore/exploreUtils'; -import * as actions from '../actions'; +import * as actions from '../actions/sqlLab'; import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger'; import Button from '../../components/Button'; @@ -184,10 +184,10 @@ class ExploreResultsButton extends React.PureComponent { ExploreResultsButton.propTypes = propTypes; ExploreResultsButton.defaultProps = defaultProps; -function mapStateToProps({ sqlLab }) { +function mapStateToProps({ sqlLab, common }) { return { errorMessage: sqlLab.errorMessage, - timeout: sqlLab.common ? sqlLab.common.conf.SUPERSET_WEBSERVER_TIMEOUT : null, + timeout: common.conf ? common.conf.SUPERSET_WEBSERVER_TIMEOUT : null, }; } diff --git a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx index 2937e15..295c32f 100644 --- a/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx +++ b/superset/assets/src/SqlLab/components/QueryAutoRefresh.jsx @@ -4,7 +4,7 @@ import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { SupersetClient } from '@superset-ui/connection'; -import * as Actions from '../actions'; +import * as Actions from '../actions/sqlLab'; const QUERY_UPDATE_FREQ = 2000; const QUERY_UPDATE_BUFFER_MS = 5000; diff --git a/superset/assets/src/SqlLab/components/SouthPane.jsx b/superset/assets/src/SqlLab/components/SouthPane.jsx index eddc808..3f6fb42 100644 --- a/superset/assets/src/SqlLab/components/SouthPane.jsx +++ b/superset/assets/src/SqlLab/components/SouthPane.jsx @@ -6,7 +6,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { t } from '@superset-ui/translation'; -import * as Actions from '../actions'; +import * as Actions from '../actions/sqlLab'; import QueryHistory from './QueryHistory'; import ResultSet from './ResultSet'; import { STATUS_OPTIONS, STATE_BSSTYLE_MAP } from '../constants'; diff --git a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx index 43b7354..0fb5f21 100644 --- a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx @@ -6,7 +6,7 @@ import { bindActionCreators } from 'redux'; import URI from 'urijs'; import { t } from '@superset-ui/translation'; -import * as Actions from '../actions'; +import * as Actions from '../actions/sqlLab'; import SqlEditor from './SqlEditor'; import { areArraysShallowEqual } from '../../reduxUtils'; import TabStatusIcon from './TabStatusIcon'; diff --git a/superset/assets/src/SqlLab/reducers/common.js b/superset/assets/src/SqlLab/reducers/common.js new file mode 100644 index 0000000..738291c --- /dev/null +++ b/superset/assets/src/SqlLab/reducers/common.js @@ -0,0 +1,3 @@ +export default function commonReducer(state = {}) { + return state; +} diff --git a/superset/assets/src/SqlLab/getInitialState.js b/superset/assets/src/SqlLab/reducers/getInitialState.js similarity index 77% rename from superset/assets/src/SqlLab/getInitialState.js rename to superset/assets/src/SqlLab/reducers/getInitialState.js index ba984c2..14bd677 100644 --- a/superset/assets/src/SqlLab/getInitialState.js +++ b/superset/assets/src/SqlLab/reducers/getInitialState.js @@ -1,6 +1,6 @@ import shortid from 'shortid'; import { t } from '@superset-ui/translation'; -import getToastsFromPyFlashMessages from '../messageToasts/utils/getToastsFromPyFlashMessages'; +import getToastsFromPyFlashMessages from '../../messageToasts/utils/getToastsFromPyFlashMessages'; export default function getInitialState({ defaultDbId, ...restBootstrapData }) { const defaultQueryEditor = { @@ -24,10 +24,13 @@ export default function getInitialState({ defaultDbId, ...restBootstrapData }) { tabHistory: [defaultQueryEditor.id], tables: [], queriesLastUpdate: Date.now(), - ...restBootstrapData, }, messageToasts: getToastsFromPyFlashMessages( (restBootstrapData.common || {}).flash_messages || [], ), + common: { + flash_messages: restBootstrapData.common.flash_messages, + conf: restBootstrapData.common.conf, + }, }; } diff --git a/superset/assets/src/SqlLab/reducers/index.js b/superset/assets/src/SqlLab/reducers/index.js new file mode 100644 index 0000000..c1dcd28 --- /dev/null +++ b/superset/assets/src/SqlLab/reducers/index.js @@ -0,0 +1,11 @@ +import { combineReducers } from 'redux'; + +import sqlLab from './sqlLab'; +import messageToasts from '../../messageToasts/reducers/index'; +import common from './common'; + +export default combineReducers({ + sqlLab, + messageToasts, + common, +}); diff --git a/superset/assets/src/SqlLab/reducers.js b/superset/assets/src/SqlLab/reducers/sqlLab.js similarity index 96% rename from superset/assets/src/SqlLab/reducers.js rename to superset/assets/src/SqlLab/reducers/sqlLab.js index 87d0332..b8a27a9 100644 --- a/superset/assets/src/SqlLab/reducers.js +++ b/superset/assets/src/SqlLab/reducers/sqlLab.js @@ -1,11 +1,9 @@ -import { combineReducers } from 'redux'; import shortid from 'shortid'; import { t } from '@superset-ui/translation'; -import messageToasts from '../messageToasts/reducers'; import getInitialState from './getInitialState'; -import * as actions from './actions'; -import { now } from '../modules/dates'; +import * as actions from '../actions/sqlLab'; +import { now } from '../../modules/dates'; import { addToObject, alterInObject, @@ -13,9 +11,9 @@ import { removeFromArr, getFromArr, addToArr, -} from '../reduxUtils'; +} from '../../reduxUtils'; -export const sqlLabReducer = function (state = {}, action) { +export default function sqlLabReducer(state = {}, action) { const actionHandlers = { [actions.ADD_QUERY_EDITOR]() { const tabHistory = state.tabHistory.slice(); @@ -276,9 +274,4 @@ export const sqlLabReducer = function (state = {}, action) { return actionHandlers[action.type](); } return state; -}; - -export default combineReducers({ - sqlLab: sqlLabReducer, - messageToasts, -}); +} diff --git a/superset/assets/src/reduxUtils.js b/superset/assets/src/reduxUtils.js index cc0b581..baaa05b 100644 --- a/superset/assets/src/reduxUtils.js +++ b/superset/assets/src/reduxUtils.js @@ -68,14 +68,16 @@ export function addToArr(state, arrKey, obj, prepend = false) { return Object.assign({}, state, newState); } -export function initEnhancer(persist = true) { - let enhancer = persist ? compose(persistState()) : compose(); - if (process.env.WEBPACK_MODE === 'development') { +export function initEnhancer(persist = true, persistConfig = {}) { + const { paths, config } = persistConfig; + const composeEnhancers = process.env.WEBPACK_MODE === 'development' /* eslint-disable-next-line no-underscore-dangle */ - const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; - enhancer = persist ? composeEnhancers(persistState()) : composeEnhancers(); - } - return enhancer; + ? (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose) + : compose; + + return persist + ? composeEnhancers(persistState(paths, config)) + : composeEnhancers(); } export function areArraysShallowEqual(arr1, arr2) {