{"action":"created","issue":{"url":"https://api.github.com/repos/rackt/reselect/issues/71","labels_url":"https://api.github.com/repos/rackt/reselect/issues/71/labels{/name}","comments_url":"https://api.github.com/repos/rackt/reselect/issues/71/comments","events_url":"https://api.github.com/repos/rackt/reselect/issues/71/events","html_url":"https://github.com/rackt/reselect/issues/71","id":124682462,"number":71,"title":"Middleware for debugging?","user":{"login":"MattSPalmer","id":490790,"avatar_url":"https://avatars.githubusercontent.com/u/490790?v=3","gravatar_id":"","url":"https://api.github.com/users/MattSPalmer","html_url":"https://github.com/MattSPalmer","followers_url":"https://api.github.com/users/MattSPalmer/followers","following_url":"https://api.github.com/users/MattSPalmer/following{/other_user}","gists_url":"https://api.github.com/users/MattSPalmer/gists{/gist_id}","starred_url":"https://api.github.com/users/MattSPalmer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MattSPalmer/subscriptions","organizations_url":"https://api.github.com/users/MattSPalmer/orgs","repos_url":"https://api.github.com/users/MattSPalmer/repos","events_url":"https://api.github.com/users/MattSPalmer/events{/privacy}","received_events_url":"https://api.github.com/users/MattSPalmer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-01-04T00:55:34Z","updated_at":"2016-01-26T08:15:34Z","closed_at":null,"body":"Hi there team. Really enjoy the library.\r\n\r\nWas wondering if there's been any consideration thus far for introspection into one's selectors via middleware or some other modification? As apps grow bigger and selectors increase in complexity, I can see a lot of value in having some way to quickly (and visually) trace the origination of an arbitrary selector's value.\r\n\r\nAll selectors created by `createSelector` can be described as having X 'ancestors' and Y 'descendants'. Seems to me these relationships lend themselves really well to being represented as a visual hierarchy; a tree, graph, or what have you.\r\n\r\nConsider the example in the README:\r\n```javascript\r\nimport { createSelector } from 'reselect'\r\n\r\nconst shopItemsSelector = state => state.shop.items\r\nconst taxPercentSelector = state => state.shop.taxPercent\r\n\r\nconst subtotalSelector = createSelector(\r\n  shopItemsSelector,\r\n  items => items.reduce((acc, item) => acc + item.value, 0)\r\n)\r\n\r\nconst taxSelector = createSelector(\r\n  subtotalSelector,\r\n  taxPercentSelector,\r\n  (subtotal, taxPercent) => subtotal * (taxPercent / 100)\r\n)\r\n\r\nexport const totalSelector = createSelector(\r\n  subtotalSelector,\r\n  taxSelector,\r\n  (subtotal, tax) => ({ total: subtotal + tax })\r\n)\r\n```\r\n\r\nOne could conceive of a graph showing the flow of state down through to totalSelector:\r\n![image](https://cloud.githubusercontent.com/assets/490790/12081767/91987b32-b252-11e5-9ffb-1da2e61a5ba1.png)\r\n\r\nNodes on such a graph could contain information such as the number of re-computations on that selector, the last memoized value, when the value last changed, etc.\r\n\r\nCurious to know if there's interest in a project that would generate output like the above, or if someone's done similar work already. Either way, I'd love to help out!"},"comment":{"url":"https://api.github.com/repos/rackt/reselect/issues/comments/174885369","html_url":"https://github.com/rackt/reselect/issues/71#issuecomment-174885369","issue_url":"https://api.github.com/repos/rackt/reselect/issues/71","id":174885369,"user":{"login":"aarongreenwald","id":6300588,"avatar_url":"https://avatars.githubusercontent.com/u/6300588?v=3","gravatar_id":"","url":"https://api.github.com/users/aarongreenwald","html_url":"https://github.com/aarongreenwald","followers_url":"https://api.github.com/users/aarongreenwald/followers","following_url":"https://api.github.com/users/aarongreenwald/following{/other_user}","gists_url":"https://api.github.com/users/aarongreenwald/gists{/gist_id}","starred_url":"https://api.github.com/users/aarongreenwald/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aarongreenwald/subscriptions","organizations_url":"https://api.github.com/users/aarongreenwald/orgs","repos_url":"https://api.github.com/users/aarongreenwald/repos","events_url":"https://api.github.com/users/aarongreenwald/events{/privacy}","received_events_url":"https://api.github.com/users/aarongreenwald/received_events","type":"User","site_admin":false},"created_at":"2016-01-26T08:15:34Z","updated_at":"2016-01-26T08:15:34Z","body":"Here's what I have for now\r\n\r\n```js\r\nconst reselectLogger = (selector, name) => ({getState}) => next => action => {\r\n  let oldState = selector(getState());\r\n  let result = next(action);\r\n  let newState = selector(getState());\r\n  if (oldState !== newState) {\r\n    console.log(`Selector recalculated: ${name}`, selector(getState()));\r\n  }\r\n  return result;\r\n};\r\n```\r\nand then \r\n```js\r\nlet middlewares = [\r\n  ...\r\n  reselectLogger(someSelector, 'Selector Name'),\r\n  reselectLogger(anotherSelector, 'Another Selector Name'),\r\n];\r\n\r\nconst createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);\r\nconst store = createStoreWithMiddleware(rootReducer);\r\n\r\n```\r\nWhen I get around to it, I'll improve the console.log statement to format the output nicely so that it fits in with the redux-logger output. Also, I'd like to figure out a way to avoid having to include an instance of the middleware for every selector I have."}}