Skip to content

Commit

Permalink
imporoved debouncing
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdugne committed Apr 18, 2021
1 parent 5832b40 commit db84f9b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 23 deletions.
Binary file added docs/devtools.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 17 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,30 @@ example: plugging the [redux devtools extension](https://github.com/reduxjs/redu

## 🐛 Redux devtools

<p align="center"><img height="280px" src="./docs/devtools.png"></p>

```js
import createLaTaverne from 'taverne';
import {devtools} from 'taverne/middlewares';
import {createDevtools} from 'taverne/middlewares';
import books from './barrels/books';

const devtools = createDevtools();
const {dispatch, taverne} = createLaTaverne({books}, [devtools]);
```

When your app state is too big, you'll hit performance issues with Redux dev tools.

In this case you may need to skip part of state from tracking;

```js
const devtools = createDevtools({
applyStateFiltering? : state => ({
...state,
hugeObject: '<skipped>'
})
});
```

## 🏗️ development

[![devDeps](https://david-dm.org/uralys/taverne/dev-status.svg)](https://david-dm.org/uralys/taverne?type=dev)
Expand Down
81 changes: 62 additions & 19 deletions src/middlewares/devtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ const logPrefix = '[La Taverne 🐛]';
// -----------------------------------------------------------------------------

const isDebounced = (action = {}) => {
if (action.devtools && action.devtools.debounce) {
return true;
}

if (!action.from) {
return action.devtools && action.devtools.debounce;
return false;
}

return isDebounced(action.from);
Expand All @@ -24,6 +28,16 @@ const getNesting = (action = {}) => {

// -----------------------------------------------------------------------------

const rootType = (action = {}) => {
if (!action.from) {
return action.type;
}

return rootType(action.from);
};

// -----------------------------------------------------------------------------

const orderParentActions = (action = {}) => {
if (!action.from) {
return [action];
Expand All @@ -34,45 +48,64 @@ const orderParentActions = (action = {}) => {

// -----------------------------------------------------------------------------

const record = (devtoolsInstance, action, dispatch, getState) => {
const record = (
devtoolsInstance,
action,
dispatch,
getState,
applyStateFiltering
) => {
let type = action.type;

const nesting = getNesting(action.from);
type = `${action.from ? `└──${nesting}` : ''} ${type}`;

const currentState = getState();
const state = applyStateFiltering(currentState);

devtoolsInstance.send(
{
...action,
type
},
getState()
state
);

action.__recorded = true;
};

// -----------------------------------------------------------------------------

const recordDebouncedTree = (devtoolsInstance, action, dispatch, getState) => {
const recordDebouncedTree = (
devtoolsInstance,
action,
dispatch,
getState,
applyStateFiltering
) => {
const actions = orderParentActions(action);

actions.forEach(action => {
record(
devtoolsInstance,
{
type: `${action.type}/debounced (${devtoolsInstance.debounceCount})`,
type: `${action.type} (debounced x ${
devtoolsInstance.debounceCount[rootType(action)]
})`,
from: action.from
},
dispatch,
getState
getState,
applyStateFiltering
);
});
};

// -----------------------------------------------------------------------------

const createDevtools = taverne => {
const createDevtools = (options = {}) => taverne => {
const extension = window && window.__REDUX_DEVTOOLS_EXTENSION__;
const {applyStateFiltering = o => o} = options;

if (!extension) {
if (process.env.NODE_ENV === 'development') {
Expand All @@ -86,8 +119,8 @@ const createDevtools = taverne => {

const initialState = taverne.getState();
const devtoolsInstance = extension.connect({maxAge: 100});
devtoolsInstance.timeout = null;
devtoolsInstance.previousAction = {type: ''};
devtoolsInstance.timeouts = {};
devtoolsInstance.debounceCount = {};

devtoolsInstance.init(initialState);

Expand All @@ -105,24 +138,34 @@ const createDevtools = taverne => {
}

if (isDebounced(action)) {
if (devtoolsInstance.timeout) {
clearTimeout(devtoolsInstance.timeout);
const actionRootType = rootType(action);

if (devtoolsInstance.debounceCount[actionRootType] === undefined) {
devtoolsInstance.debounceCount[actionRootType] = 0;
}

if (!action.from) {
devtoolsInstance.debounceCount++;
devtoolsInstance.debounceCount[actionRootType]++;

if (devtoolsInstance.timeouts[actionRootType]) {
clearTimeout(devtoolsInstance.timeouts[actionRootType]);
}

devtoolsInstance.timeout = setTimeout(() => {
if (devtoolsInstance.debounceCount > 0) {
recordDebouncedTree(devtoolsInstance, action, dispatch, getState);
devtoolsInstance.timeouts[actionRootType] = setTimeout(() => {
if (devtoolsInstance.debounceCount[actionRootType] > 0) {
recordDebouncedTree(
devtoolsInstance,
action,
dispatch,
getState,
applyStateFiltering
);
}

devtoolsInstance.debounceCount = 0;
devtoolsInstance.debounceCount[actionRootType] = 0;
}, 250);
} else {
devtoolsInstance.debounceCount = 0;
record(devtoolsInstance, action, dispatch, getState);
devtoolsInstance.debounceCount[action.type] = 0;
record(devtoolsInstance, action, dispatch, getState, applyStateFiltering);
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/middlewares/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import devtools from './devtools';
import createDevtools from './devtools';

export {devtools};
export {createDevtools};
6 changes: 5 additions & 1 deletion src/taverne/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ const createDispatch = (taverne, middlewares) => {
middlewaresApplied = true;
dispatch({
...nextAction,
from: {type: action.type}
from: {
type: action.type,
devtools: action.devtools,
from: action.from
}
});
};

Expand Down

0 comments on commit db84f9b

Please sign in to comment.