mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-22 09:36:43 +03:00
Figure out monitor composition
This commit is contained in:
parent
1edf2d25c8
commit
c1256ed8ff
|
@ -28,8 +28,8 @@
|
||||||
"node-libs-browser": "^0.5.2",
|
"node-libs-browser": "^0.5.2",
|
||||||
"react-dock": "^0.1.0",
|
"react-dock": "^0.1.0",
|
||||||
"react-hot-loader": "^1.3.0",
|
"react-hot-loader": "^1.3.0",
|
||||||
"redux-devtools": "^3.0.0-alpha-1",
|
"redux-devtools": "^3.0.0-alpha-4",
|
||||||
"redux-devtools-log-monitor": "^1.0.0-alpha-3",
|
"redux-devtools-log-monitor": "^1.0.0-alpha-4",
|
||||||
"webpack": "^1.9.11",
|
"webpack": "^1.9.11",
|
||||||
"webpack-dev-server": "^1.9.0"
|
"webpack-dev-server": "^1.9.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
import { DevToolsProvider } from 'redux-devtools';
|
||||||
import CounterApp from './CounterApp';
|
import CounterApp from './CounterApp';
|
||||||
import Dock from 'react-dock';
|
|
||||||
import LogMonitor from 'redux-devtools-log-monitor';
|
import LogMonitor from 'redux-devtools-log-monitor';
|
||||||
|
import DockMonitor from '../dock/DockMonitor';
|
||||||
|
|
||||||
export default class Root extends Component {
|
export default class Root extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
@ -12,9 +13,11 @@ export default class Root extends Component {
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<CounterApp />
|
<CounterApp />
|
||||||
</Provider>
|
</Provider>
|
||||||
<Dock position='right' isVisible dimMode='none'>
|
<DevToolsProvider store={store}>
|
||||||
<LogMonitor store={store} />
|
<DockMonitor>
|
||||||
</Dock>
|
<LogMonitor />
|
||||||
|
</DockMonitor>
|
||||||
|
</DevToolsProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
109
examples/counter/src/dock/DockMonitor.js
Normal file
109
examples/counter/src/dock/DockMonitor.js
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
//
|
||||||
|
// TODO: extract to a separate project.
|
||||||
|
//
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import Dock from 'react-dock';
|
||||||
|
import MapProvider from './MapProvider';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { combineReducers } from 'redux';
|
||||||
|
|
||||||
|
const TOGGLE_VISIBILITY = '@@redux-devtools/dock/TOGGLE_VISIBILITY';
|
||||||
|
function toggleVisibility() {
|
||||||
|
return { type: TOGGLE_VISIBILITY };
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHANGE_POSITION = '@@redux-devtools/dock/CHANGE_POSITION';
|
||||||
|
function changePosition() {
|
||||||
|
return { type: CHANGE_POSITION };
|
||||||
|
}
|
||||||
|
|
||||||
|
const POSITIONS = ['left', 'top', 'right', 'bottom'];
|
||||||
|
|
||||||
|
function wrapReducer(options = {}) {
|
||||||
|
const {
|
||||||
|
isVisible: initialIsVisible = true,
|
||||||
|
position: initialPosition = 'right'
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
function position(state = initialPosition, action) {
|
||||||
|
return (action.type === CHANGE_POSITION) ?
|
||||||
|
POSITIONS[(POSITIONS.indexOf(state) + 1) % POSITIONS.length] :
|
||||||
|
state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isVisible(state = initialIsVisible, action) {
|
||||||
|
return (action.type === TOGGLE_VISIBILITY) ?
|
||||||
|
!state :
|
||||||
|
state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return childMonitorReducer => combineReducers({
|
||||||
|
childMonitorState: childMonitorReducer,
|
||||||
|
position,
|
||||||
|
isVisible
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapUpstreamStateToDownstreamState(state) {
|
||||||
|
return {
|
||||||
|
devToolsState: state.devToolsState,
|
||||||
|
monitorState: state.monitorState.childMonitorState
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@connect(
|
||||||
|
state => state.monitorState,
|
||||||
|
{ toggleVisibility, changePosition }
|
||||||
|
)
|
||||||
|
export default class DockMonitor extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
position: PropTypes.oneOf(['left', 'top', 'right', 'bottom']).isRequired,
|
||||||
|
isVisible: PropTypes.bool.isRequired,
|
||||||
|
childMonitorState: PropTypes.any,
|
||||||
|
toggleVisibility: PropTypes.func.isRequired,
|
||||||
|
changePosition: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||||
|
window.addEventListener('keydown', this.handleKeyDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('keydown', this.handleKeyDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyDown(e) {
|
||||||
|
if (!e.ctrlKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const key = event.keyCode || event.which;
|
||||||
|
const char = String.fromCharCode(key);
|
||||||
|
switch (char) {
|
||||||
|
case 'H':
|
||||||
|
this.props.toggleVisibility();
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
this.props.changePosition();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { position, isVisible, children } = this.props;
|
||||||
|
return (
|
||||||
|
<Dock position={position}
|
||||||
|
isVisible={isVisible}
|
||||||
|
dimMode='none'>
|
||||||
|
<MapProvider mapState={mapUpstreamStateToDownstreamState}>
|
||||||
|
{children}
|
||||||
|
</MapProvider>
|
||||||
|
</Dock>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DockMonitor.wrapReducer = wrapReducer;
|
52
examples/counter/src/dock/MapProvider.js
Normal file
52
examples/counter/src/dock/MapProvider.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// TODO: extract to a separate project.
|
||||||
|
//
|
||||||
|
|
||||||
|
import React, { Children, Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
const identity = _ => _;
|
||||||
|
function mapStore(store, { mapAction = identity, mapState = identity }) {
|
||||||
|
return {
|
||||||
|
...store,
|
||||||
|
dispatch(action) {
|
||||||
|
return store.dispatch(mapAction(action));
|
||||||
|
},
|
||||||
|
subscribe(listener) {
|
||||||
|
return store.subscribe(listener);
|
||||||
|
},
|
||||||
|
getState() {
|
||||||
|
return mapState(store.getState());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class MapProvider extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
mapAction: PropTypes.func,
|
||||||
|
mapState: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
static contextTypes = {
|
||||||
|
store: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
static childContextTypes = {
|
||||||
|
store: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
getChildContext() {
|
||||||
|
return {
|
||||||
|
store: this.store
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
this.store = mapStore(context.store, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return Children.only(this.props.children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,28 @@
|
||||||
import { createStore, applyMiddleware, compose } from 'redux';
|
import { createStore, applyMiddleware, compose } from 'redux';
|
||||||
import { devTools, persistState } from 'redux-devtools';
|
import devTools, { persistState } from 'redux-devtools';
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
import rootReducer from '../reducers';
|
import rootReducer from '../reducers';
|
||||||
import { createMonitorReducer } from 'redux-devtools-log-monitor';
|
import DockMonitor from '../dock/DockMonitor';
|
||||||
|
import LogMonitor from 'redux-devtools-log-monitor';
|
||||||
|
|
||||||
const finalCreateStore = compose(
|
const finalCreateStore = compose(
|
||||||
applyMiddleware(thunk),
|
applyMiddleware(
|
||||||
devTools(createMonitorReducer({
|
thunk
|
||||||
isVisibleOnLoad: true
|
),
|
||||||
})),
|
devTools(
|
||||||
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
|
LogMonitor.createReducer({
|
||||||
|
preserveScrollTop: true
|
||||||
|
}),
|
||||||
|
DockMonitor.wrapReducer({
|
||||||
|
position: 'right',
|
||||||
|
isVisible: true
|
||||||
|
})
|
||||||
|
),
|
||||||
|
persistState(
|
||||||
|
window.location.href.match(
|
||||||
|
/[?&]debug_session=([^&]+)\b/
|
||||||
|
)
|
||||||
|
)
|
||||||
)(createStore);
|
)(createStore);
|
||||||
|
|
||||||
export default function configureStore(initialState) {
|
export default function configureStore(initialState) {
|
||||||
|
|
37
src/DevToolsProvider.js
Normal file
37
src/DevToolsProvider.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
|
export default class DevToolsProvider extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
store(props, propName, componentName) {
|
||||||
|
if (!props.store) {
|
||||||
|
return new Error('Required prop `store` was not specified in `' + componentName + '`.');
|
||||||
|
}
|
||||||
|
if (!props.store.devToolsStore) {
|
||||||
|
return new Error(
|
||||||
|
'Could not find the DevTools store inside the `store` prop passed to `' +
|
||||||
|
componentName +
|
||||||
|
'`. Have you applied the devTools() store enhancer?'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { store, children } = this.props;
|
||||||
|
if (!store) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { devToolsStore } = store;
|
||||||
|
if (!devToolsStore) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Provider store={devToolsStore}>
|
||||||
|
{children}
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,38 +16,6 @@ export default function connectMonitor(monitorActionCreators = {}) {
|
||||||
}
|
}
|
||||||
const ConnectedMonitor = connect(mapStateToProps, mapDispatchToProps)(Monitor);
|
const ConnectedMonitor = connect(mapStateToProps, mapDispatchToProps)(Monitor);
|
||||||
|
|
||||||
class DevTools extends Component {
|
|
||||||
static Monitor = Monitor;
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
store(props, propName, componentName) {
|
|
||||||
if (!props.store) {
|
|
||||||
return new Error('Required prop `store` was not specified in `' + componentName + '`.');
|
|
||||||
}
|
|
||||||
if (!props.store.devToolsStore) {
|
|
||||||
return new Error(
|
|
||||||
'Could not find the DevTools store inside the `store` prop passed to `' +
|
|
||||||
componentName +
|
|
||||||
'`. Have you applied the devTools() store enhancer?'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { store } = this.props;
|
|
||||||
if (!store) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { devToolsStore } = store;
|
|
||||||
if (!devToolsStore) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ConnectedMonitor {...this.props} store={devToolsStore} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DevTools;
|
return DevTools;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { combineReducers, compose } from 'redux';
|
||||||
|
|
||||||
const ActionTypes = {
|
const ActionTypes = {
|
||||||
PERFORM_ACTION: 'PERFORM_ACTION',
|
PERFORM_ACTION: 'PERFORM_ACTION',
|
||||||
RESET: 'RESET',
|
RESET: 'RESET',
|
||||||
|
@ -77,20 +79,19 @@ function recomputeStates(reducer, committedState, stagedActions, skippedActions)
|
||||||
/**
|
/**
|
||||||
* Lifts the app state reducer into a DevTools state reducer.
|
* Lifts the app state reducer into a DevTools state reducer.
|
||||||
*/
|
*/
|
||||||
function liftReducer(reducer, monitorReducer, initialState) {
|
function createDevToolsStateReducer(reducer, initialCommittedState) {
|
||||||
const initialLiftedState = {
|
const initialState = {
|
||||||
committedState: initialState,
|
committedState: initialCommittedState,
|
||||||
stagedActions: [INIT_ACTION],
|
stagedActions: [INIT_ACTION],
|
||||||
skippedActions: {},
|
skippedActions: {},
|
||||||
currentStateIndex: 0,
|
currentStateIndex: 0,
|
||||||
monitorState: monitorReducer(undefined, INIT_ACTION),
|
|
||||||
timestamps: [Date.now()]
|
timestamps: [Date.now()]
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages how the DevTools actions modify the DevTools state.
|
* Manages how the DevTools actions modify the DevTools state.
|
||||||
*/
|
*/
|
||||||
return function liftedReducer(liftedState = initialLiftedState, liftedAction) {
|
return function devToolsState(state = initialState, action) {
|
||||||
let shouldRecomputeStates = true;
|
let shouldRecomputeStates = true;
|
||||||
let {
|
let {
|
||||||
committedState,
|
committedState,
|
||||||
|
@ -98,36 +99,35 @@ function liftReducer(reducer, monitorReducer, initialState) {
|
||||||
skippedActions,
|
skippedActions,
|
||||||
computedStates,
|
computedStates,
|
||||||
currentStateIndex,
|
currentStateIndex,
|
||||||
monitorState,
|
|
||||||
timestamps
|
timestamps
|
||||||
} = liftedState;
|
} = state;
|
||||||
|
|
||||||
switch (liftedAction.type) {
|
switch (action.type) {
|
||||||
case ActionTypes.RESET:
|
case ActionTypes.RESET:
|
||||||
committedState = initialState;
|
committedState = initialState;
|
||||||
stagedActions = [INIT_ACTION];
|
stagedActions = [INIT_ACTION];
|
||||||
skippedActions = {};
|
skippedActions = {};
|
||||||
currentStateIndex = 0;
|
currentStateIndex = 0;
|
||||||
timestamps = [liftedAction.timestamp];
|
timestamps = [action.timestamp];
|
||||||
break;
|
break;
|
||||||
case ActionTypes.COMMIT:
|
case ActionTypes.COMMIT:
|
||||||
committedState = computedStates[currentStateIndex].state;
|
committedState = computedStates[currentStateIndex].state;
|
||||||
stagedActions = [INIT_ACTION];
|
stagedActions = [INIT_ACTION];
|
||||||
skippedActions = {};
|
skippedActions = {};
|
||||||
currentStateIndex = 0;
|
currentStateIndex = 0;
|
||||||
timestamps = [liftedAction.timestamp];
|
timestamps = [action.timestamp];
|
||||||
break;
|
break;
|
||||||
case ActionTypes.ROLLBACK:
|
case ActionTypes.ROLLBACK:
|
||||||
stagedActions = [INIT_ACTION];
|
stagedActions = [INIT_ACTION];
|
||||||
skippedActions = {};
|
skippedActions = {};
|
||||||
currentStateIndex = 0;
|
currentStateIndex = 0;
|
||||||
timestamps = [liftedAction.timestamp];
|
timestamps = [action.timestamp];
|
||||||
break;
|
break;
|
||||||
case ActionTypes.TOGGLE_ACTION:
|
case ActionTypes.TOGGLE_ACTION:
|
||||||
skippedActions = toggle(skippedActions, liftedAction.index);
|
skippedActions = toggle(skippedActions, action.index);
|
||||||
break;
|
break;
|
||||||
case ActionTypes.JUMP_TO_STATE:
|
case ActionTypes.JUMP_TO_STATE:
|
||||||
currentStateIndex = liftedAction.index;
|
currentStateIndex = action.index;
|
||||||
// Optimization: we know the history has not changed.
|
// Optimization: we know the history has not changed.
|
||||||
shouldRecomputeStates = false;
|
shouldRecomputeStates = false;
|
||||||
break;
|
break;
|
||||||
|
@ -142,8 +142,8 @@ function liftReducer(reducer, monitorReducer, initialState) {
|
||||||
currentStateIndex++;
|
currentStateIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
stagedActions = [...stagedActions, liftedAction.action];
|
stagedActions = [...stagedActions, action.action];
|
||||||
timestamps = [...timestamps, liftedAction.timestamp];
|
timestamps = [...timestamps, action.timestamp];
|
||||||
|
|
||||||
// Optimization: we know that the past has not changed.
|
// Optimization: we know that the past has not changed.
|
||||||
shouldRecomputeStates = false;
|
shouldRecomputeStates = false;
|
||||||
|
@ -151,7 +151,7 @@ function liftReducer(reducer, monitorReducer, initialState) {
|
||||||
const previousEntry = computedStates[computedStates.length - 1];
|
const previousEntry = computedStates[computedStates.length - 1];
|
||||||
const nextEntry = computeNextEntry(
|
const nextEntry = computeNextEntry(
|
||||||
reducer,
|
reducer,
|
||||||
liftedAction.action,
|
action.action,
|
||||||
previousEntry.state,
|
previousEntry.state,
|
||||||
previousEntry.error
|
previousEntry.error
|
||||||
);
|
);
|
||||||
|
@ -170,15 +170,12 @@ function liftReducer(reducer, monitorReducer, initialState) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
monitorState = monitorReducer(monitorState, liftedAction);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
committedState,
|
committedState,
|
||||||
stagedActions,
|
stagedActions,
|
||||||
skippedActions,
|
skippedActions,
|
||||||
computedStates,
|
computedStates,
|
||||||
currentStateIndex,
|
currentStateIndex,
|
||||||
monitorState,
|
|
||||||
timestamps
|
timestamps
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -200,7 +197,7 @@ function liftAction(action) {
|
||||||
* Unlifts the DevTools state to the app state.
|
* Unlifts the DevTools state to the app state.
|
||||||
*/
|
*/
|
||||||
function unliftState(liftedState) {
|
function unliftState(liftedState) {
|
||||||
const { computedStates, currentStateIndex } = liftedState;
|
const { computedStates, currentStateIndex } = liftedState.devToolsState;
|
||||||
const { state } = computedStates[currentStateIndex];
|
const { state } = computedStates[currentStateIndex];
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -208,24 +205,29 @@ function unliftState(liftedState) {
|
||||||
/**
|
/**
|
||||||
* Unlifts the DevTools store to act like the app's store.
|
* Unlifts the DevTools store to act like the app's store.
|
||||||
*/
|
*/
|
||||||
function unliftStore(liftedStore, monitorReducer) {
|
function mapToComputedStateStore(devToolsStore, wrapReducer) {
|
||||||
let lastDefinedState;
|
let lastDefinedState;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...liftedStore,
|
...devToolsStore,
|
||||||
devToolsStore: liftedStore,
|
|
||||||
|
devToolsStore,
|
||||||
|
|
||||||
dispatch(action) {
|
dispatch(action) {
|
||||||
liftedStore.dispatch(liftAction(action));
|
devToolsStore.dispatch(liftAction(action));
|
||||||
return action;
|
return action;
|
||||||
},
|
},
|
||||||
|
|
||||||
getState() {
|
getState() {
|
||||||
const state = unliftState(liftedStore.getState());
|
const state = unliftState(devToolsStore.getState());
|
||||||
if (state !== undefined) {
|
if (state !== undefined) {
|
||||||
lastDefinedState = state;
|
lastDefinedState = state;
|
||||||
}
|
}
|
||||||
return lastDefinedState;
|
return lastDefinedState;
|
||||||
},
|
},
|
||||||
|
|
||||||
replaceReducer(nextReducer) {
|
replaceReducer(nextReducer) {
|
||||||
liftedStore.replaceReducer(liftReducer(nextReducer, monitorReducer));
|
devToolsStore.replaceReducer(wrapReducer(nextReducer));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -237,18 +239,23 @@ export const ActionCreators = {
|
||||||
reset() {
|
reset() {
|
||||||
return { type: ActionTypes.RESET, timestamp: Date.now() };
|
return { type: ActionTypes.RESET, timestamp: Date.now() };
|
||||||
},
|
},
|
||||||
|
|
||||||
rollback() {
|
rollback() {
|
||||||
return { type: ActionTypes.ROLLBACK, timestamp: Date.now() };
|
return { type: ActionTypes.ROLLBACK, timestamp: Date.now() };
|
||||||
},
|
},
|
||||||
|
|
||||||
commit() {
|
commit() {
|
||||||
return { type: ActionTypes.COMMIT, timestamp: Date.now() };
|
return { type: ActionTypes.COMMIT, timestamp: Date.now() };
|
||||||
},
|
},
|
||||||
|
|
||||||
sweep() {
|
sweep() {
|
||||||
return { type: ActionTypes.SWEEP };
|
return { type: ActionTypes.SWEEP };
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleAction(index) {
|
toggleAction(index) {
|
||||||
return { type: ActionTypes.TOGGLE_ACTION, index };
|
return { type: ActionTypes.TOGGLE_ACTION, index };
|
||||||
},
|
},
|
||||||
|
|
||||||
jumpToState(index) {
|
jumpToState(index) {
|
||||||
return { type: ActionTypes.JUMP_TO_STATE, index };
|
return { type: ActionTypes.JUMP_TO_STATE, index };
|
||||||
}
|
}
|
||||||
|
@ -257,11 +264,21 @@ export const ActionCreators = {
|
||||||
/**
|
/**
|
||||||
* Redux DevTools store enhancer.
|
* Redux DevTools store enhancer.
|
||||||
*/
|
*/
|
||||||
export default function devTools(monitorReducer = () => undefined) {
|
export default function devTools(
|
||||||
|
monitorReducer = () => null,
|
||||||
|
...monitorReducerWrappers
|
||||||
|
) {
|
||||||
return next => (reducer, initialState) => {
|
return next => (reducer, initialState) => {
|
||||||
const liftedReducer = liftReducer(reducer, monitorReducer, initialState);
|
const finalMonitorReducer = compose(
|
||||||
const liftedStore = next(liftedReducer);
|
...monitorReducerWrappers.slice().reverse()
|
||||||
const store = unliftStore(liftedStore, monitorReducer);
|
)(monitorReducer);
|
||||||
return store;
|
|
||||||
|
const wrapReducer = (r) => combineReducers({
|
||||||
|
devToolsState: createDevToolsStateReducer(r, initialState),
|
||||||
|
monitorState: finalMonitorReducer
|
||||||
|
});
|
||||||
|
|
||||||
|
const devToolsStore = next(wrapReducer(reducer));
|
||||||
|
return mapToComputedStateStore(devToolsStore, wrapReducer);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export { default as devTools } from './devTools';
|
export { default, ActionCreators, ActionTypes } from './devTools';
|
||||||
|
export { default as DevToolsProvider } from './DevToolsProvider';
|
||||||
export { default as persistState } from './persistState';
|
export { default as persistState } from './persistState';
|
||||||
export { default as connectMonitor } from './connectMonitor';
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user