Skip to content

Commit ee586ad

Browse files
committed
Implement actionsFilter and statesFilter
1 parent cf60af3 commit ee586ad

File tree

3 files changed

+77
-20
lines changed

3 files changed

+77
-20
lines changed

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,22 @@
8686
- **deserializeAction(action): transformedAction** (*function*) - optional transformation of actions deserialized from debug session (useful if actions are not plain object. Example: immutable-js action payload)
8787
- action, transformedAction - Redux action objects
8888
- **actionsBlacklist** (*array*) - actions to be hidden in DevTools. Overwrites corresponding global setting in the options page.
89-
- **actionsWhitelist** (*array*) - all other actions will be hidden in DevTools. Overwrites corresponding global setting in the options page.
89+
- **actionsFilter** (*function*) - function which takes `action` object and id number as arguments, and should return `action` object back. See the example bellow.
90+
- **statesFilter** (*function*) - function which takes `state` object and index as arguments, and should return `state` object back.
91+
Example of usage:
92+
93+
```js
94+
const actionsFilter = (action) => (
95+
action.type === 'FILE_DOWNLOAD_SUCCESS' && action.data ?
96+
{ ...action, data: '<<LONG_BLOB>>' } : action
97+
);
98+
const store = createStore(rootReducer, window.devToolsExtension && window.devToolsExtension({
99+
actionsFilter,
100+
statesFilter: (state) => state.data ? { ...state, data: '<<LONG_BLOB>>' } : state)
101+
}));
102+
```
90103

91-
## Examples
104+
## Demo
92105
Open these urls to test the extension:
93106

94107
- [Counter](http://zalmoxisus.github.io/redux-devtools-extension/examples/counter/)

src/browser/extension/inject/pageScript.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ window.devToolsExtension = function(config = {}) {
1616

1717
let store;
1818
let liftedStore;
19-
let localFilter = getLocalFilter(config);
2019
let shouldSerialize = false;
2120
let lastAction;
2221
let errorOccurred = false;
2322
let isMonitored = false;
2423
let isExcess;
24+
const localFilter = getLocalFilter(config);
25+
const { statesFilter, actionsFilter } = config;
2526

2627
function stringify(obj) {
2728
return jsan.stringify(obj);
@@ -42,15 +43,17 @@ window.devToolsExtension = function(config = {}) {
4243
function relay(type, state, action, nextActionId) {
4344
const message = {
4445
type,
45-
payload: filterState(state, type, localFilter),
46+
payload: filterState(state, type, localFilter, statesFilter, actionsFilter, nextActionId),
4647
source: 'redux-page',
4748
name: config.name || document.title
4849
};
4950

50-
if (action) message.action = action;
5151
if (type === 'ACTION') {
52+
message.action = !actionsFilter ? action : actionsFilter(action.action, nextActionId - 1);
5253
message.isExcess = isExcess;
5354
message.nextActionId = nextActionId;
55+
} else if (action) {
56+
message.action = action;
5457
}
5558

5659
if (shouldSerialize || window.devToolsOptions.serialize) {
Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import mapValues from 'lodash/mapValues';
2+
13
export function getLocalFilter(config) {
24
if (config.actionsBlacklist || config.actionsWhitelist) {
35
return {
@@ -18,20 +20,59 @@ export function isFiltered(action, localFilter) {
1820
);
1921
}
2022

21-
export function filterState(state, type, localFilter) {
22-
if (type !== 'STATE' || !localFilter && !window.devToolsOptions.filter) return state;
23-
24-
const filteredStagedActionIds = [];
25-
const filteredComputedStates = [];
26-
state.stagedActionIds.forEach((id, idx) => {
27-
if (!isFiltered(state.actionsById[id].action)) {
28-
filteredStagedActionIds.push(id);
29-
filteredComputedStates.push(state.computedStates[idx]);
30-
}
31-
});
32-
33-
return { ...state,
34-
stagedActionIds: filteredStagedActionIds,
35-
computedStates: filteredComputedStates
23+
function filterActions(actionsById, actionsFilter) {
24+
if (!actionsFilter) return actionsById;
25+
return mapValues(actionsById, (action, id) => (
26+
{ ...action, action: actionsFilter(action.action, id) }
27+
));
28+
}
29+
30+
function filterStates(computedStates, statesFilter) {
31+
if (!statesFilter) return computedStates;
32+
return computedStates.map((state, idx) => (
33+
{ ...state, state: statesFilter(state.state, idx) }
34+
));
35+
}
36+
37+
export function filterState(state, type, localFilter, statesFilter, actionsFilter, nextActionId) {
38+
if (type === 'ACTION') return !statesFilter ? state : statesFilter(state, nextActionId - 1);
39+
else if (type !== 'STATE') return state;
40+
41+
if (localFilter || window.devToolsOptions.filter) {
42+
const filteredStagedActionIds = [];
43+
const filteredComputedStates = [];
44+
const filteredActionsById = actionsFilter && {};
45+
const { actionsById } = state;
46+
const { computedStates } = state;
47+
48+
state.stagedActionIds.forEach((id, idx) => {
49+
if (!isFiltered(actionsById[id].action, localFilter)) {
50+
filteredStagedActionIds.push(id);
51+
filteredComputedStates.push(
52+
statesFilter ?
53+
{ ...computedStates[idx], state: statesFilter(computedStates[idx].state, idx) } :
54+
computedStates[idx]
55+
);
56+
if (actionsFilter) {
57+
filteredActionsById[id] = {
58+
...actionsById[id], action: actionsFilter(actionsById[id].action, id)
59+
};
60+
}
61+
}
62+
});
63+
64+
return {
65+
...state,
66+
actionsById: filteredActionsById || actionsById,
67+
stagedActionIds: filteredStagedActionIds,
68+
computedStates: filteredComputedStates
69+
};
70+
}
71+
72+
if (!statesFilter && !actionsFilter) return state;
73+
return {
74+
...state,
75+
actionsById: filterActions(state.actionsById, actionsFilter),
76+
computedStates: filterStates(state.computedStates, statesFilter)
3677
};
3778
}

0 commit comments

Comments
 (0)