├── .gitignore ├── .babelrc ├── test ├── fixtures │ ├── middleware │ │ ├── actual.js │ │ └── expected.js │ ├── selector-with-another-assignment │ │ ├── actual.js │ │ └── expected.js │ ├── selector-factory │ │ ├── actual.js │ │ └── expected.js │ └── selectors │ │ ├── actual.js │ │ └── expected.js └── index.js ├── .editorconfig ├── README.md ├── package.json ├── LICENSE.md └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | lib 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": [] 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/middleware/actual.js: -------------------------------------------------------------------------------- 1 | export const stickyMiddleware = () => (next) => (action) => { 2 | return next(action); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/selector-with-another-assignment/actual.js: -------------------------------------------------------------------------------- 1 | const birdSelector = createSelector( 2 | a => a.b, 3 | (b) => b 4 | ); 5 | 6 | const bird = '🐦'; 7 | -------------------------------------------------------------------------------- /test/fixtures/selector-factory/actual.js: -------------------------------------------------------------------------------- 1 | export const makeOrderSelector = () => createSelector( 2 | (state) => state.data.orders, 3 | (state, props) => props.orderNumber, 4 | (orders, orderNumber) => orders[orderNumber] 5 | ); 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*.{js,eslintrc,scss,json}] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /test/fixtures/selector-with-another-assignment/expected.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var birdSelector = createSelector('actual.js:birdSelector', function (a) { 4 | return a.b; 5 | }, function (b) { 6 | return b; 7 | }); 8 | 9 | var bird = '🐦'; 10 | -------------------------------------------------------------------------------- /test/fixtures/middleware/expected.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var stickyMiddleware = exports.stickyMiddleware = function stickyMiddleware() { 7 | return function (next) { 8 | return function (action) { 9 | return next(action); 10 | }; 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-transform-reselect-selector-name 2 | 3 | [experiment] 4 | 5 | Transform calls to [reselect](https://github.com/reactjs/reselect) `createSelector` to call with `name` as the first argument. Combine with a modified reselect library to debug `reselect` performance: https://gist.github.com/luqmaan/ed596266828847e27657619eae646328. 6 | 7 | package.json and test structure mostly copypasta'd from https://github.com/gaearon/babel-plugin-react-transform. 8 | -------------------------------------------------------------------------------- /test/fixtures/selector-factory/expected.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var makeOrderSelector = exports.makeOrderSelector = function makeOrderSelector() { 7 | return createSelector("actual.js:makeOrderSelector", function (state) { 8 | return state.data.orders; 9 | }, function (state, props) { 10 | return props.orderNumber; 11 | }, function (orders, orderNumber) { 12 | return orders[orderNumber]; 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/selectors/actual.js: -------------------------------------------------------------------------------- 1 | const cartSelector = createSelector( 2 | (state) => state.data.carts, 3 | (state) => state.ui.settings.salesChannels.editID, 4 | (carts, id) => carts[id] 5 | ); 6 | 7 | const mapStateToProps = createStructuredSelector({ 8 | id: createSelector( 9 | cartSelector, 10 | (cart) => cart.id 11 | ), 12 | currentVendor: createSelector( 13 | cartSelector, 14 | (cart) => cart.vendor 15 | ), 16 | authorizeMessage: createSelector( 17 | cartSelector, 18 | (cart) => formatAuthorizeMessage(vendorActions[cart.vendor].name) 19 | ), 20 | isSubmitting: (state) => state.ui.settings.salesChannels.isReauthorizeSubmitting, 21 | }); 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-reselect-name-transform", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "clean": "rimraf lib", 8 | "build": "babel src -d lib", 9 | "test": "mocha --compilers js:babel-register", 10 | "test:watch": "npm run test -- --watch", 11 | "prepublish": "npm run clean && npm run build" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "dependencies": { 17 | "babylon": "^6.8.0" 18 | }, 19 | "devDependencies": { 20 | "babel-cli": "^6.2.0", 21 | "babel-core": "^6.2.1", 22 | "babel-eslint": "^4.1.6", 23 | "babel-preset-es2015": "^6.1.18", 24 | "babel-register": "^6.2.0", 25 | "eslint": "^1.10.3", 26 | "eslint-plugin-react": "^3.11.2", 27 | "mocha": "^2.2.5", 28 | "rimraf": "^2.4.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/fixtures/selectors/expected.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var cartSelector = createSelector("actual.js:cartSelector", function (state) { 4 | return state.data.carts; 5 | }, function (state) { 6 | return state.ui.settings.salesChannels.editID; 7 | }, function (carts, id) { 8 | return carts[id]; 9 | }); 10 | 11 | var mapStateToProps = createStructuredSelector({ 12 | id: createSelector("actual.js:id", cartSelector, function (cart) { 13 | return cart.id; 14 | }), 15 | currentVendor: createSelector("actual.js:currentVendor", cartSelector, function (cart) { 16 | return cart.vendor; 17 | }), 18 | authorizeMessage: createSelector("actual.js:authorizeMessage", cartSelector, function (cart) { 19 | return formatAuthorizeMessage(vendorActions[cart.vendor].name); 20 | }), 21 | isSubmitting: function isSubmitting(state) { 22 | return state.ui.settings.salesChannels.isReauthorizeSubmitting; 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Ordoro 3 | 4 | permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import assert from 'assert'; 4 | import { transformFileSync } from 'babel-core'; 5 | import plugin from '../src'; 6 | 7 | function trim(str) { 8 | return str.replace(/^\s+|\s+$/, ''); 9 | } 10 | 11 | describe('finds createSelector calls', () => { 12 | const fixturesDir = path.join(__dirname, 'fixtures'); 13 | fs.readdirSync(fixturesDir).map((caseName) => { 14 | it(`should ${caseName.split('-').join(' ')}`, () => { 15 | const fixtureDir = path.join(fixturesDir, caseName); 16 | let actualPath = path.join(fixtureDir, 'actual.js'); 17 | const actual = transformFileSync(actualPath, { 18 | plugins: [plugin] 19 | }).code; 20 | 21 | if (path.sep === '\\') { 22 | // Specific case of windows, transformFileSync return code with '/' 23 | actualPath = actualPath.replace(/\\/g, '/'); 24 | } 25 | 26 | const expected = fs.readFileSync( 27 | path.join(fixtureDir, 'expected.js') 28 | ).toString().replace(/%FIXTURE_PATH%/g, actualPath); 29 | 30 | assert.equal(trim(actual), trim(expected)); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export default function ({Plugin, types: t}) { 2 | function updateArgs(call, selectorName, state) { 3 | call.arguments = [ 4 | t.stringLiteral(`${state.file.opts.sourceFileName}:${selectorName}`),, 5 | ...call.arguments 6 | ]; 7 | } 8 | 9 | return { 10 | visitor: { 11 | VariableDeclarator(path, state) { 12 | if (t.isCallExpression(path.node.init)) { 13 | if (path.node.init.callee.name === 'createSelector') { 14 | updateArgs(path.node.init, path.node.id.name, state); 15 | } 16 | } 17 | else if (t.isArrowFunctionExpression(path.node.init) && t.isCallExpression(path.node.init.body)) { 18 | if (path.node.init.body.callee.name === 'createSelector') { 19 | updateArgs(path.node.init.body, path.node.id.name, state); 20 | } 21 | } 22 | }, 23 | 24 | ObjectProperty(path, state) { 25 | if (!t.isCallExpression(path.node.value)) { 26 | return; 27 | } 28 | if (path.node.value.callee.name === 'createSelector') { 29 | updateArgs(path.node.value, path.node.key.name, state); 30 | } 31 | } 32 | } 33 | }; 34 | } 35 | --------------------------------------------------------------------------------