diff --git a/examples/counter/package.json b/examples/counter/package.json
index 25f7eaf9..70a9e101 100644
--- a/examples/counter/package.json
+++ b/examples/counter/package.json
@@ -26,10 +26,10 @@
"babel-core": "^5.6.18",
"babel-loader": "^5.1.4",
"node-libs-browser": "^0.5.2",
- "react-dock": "0.0.3",
+ "react-dock": "^0.1.0",
"react-hot-loader": "^1.3.0",
"redux-devtools": "^3.0.0-alpha-1",
- "redux-devtools-log-monitor": "^1.0.0-alpha",
+ "redux-devtools-log-monitor": "^1.0.0-alpha-3",
"webpack": "^1.9.11",
"webpack-dev-server": "^1.9.0"
}
diff --git a/examples/counter/src/store/configureStore.dev.js b/examples/counter/src/store/configureStore.dev.js
index 4239b740..85c39ebf 100644
--- a/examples/counter/src/store/configureStore.dev.js
+++ b/examples/counter/src/store/configureStore.dev.js
@@ -2,10 +2,13 @@ import { createStore, applyMiddleware, compose } from 'redux';
import { devTools, persistState } from 'redux-devtools';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';
+import { createMonitorReducer } from 'redux-devtools-log-monitor';
const finalCreateStore = compose(
applyMiddleware(thunk),
- devTools(),
+ devTools(createMonitorReducer({
+ isVisibleOnLoad: true
+ })),
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)(createStore);
diff --git a/package.json b/package.json
index dcdc983c..a28f5fc3 100644
--- a/package.json
+++ b/package.json
@@ -50,10 +50,10 @@
"webpack": "^1.11.0"
},
"peerDependencies": {
- "redux": "^2.0.0 || ^3.0.0"
+ "redux": "^3.0.0"
},
"dependencies": {
"react-redux": "^3.0.0",
- "redux": "^2.0.0 || ^3.0.0"
+ "redux": "^3.0.0"
}
}
diff --git a/src/connectMonitor.js b/src/connectMonitor.js
index c0ae0362..f372e6b4 100644
--- a/src/connectMonitor.js
+++ b/src/connectMonitor.js
@@ -1,42 +1,54 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
import { ActionCreators } from './devTools';
-export default function connectMonitor(Monitor) {
- const ConnectedMonitor = connect(state => state, ActionCreators)(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 ;
+export default function connectMonitor(monitorActionCreators = {}) {
+ return Monitor => {
+ function mapStateToProps(state) {
+ return state;
}
- }
+ function mapDispatchToProps(dispatch) {
+ return {
+ ...bindActionCreators(ActionCreators, dispatch),
+ monitorActions: bindActionCreators(monitorActionCreators, dispatch)
+ };
+ }
+ const ConnectedMonitor = connect(mapStateToProps, mapDispatchToProps)(Monitor);
- return DevTools;
+ 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 ;
+ }
+ }
+
+ return DevTools;
+ };
}
diff --git a/src/devTools.js b/src/devTools.js
index 4704438a..8658d567 100644
--- a/src/devTools.js
+++ b/src/devTools.js
@@ -6,7 +6,6 @@ const ActionTypes = {
SWEEP: 'SWEEP',
TOGGLE_ACTION: 'TOGGLE_ACTION',
JUMP_TO_STATE: 'JUMP_TO_STATE',
- SET_MONITOR_STATE: 'SET_MONITOR_STATE',
RECOMPUTE_STATES: 'RECOMPUTE_STATES'
};
@@ -79,15 +78,13 @@ function recomputeStates(reducer, committedState, stagedActions, skippedActions)
/**
* Lifts the app state reducer into a DevTools state reducer.
*/
-function liftReducer(reducer, initialState) {
+function liftReducer(reducer, monitorStateReducer, initialState) {
const initialLiftedState = {
committedState: initialState,
stagedActions: [INIT_ACTION],
skippedActions: {},
currentStateIndex: 0,
- monitorState: {
- isVisible: true
- },
+ monitorState: monitorStateReducer(undefined, INIT_ACTION),
timestamps: [Date.now()]
};
@@ -145,9 +142,6 @@ function liftReducer(reducer, initialState) {
stagedActions = [...stagedActions, liftedAction.action];
timestamps = [...timestamps, liftedAction.timestamp];
break;
- case ActionTypes.SET_MONITOR_STATE:
- monitorState = liftedAction.monitorState;
- break;
case ActionTypes.RECOMPUTE_STATES:
stagedActions = liftedAction.stagedActions;
timestamps = liftedAction.timestamps;
@@ -166,6 +160,8 @@ function liftReducer(reducer, initialState) {
skippedActions
);
+ monitorState = monitorStateReducer(monitorState, liftedAction);
+
return {
committedState,
stagedActions,
@@ -202,7 +198,7 @@ function unliftState(liftedState) {
/**
* Unlifts the DevTools store to act like the app's store.
*/
-function unliftStore(liftedStore, reducer) {
+function unliftStore(liftedStore, monitorStateReducer) {
let lastDefinedState;
return {
...liftedStore,
@@ -218,11 +214,8 @@ function unliftStore(liftedStore, reducer) {
}
return lastDefinedState;
},
- getReducer() {
- return reducer;
- },
replaceReducer(nextReducer) {
- liftedStore.replaceReducer(liftReducer(nextReducer));
+ liftedStore.replaceReducer(liftReducer(nextReducer, monitorStateReducer));
}
};
}
@@ -249,9 +242,6 @@ export const ActionCreators = {
jumpToState(index) {
return { type: ActionTypes.JUMP_TO_STATE, index };
},
- setMonitorState(monitorState) {
- return { type: ActionTypes.SET_MONITOR_STATE, monitorState };
- },
recomputeStates(committedState, stagedActions) {
return {
type: ActionTypes.RECOMPUTE_STATES,
@@ -264,11 +254,11 @@ export const ActionCreators = {
/**
* Redux DevTools middleware.
*/
-export default function devTools() {
+export default function devTools(monitorStateReducer = () => undefined) {
return next => (reducer, initialState) => {
- const liftedReducer = liftReducer(reducer, initialState);
+ const liftedReducer = liftReducer(reducer, monitorStateReducer, initialState);
const liftedStore = next(liftedReducer);
- const store = unliftStore(liftedStore, reducer);
+ const store = unliftStore(liftedStore, monitorStateReducer);
return store;
};
}
diff --git a/test/connectMonitor.spec.js b/test/connectMonitor.spec.js
index bce19426..40c36d0b 100644
--- a/test/connectMonitor.spec.js
+++ b/test/connectMonitor.spec.js
@@ -11,12 +11,25 @@ class MockMonitor extends Component {
}
}
+function increment() {
+ return { type: 'INCREMENT' };
+}
+
+function mockMonitorReducer(state = 0, action) {
+ switch (action.type) {
+ case 'INCREMENT':
+ return state + 1;
+ default:
+ return state;
+ }
+}
+
describe('connectMonitor', () => {
jsdom();
it('should pass devToolsStore to monitor', () => {
const store = devTools()(createStore)(() => {});
- const ConnectedMonitor = connectMonitor(MockMonitor);
+ const ConnectedMonitor = connectMonitor()(MockMonitor);
const tree = TestUtils.renderIntoDocument(
);
@@ -26,7 +39,7 @@ describe('connectMonitor', () => {
it('should pass props to monitor', () => {
const store = devTools()(createStore)(() => {});
- const ConnectedMonitor = connectMonitor(MockMonitor);
+ const ConnectedMonitor = connectMonitor()(MockMonitor);
const tree = TestUtils.renderIntoDocument(
);
@@ -36,7 +49,7 @@ describe('connectMonitor', () => {
});
it('should subscribe monitor to store updates', () => {
- const ConnectedMonitor = connectMonitor(MockMonitor);
+ const ConnectedMonitor = connectMonitor()(MockMonitor);
const store = devTools()(createStore)(
(state, action) => {
switch (action.type) {
@@ -63,7 +76,7 @@ describe('connectMonitor', () => {
it('should warn if devTools() not in middleware', () => {
const store = createStore(() => {});
- const ConnectedMonitor = connectMonitor(MockMonitor);
+ const ConnectedMonitor = connectMonitor()(MockMonitor);
// Force to re-evaluate propType checks on every run
ConnectedMonitor.displayName = Math.random().toString();
@@ -77,4 +90,27 @@ describe('connectMonitor', () => {
(call, errMsg) => call.arguments[0].match(errMsg)
);
});
+
+ it('should pass monitor state and actions to the monitor', () => {
+ const store = devTools(mockMonitorReducer)(createStore)(() => {});
+ const ConnectedMonitor = connectMonitor()(MockMonitor);
+ const tree = TestUtils.renderIntoDocument(
+
+ );
+ const mockMonitor = TestUtils.findRenderedComponentWithType(tree, MockMonitor);
+ expect(mockMonitor.props.monitorState).toBe(0);
+ });
+
+ it('should pass bound monitor actions to monitor', () => {
+ const ConnectedMonitor = connectMonitor({ increment })(MockMonitor);
+ const store = devTools(mockMonitorReducer)(createStore)(() => {});
+ const tree = TestUtils.renderIntoDocument(
+
+ );
+
+ const mockMonitor = TestUtils.findRenderedComponentWithType(tree, MockMonitor);
+ expect(mockMonitor.props.monitorState).toBe(0);
+ mockMonitor.props.monitorActions.increment();
+ expect(mockMonitor.props.monitorState).toBe(1);
+ });
});
diff --git a/test/devTools.spec.js b/test/devTools.spec.js
index 672fb8b9..0e5014ea 100644
--- a/test/devTools.spec.js
+++ b/test/devTools.spec.js
@@ -143,11 +143,6 @@ describe('devTools', () => {
expect(store.getState()).toBe(2);
});
- it('should set monitor state', () => {
- devToolsStore.dispatch(ActionCreators.setMonitorState({test: 'test'}));
- expect(devToolsStore.getState().monitorState.test).toBe('test');
- });
-
it('should recompute', () => {
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });
@@ -167,10 +162,6 @@ describe('devTools', () => {
expect(store.getState()).toBe(13);
});
- it('should get the reducer', () => {
- expect(store.getReducer()).toBe(counter);
- });
-
it('should replace the reducer', () => {
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });