inline-loops.macro
Advanced tools
Comparing version 2.0.0-beta.0 to 2.0.0-beta.1
@@ -50,4 +50,3 @@ "use strict"; | ||
local = _ref.local, | ||
path = _ref.path, | ||
statement = _ref.statement; | ||
path = _ref.path; | ||
var body = handler.get('body'); | ||
@@ -89,3 +88,3 @@ var traverseState = { | ||
}); | ||
statement.insertBefore(localFn); | ||
local.contents.push(localFn); | ||
var _logic = t.callExpression(localFnName, (0, _utils.getCachedFnArgs)(local, isReduce)); | ||
@@ -119,3 +118,3 @@ return { | ||
} | ||
function getLocalReferences(path, statement, isReduce) { | ||
function getLocalReferences(path, isReduce) { | ||
var _path$get = path.get('arguments'), | ||
@@ -128,2 +127,3 @@ _path$get2 = (0, _slicedToArray2["default"])(_path$get, 2), | ||
} | ||
var contents = []; | ||
var localCollection = collection.node; | ||
@@ -136,3 +136,3 @@ if (!collection.isIdentifier()) { | ||
}); | ||
statement.insertBefore(localVariable); | ||
contents.push(localVariable); | ||
} | ||
@@ -197,2 +197,3 @@ var accumulated; | ||
collection: localCollection, | ||
contents: contents, | ||
key: localKey, | ||
@@ -219,9 +220,7 @@ length: localLength, | ||
(0, _utils.processNestedInlineLoopMacros)(collection, handlers); | ||
var statement = path.getStatementParent(); | ||
var local = getLocalReferences(path, statement); | ||
var local = getLocalReferences(path); | ||
var _getInjectedBodyAndLo = getInjectedBodyAndLogic({ | ||
handler: handler, | ||
local: local, | ||
path: path, | ||
statement: statement | ||
path: path | ||
}), | ||
@@ -232,6 +231,6 @@ injectedBody = _getInjectedBodyAndLo.injectedBody, | ||
var determination = path.scope.generateUidIdentifier('determination'); | ||
var forLoop; | ||
var loop; | ||
switch (type) { | ||
case 'every-left': | ||
forLoop = templates.every({ | ||
loop = templates.every({ | ||
BODY: injectedBody, | ||
@@ -248,3 +247,3 @@ RESULT: result, | ||
case 'some-left': | ||
forLoop = templates.some({ | ||
loop = templates.some({ | ||
BODY: injectedBody, | ||
@@ -261,3 +260,3 @@ RESULT: result, | ||
case 'every-right': | ||
forLoop = templates.everyRight({ | ||
loop = templates.everyRight({ | ||
BODY: injectedBody, | ||
@@ -273,3 +272,3 @@ RESULT: result, | ||
case 'some-right': | ||
forLoop = templates.someRight({ | ||
loop = templates.someRight({ | ||
BODY: injectedBody, | ||
@@ -285,3 +284,3 @@ RESULT: result, | ||
case 'every-object': | ||
forLoop = templates.everyObject({ | ||
loop = templates.everyObject({ | ||
BODY: injectedBody, | ||
@@ -297,3 +296,3 @@ RESULT: result, | ||
case 'some-object': | ||
forLoop = templates.someObject({ | ||
loop = templates.someObject({ | ||
BODY: injectedBody, | ||
@@ -311,4 +310,4 @@ RESULT: result, | ||
} | ||
statement.insertBefore(forLoop); | ||
(0, _utils.replaceOrRemove)(path, determination); | ||
local.contents.push(loop); | ||
(0, _utils.replaceOrRemove)(babel, path, local, templates, determination); | ||
}; | ||
@@ -332,9 +331,7 @@ } | ||
(0, _utils.processNestedInlineLoopMacros)(collection, handlers); | ||
var statement = path.getStatementParent(); | ||
var local = getLocalReferences(path, statement); | ||
var local = getLocalReferences(path); | ||
var _getInjectedBodyAndLo2 = getInjectedBodyAndLogic({ | ||
handler: handler, | ||
local: local, | ||
path: path, | ||
statement: statement | ||
path: path | ||
}), | ||
@@ -345,6 +342,6 @@ injectedBody = _getInjectedBodyAndLo2.injectedBody, | ||
var match = path.scope.generateUidIdentifier('match'); | ||
var forLoop; | ||
var loop; | ||
switch (type) { | ||
case 'find-left': | ||
forLoop = templates.find({ | ||
loop = templates.find({ | ||
BODY: injectedBody, | ||
@@ -361,3 +358,3 @@ RESULT: result, | ||
case 'find-index': | ||
forLoop = templates.findIndex({ | ||
loop = templates.findIndex({ | ||
BODY: injectedBody, | ||
@@ -374,3 +371,3 @@ RESULT: result, | ||
case 'find-last': | ||
forLoop = templates.findLast({ | ||
loop = templates.findLast({ | ||
BODY: injectedBody, | ||
@@ -386,3 +383,3 @@ RESULT: result, | ||
case 'find-last-index': | ||
forLoop = templates.findLastIndex({ | ||
loop = templates.findLastIndex({ | ||
BODY: injectedBody, | ||
@@ -398,3 +395,3 @@ RESULT: result, | ||
case 'find-object': | ||
forLoop = templates.findObject({ | ||
loop = templates.findObject({ | ||
BODY: injectedBody, | ||
@@ -410,3 +407,3 @@ RESULT: result, | ||
case 'find-key': | ||
forLoop = templates.findKey({ | ||
loop = templates.findKey({ | ||
BODY: injectedBody, | ||
@@ -424,4 +421,4 @@ RESULT: result, | ||
} | ||
statement.insertBefore(forLoop); | ||
(0, _utils.replaceOrRemove)(path, match); | ||
local.contents.push(loop); | ||
(0, _utils.replaceOrRemove)(babel, path, local, templates, match); | ||
}; | ||
@@ -445,4 +442,3 @@ } | ||
(0, _utils.processNestedInlineLoopMacros)(collection, handlers); | ||
var statement = path.getStatementParent(); | ||
var local = getLocalReferences(path, statement); | ||
var local = getLocalReferences(path); | ||
var localResults = (0, _utils.getLocalName)(path, 'results'); | ||
@@ -455,11 +451,10 @@ var isForEach = type.includes('for-each'); | ||
local: local, | ||
path: path, | ||
statement: statement | ||
path: path | ||
}), | ||
injectedBody = _getInjectedBodyAndLo3.injectedBody, | ||
logic = _getInjectedBodyAndLo3.logic; | ||
var forLoop; | ||
var loop; | ||
switch (type) { | ||
case 'map-left': | ||
forLoop = templates.map({ | ||
loop = templates.map({ | ||
BODY: injectedBody, | ||
@@ -475,3 +470,3 @@ COLLECTION: local.collection, | ||
case 'filter-left': | ||
forLoop = templates.filter({ | ||
loop = templates.filter({ | ||
BODY: injectedBody, | ||
@@ -488,3 +483,3 @@ COLLECTION: local.collection, | ||
case 'flat-map-left': | ||
forLoop = templates.flatMap({ | ||
loop = templates.flatMap({ | ||
BODY: injectedBody, | ||
@@ -501,3 +496,3 @@ COLLECTION: local.collection, | ||
case 'for-each-left': | ||
forLoop = templates.forEach({ | ||
loop = templates.forEach({ | ||
BODY: injectedBody, | ||
@@ -511,3 +506,3 @@ COLLECTION: local.collection, | ||
case 'map-right': | ||
forLoop = templates.mapRight({ | ||
loop = templates.mapRight({ | ||
BODY: injectedBody, | ||
@@ -523,3 +518,3 @@ COLLECTION: local.collection, | ||
case 'filter-right': | ||
forLoop = templates.filterRight({ | ||
loop = templates.filterRight({ | ||
BODY: injectedBody, | ||
@@ -535,3 +530,3 @@ COLLECTION: local.collection, | ||
case 'flat-map-right': | ||
forLoop = templates.flatMapRight({ | ||
loop = templates.flatMapRight({ | ||
BODY: injectedBody, | ||
@@ -547,3 +542,3 @@ COLLECTION: local.collection, | ||
case 'for-each-right': | ||
forLoop = templates.forEachRight({ | ||
loop = templates.forEachRight({ | ||
BODY: injectedBody, | ||
@@ -556,3 +551,3 @@ COLLECTION: local.collection, | ||
case 'map-object': | ||
forLoop = templates.mapObject({ | ||
loop = templates.mapObject({ | ||
BODY: injectedBody, | ||
@@ -568,3 +563,3 @@ COLLECTION: local.collection, | ||
case 'filter-object': | ||
forLoop = templates.filterObject({ | ||
loop = templates.filterObject({ | ||
BODY: injectedBody, | ||
@@ -580,3 +575,3 @@ COLLECTION: local.collection, | ||
case 'for-each-object': | ||
forLoop = templates.forEachObject({ | ||
loop = templates.forEachObject({ | ||
BODY: injectedBody, | ||
@@ -591,4 +586,4 @@ COLLECTION: local.collection, | ||
} | ||
statement.insertBefore(forLoop); | ||
(0, _utils.replaceOrRemove)(path, isForEach ? t.identifier('undefined') : localResults); | ||
local.contents.push(loop); | ||
(0, _utils.replaceOrRemove)(babel, path, local, templates, isForEach ? t.identifier('undefined') : localResults); | ||
}; | ||
@@ -613,4 +608,3 @@ } | ||
(0, _utils.processNestedInlineLoopMacros)(collection, handlers); | ||
var statement = path.getStatementParent(); | ||
var local = getLocalReferences(path, statement, true); | ||
var local = getLocalReferences(path, true); | ||
var _getInjectedBodyAndLo4 = getInjectedBodyAndLogic({ | ||
@@ -620,4 +614,3 @@ handler: handler, | ||
local: local, | ||
path: path, | ||
statement: statement | ||
path: path | ||
}), | ||
@@ -636,6 +629,6 @@ injectedBody = _getInjectedBodyAndLo4.injectedBody, | ||
var start = t.numericLiteral(initialValue ? 0 : 1); | ||
var forLoop; | ||
var loop; | ||
switch (type) { | ||
case 'left': | ||
forLoop = templates.reduce({ | ||
loop = templates.reduce({ | ||
ACCUMULATED: local.accumulated, | ||
@@ -653,3 +646,3 @@ BODY: injectedBody, | ||
case 'right': | ||
forLoop = templates.reduceRight({ | ||
loop = templates.reduceRight({ | ||
ACCUMULATED: local.accumulated, | ||
@@ -669,3 +662,3 @@ BODY: injectedBody, | ||
var shouldSkip = t.booleanLiteral(!initialValue); | ||
forLoop = templates.reduceObject({ | ||
loop = templates.reduceObject({ | ||
ACCUMULATED: local.accumulated, | ||
@@ -686,4 +679,4 @@ BODY: injectedBody, | ||
} | ||
statement.insertBefore(forLoop); | ||
(0, _utils.replaceOrRemove)(path, local.accumulated); | ||
local.contents.push(loop); | ||
(0, _utils.replaceOrRemove)(babel, path, local, templates, local.accumulated); | ||
}; | ||
@@ -690,0 +683,0 @@ } |
@@ -9,3 +9,3 @@ "use strict"; | ||
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); | ||
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19, _templateObject20, _templateObject21, _templateObject22, _templateObject23, _templateObject24, _templateObject25, _templateObject26, _templateObject27, _templateObject28; | ||
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19, _templateObject20, _templateObject21, _templateObject22, _templateObject23, _templateObject24, _templateObject25, _templateObject26, _templateObject27, _templateObject28, _templateObject29; | ||
function createTemplates(_ref) { | ||
@@ -31,12 +31,13 @@ var template = _ref.template; | ||
var localVariable = template(_templateObject18 || (_templateObject18 = (0, _taggedTemplateLiteral2["default"])(["\n const LOCAL = VALUE;\n"]))); | ||
var map = template(_templateObject19 || (_templateObject19 = (0, _taggedTemplateLiteral2["default"])(["\n const LENGTH = COLLECTION.length;\n const RESULTS = Array(LENGTH);\n\tfor (let KEY = 0, VALUE; KEY < LENGTH; ++KEY) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULTS[KEY] = LOGIC;\n }\n"]))); | ||
var mapObject = template(_templateObject20 || (_templateObject20 = (0, _taggedTemplateLiteral2["default"])(["\n const RESULTS = {};\n let VALUE,\n RESULT;\n for (const KEY in COLLECTION) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULTS[KEY] = LOGIC;\n }\n"]))); | ||
var mapRight = template(_templateObject21 || (_templateObject21 = (0, _taggedTemplateLiteral2["default"])(["\n const LENGTH = COLLECTION.length;\n let KEY = LENGTH;\n const RESULTS = Array(LENGTH);\n for (let VALUE; --KEY >= 0;) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULTS[LENGTH - KEY - 1] = LOGIC;\n }\n"]))); | ||
var nthLastItem = template(_templateObject22 || (_templateObject22 = (0, _taggedTemplateLiteral2["default"])(["\n COLLECTION[COLLECTION.length - COUNT]\n"]))); | ||
var reduce = template(_templateObject23 || (_templateObject23 = (0, _taggedTemplateLiteral2["default"])(["\n let ACCUMULATED = INITIAL;\n for (let KEY = START, LENGTH = COLLECTION.length, VALUE; KEY < LENGTH; ++KEY) {\n VALUE = COLLECTION[KEY];\n BODY\n ACCUMULATED = LOGIC;\n }\n"]))); | ||
var reduceObject = template(_templateObject24 || (_templateObject24 = (0, _taggedTemplateLiteral2["default"])(["\n let SKIP = SHOULD_SKIP,\n ACCUMULATED = INITIAL,\n VALUE;\n for (const KEY in COLLECTION) {\n VALUE = COLLECTION[KEY];\n\n if (SKIP) {\n ACCUMULATED = VALUE;\n SKIP = false;\n continue;\n }\n\n BODY\n ACCUMULATED = LOGIC;\n }\n"]))); | ||
var reduceRight = template(_templateObject25 || (_templateObject25 = (0, _taggedTemplateLiteral2["default"])(["\n let ACCUMULATED = INITIAL;\n for (let KEY = COLLECTION.length - START, VALUE; --KEY >= START;) {\n VALUE = COLLECTION[KEY];\n BODY\n ACCUMULATED = LOGIC;\n }\n"]))); | ||
var some = template(_templateObject26 || (_templateObject26 = (0, _taggedTemplateLiteral2["default"])(["\n let DETERMINATION = false;\n for (let KEY = 0, LENGTH = COLLECTION.length, VALUE, RESULT; KEY < LENGTH; ++KEY) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULT = LOGIC;\n\n if (RESULT) {\n DETERMINATION = true;\n break;\n }\n }\n"]))); | ||
var someObject = template(_templateObject27 || (_templateObject27 = (0, _taggedTemplateLiteral2["default"])(["\n let DETERMINATION = false,\n VALUE,\n RESULT;\n for (const KEY in COLLECTION) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULT = LOGIC;\n\n if (RESULT) {\n DETERMINATION = true;\n break;\n }\n }\n"]))); | ||
var someRight = template(_templateObject28 || (_templateObject28 = (0, _taggedTemplateLiteral2["default"])(["\n const DETERMINATION = false;\n for (let KEY = COLLECTION.length, VALUE, RESULT; --KEY >= 0;) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULT = LOGIC;\n\n if (RESULT) {\n DETERMINATION = true;\n break;\n }\n }\n"]))); | ||
var iife = template(_templateObject19 || (_templateObject19 = (0, _taggedTemplateLiteral2["default"])(["\n (() => {\n BODY\n })();\n"]))); | ||
var map = template(_templateObject20 || (_templateObject20 = (0, _taggedTemplateLiteral2["default"])(["\n const LENGTH = COLLECTION.length;\n const RESULTS = Array(LENGTH);\n\tfor (let KEY = 0, VALUE; KEY < LENGTH; ++KEY) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULTS[KEY] = LOGIC;\n }\n"]))); | ||
var mapObject = template(_templateObject21 || (_templateObject21 = (0, _taggedTemplateLiteral2["default"])(["\n const RESULTS = {};\n let VALUE,\n RESULT;\n for (const KEY in COLLECTION) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULTS[KEY] = LOGIC;\n }\n"]))); | ||
var mapRight = template(_templateObject22 || (_templateObject22 = (0, _taggedTemplateLiteral2["default"])(["\n const LENGTH = COLLECTION.length;\n let KEY = LENGTH;\n const RESULTS = Array(LENGTH);\n for (let VALUE; --KEY >= 0;) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULTS[LENGTH - KEY - 1] = LOGIC;\n }\n"]))); | ||
var nthLastItem = template(_templateObject23 || (_templateObject23 = (0, _taggedTemplateLiteral2["default"])(["\n COLLECTION[COLLECTION.length - COUNT]\n"]))); | ||
var reduce = template(_templateObject24 || (_templateObject24 = (0, _taggedTemplateLiteral2["default"])(["\n let ACCUMULATED = INITIAL;\n for (let KEY = START, LENGTH = COLLECTION.length, VALUE; KEY < LENGTH; ++KEY) {\n VALUE = COLLECTION[KEY];\n BODY\n ACCUMULATED = LOGIC;\n }\n"]))); | ||
var reduceObject = template(_templateObject25 || (_templateObject25 = (0, _taggedTemplateLiteral2["default"])(["\n let SKIP = SHOULD_SKIP,\n ACCUMULATED = INITIAL,\n VALUE;\n for (const KEY in COLLECTION) {\n VALUE = COLLECTION[KEY];\n\n if (SKIP) {\n ACCUMULATED = VALUE;\n SKIP = false;\n continue;\n }\n\n BODY\n ACCUMULATED = LOGIC;\n }\n"]))); | ||
var reduceRight = template(_templateObject26 || (_templateObject26 = (0, _taggedTemplateLiteral2["default"])(["\n let ACCUMULATED = INITIAL;\n for (let KEY = COLLECTION.length - START, VALUE; --KEY >= START;) {\n VALUE = COLLECTION[KEY];\n BODY\n ACCUMULATED = LOGIC;\n }\n"]))); | ||
var some = template(_templateObject27 || (_templateObject27 = (0, _taggedTemplateLiteral2["default"])(["\n let DETERMINATION = false;\n for (let KEY = 0, LENGTH = COLLECTION.length, VALUE, RESULT; KEY < LENGTH; ++KEY) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULT = LOGIC;\n\n if (RESULT) {\n DETERMINATION = true;\n break;\n }\n }\n"]))); | ||
var someObject = template(_templateObject28 || (_templateObject28 = (0, _taggedTemplateLiteral2["default"])(["\n let DETERMINATION = false,\n VALUE,\n RESULT;\n for (const KEY in COLLECTION) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULT = LOGIC;\n\n if (RESULT) {\n DETERMINATION = true;\n break;\n }\n }\n"]))); | ||
var someRight = template(_templateObject29 || (_templateObject29 = (0, _taggedTemplateLiteral2["default"])(["\n const DETERMINATION = false;\n for (let KEY = COLLECTION.length, VALUE, RESULT; --KEY >= 0;) {\n VALUE = COLLECTION[KEY];\n BODY\n RESULT = LOGIC;\n\n if (RESULT) {\n DETERMINATION = true;\n break;\n }\n }\n"]))); | ||
return { | ||
@@ -60,2 +61,3 @@ every: every, | ||
forEachRight: forEachRight, | ||
iife: iife, | ||
localVariable: localVariable, | ||
@@ -62,0 +64,0 @@ map: map, |
@@ -12,2 +12,3 @@ "use strict"; | ||
exports.handleInvalidUsage = handleInvalidUsage; | ||
exports.isConditionalUsage = isConditionalUsage; | ||
exports.isMacroHandlerName = isMacroHandlerName; | ||
@@ -96,2 +97,6 @@ exports.processNestedInlineLoopMacros = processNestedInlineLoopMacros; | ||
} | ||
function isConditionalUsage(path) { | ||
var parentPath = path.parentPath; | ||
return parentPath.isConditionalExpression() || parentPath.isLogicalExpression(); | ||
} | ||
function isMacroHandlerName(handlers, name) { | ||
@@ -116,9 +121,33 @@ return !!(name && handlers[name]); | ||
} | ||
function replaceOrRemove(path, replacement) { | ||
var parentPath = path.parentPath; | ||
if (parentPath !== null && parentPath !== void 0 && parentPath.isExpressionStatement()) { | ||
path.remove(); | ||
function replaceOrRemove(_ref, path, local, templates, replacement) { | ||
var _functionParent$get; | ||
var t = _ref.types; | ||
var functionParent = path.getFunctionParent(); | ||
var contents = functionParent === null || functionParent === void 0 || (_functionParent$get = functionParent.get('body')) === null || _functionParent$get === void 0 ? void 0 : _functionParent$get.get('body'); | ||
var shouldWrapInIife = functionParent && (Array.isArray(contents) && contents.length > 1 || local.contents.length > 1 || isConditionalUsage(path)); | ||
if (shouldWrapInIife) { | ||
if (!t.isIdentifier(replacement, { | ||
name: 'undefined' | ||
})) { | ||
local.contents.push(t.returnStatement(replacement)); | ||
} | ||
var iife = templates.iife({ | ||
BODY: local.contents.flat() | ||
}); | ||
path.replaceWith(iife.expression); | ||
} else { | ||
path.replaceWith(replacement); | ||
var statement = path.getStatementParent(); | ||
if (!statement) { | ||
throw new _babelPluginMacros.MacroError('Could not insert contents because the statement was indeterminable.'); | ||
} | ||
local.contents.forEach(function (content) { | ||
statement.insertBefore(content); | ||
}); | ||
var parentPath = path.parentPath; | ||
if (parentPath !== null && parentPath !== void 0 && parentPath.isExpressionStatement()) { | ||
path.remove(); | ||
} else { | ||
path.replaceWith(replacement); | ||
} | ||
} | ||
} |
@@ -61,3 +61,3 @@ { | ||
"typings": "./index.d.ts", | ||
"version": "2.0.0-beta.0" | ||
"version": "2.0.0-beta.1" | ||
} |
190
README.md
@@ -17,3 +17,3 @@ # inline-loops.macro | ||
- [`*Object` methods do not perform `hasOwnProperty` check](#object-methods-do-not-perform-hasownproperty-check) | ||
- [`findIndex` vs `findKey`](#findindex-vs-findkey) | ||
- [`find*` methods](#find-methods) | ||
- [Development](#development) | ||
@@ -31,3 +31,3 @@ | ||
```javascript | ||
```js | ||
import { map, reduce, someObject } from 'inline-loops.macro'; | ||
@@ -57,6 +57,6 @@ | ||
- `find` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)) | ||
- `findRight` => same as `find`, but iterating in reverse | ||
- `findLast` => same as `find`, but iterating in reverse ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLast)) | ||
- `findObject` => same as `find` but iterating over objects intead of arrays | ||
- `findIndex` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)) | ||
- `findIndexRight` => same as `findIndex`, but iterating in reverse | ||
- `findLastIndex` => same as `findIndex`, but iterating in reverse ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex)) | ||
- `findKey` => same as `findIndex` but iterating over objects intead of arrays | ||
@@ -73,3 +73,3 @@ - `flatMap` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)) | ||
- `reduce` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)) | ||
- `reduceRight` => same as `reduce`, but iterating in reverse | ||
- `reduceRight` => same as `reduce`, but iterating in reverse ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight)) | ||
- `reduceObject` => same as `reduce` but iterating over objects intead of arrays | ||
@@ -84,3 +84,3 @@ - `some` ([MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)) | ||
```javascript | ||
```js | ||
// this | ||
@@ -90,10 +90,9 @@ const foo = map(array, fn); | ||
// becomes this | ||
let _result = []; | ||
for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) { | ||
const _length = array.length; | ||
const _results = Array(_length); | ||
for (let _key = 0, _value; _key < _length; ++_key) { | ||
_value = array[_key]; | ||
_result.push(fn(_value, _key, array)); | ||
_results[_key] = fn(_value, _key, array); | ||
} | ||
const foo = _result; | ||
const foo = _results; | ||
``` | ||
@@ -107,15 +106,14 @@ | ||
```javascript | ||
```js | ||
// this | ||
const doubled = map(array, value => value * 2); | ||
const doubled = map(array, (value) => value * 2); | ||
// becomes this | ||
let _result = []; | ||
for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) { | ||
const _length = array.length; | ||
const _results = Array(_length); | ||
for (let _key = 0, _value; _key < _length; ++_key) { | ||
_value = array[_key]; | ||
_result.push(_value * 2); | ||
_results[_key] = _value * 2; | ||
} | ||
const doubled = _result; | ||
const doubled = _results; | ||
``` | ||
@@ -125,30 +123,36 @@ | ||
```javascript | ||
```js | ||
// this | ||
const isAllTuples = every(array, tuple => every(tuple, value => Array.isArray(value) && value.length === 2)); | ||
const isAllTuples = every(array, (tuple) => | ||
every(tuple, (value) => Array.isArray(value) && value.length === 2), | ||
); | ||
// becomes this | ||
let _result = true; | ||
for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) { | ||
_value = array[_key]; | ||
let _result2 = true; | ||
for (let _key2 = 0, _length2 = _value.length, _value2; _key2 < _length2; ++_key2) { | ||
_value2 = _value[_key2]; | ||
if (!(Array.isArray(_value2) && _value2.length === 2)) { | ||
_result2 = false; | ||
let _determination = true; | ||
for ( | ||
let _key = 0, _length = array.length, _tuple, _result; | ||
_key < _length; | ||
++_key | ||
) { | ||
_tuple = array[_key]; | ||
let _determination2 = true; | ||
for ( | ||
let _key2 = 0, _length2 = _tuple.length, _value, _result2; | ||
_key2 < _length2; | ||
++_key2 | ||
) { | ||
_value = _tuple[_key2]; | ||
_result2 = Array.isArray(_value) && _value.length === 2; | ||
if (!_result2) { | ||
_determination2 = false; | ||
break; | ||
} | ||
} | ||
if (!_result2) { | ||
_result = false; | ||
_result = _determination2; | ||
if (!_result) { | ||
_determination = false; | ||
break; | ||
} | ||
} | ||
const isAllTuples = _result; | ||
const isAllTuples = _determination; | ||
``` | ||
@@ -163,4 +167,5 @@ | ||
- When the `return` statement is not top-level (same reason as with multiple `return`s) | ||
- The `this` keyword is used (closure must be maintained to guarantee correct value) | ||
That means if you are cranking every last ounce of performance out of this macro, you want to get cozy with ternaries. | ||
That means if you are cranking every last ounce of performance out of this macro, you may want to get cozy with ternaries. | ||
@@ -171,3 +176,3 @@ ```js | ||
// this will bail out to storing the function and calling it in the loop | ||
const deopted = map(array, value => { | ||
const deopted = map(array, (value) => { | ||
if (value % 2 === 0) { | ||
@@ -181,3 +186,3 @@ return 'even'; | ||
// this will inline the operation and avoid function calls | ||
const inlined = map(array, value => (value % 2 === 0 ? 'even' : 'odd')); | ||
const inlined = map(array, (value) => (value % 2 === 0 ? 'even' : 'odd')); | ||
``` | ||
@@ -189,54 +194,2 @@ | ||
### Conditionals do not delay execution | ||
If you do something like this with standard JS: | ||
```js | ||
return isFoo ? array.map(v => v * 2) : array; | ||
``` | ||
The `array` is only mapped over if `isFoo` is true. However, because we are inlining these calls into `for` loops in the scope they operate in, this conditional calling does not apply with this macro. | ||
```js | ||
// this | ||
return isFoo ? map(array, v => v * 2) : array; | ||
// turns into this | ||
let _result = []; | ||
for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) { | ||
_value = array[_key]; | ||
_result[_key] = _value * 2; | ||
} | ||
return isFoo ? _result : array; | ||
``` | ||
Notice the mapping occurs whether the condition is met or not. If you want to ensure this conditionality is maintained, you should use an `if` block instead: | ||
```js | ||
// this | ||
if (isFoo) { | ||
return map(array, v => v * 2); | ||
} | ||
return array; | ||
// turns into this | ||
if (isFoo) { | ||
let _result = []; | ||
for (let _key = 0, _length = array.length, _value; _key < _length; ++_key) { | ||
_value = array[_key]; | ||
_result[_key] = _value * 2; | ||
} | ||
return _result; | ||
} | ||
return array; | ||
``` | ||
This will ensure the potentially expensive computation only occurs when necessary. | ||
### `*Object` methods do not perform `hasOwnProperty` check | ||
@@ -246,5 +199,5 @@ | ||
```javascript | ||
```js | ||
// this | ||
const doubled = mapObject(object, value => value * 2); | ||
const doubled = mapObject(object, (value) => value * 2); | ||
@@ -266,25 +219,11 @@ // becomes this | ||
If you need to incorporate this, you can do it one of two ways: | ||
If you need to incorporate this, you can just filter prior to the operation: | ||
**Add filtering (iterates twice, but arguably cleaner semantics)** | ||
```javascript | ||
const raw = mapObject(object, (value, key) => (object.hasOwnProperty(key) ? value * 2 : null)); | ||
const doubled = filterObject(raw, value => value !== null); | ||
```js | ||
const filtered = filterObject(object, (_, key) => Object.hasOwn(object, key)); | ||
const doubled = mapObject(filtered, (value) => value * 2); | ||
``` | ||
**Use reduce instead (iterates only once, but a little harder to grok)** | ||
### `find*` methods | ||
```javascript | ||
const doubled = reduceObject(object, (_doubled, value, key) => { | ||
if (object.hasOwnProperty(key)) { | ||
_doubled[key] = value * 2; | ||
} | ||
return _doubled; | ||
}); | ||
``` | ||
### `findIndex` vs `findKey` | ||
Most of the operations follow the same naming conventions: | ||
@@ -296,4 +235,13 @@ | ||
The exception to this is `findIndex` / `findIndexRight` (which are specific to arrays) and `findKey` (which is specific to objects). The rationale should be obvious (arrays only have indices, objects only have keys), but because it is the only exception to the rule I wanted to call it out. | ||
The exception to this is the collection of `find`-related methods: | ||
- `find` | ||
- `findLast` | ||
- `findObject` | ||
- `findIndex` | ||
- `findLastIndex` | ||
- `findKey` | ||
The reason for `findLast` / `findLastIndex` instead of `findRight` / `findIndexRight` is because unlike all the other right-direction methods, those are part of the ES spec. Additionally, the reason for `findIndex` vs `findKey` is semantic, as objects have keys and arrays have indices. | ||
## Development | ||
@@ -304,10 +252,10 @@ | ||
- `build` => runs babel to transform the macro for legacy NodeJS support | ||
- `copy:types` => copies `index.d.ts` to `build` | ||
- `dist` => runs `build` and `copy:types` | ||
- `clean`=> remove any files from `dist` | ||
- `lint` => runs ESLint against all files in the `src` folder | ||
- `lint:fix` => runs `lint`, fixing any errors if possible | ||
- `prepublishOnly` => run `lint`, `test`, `test:coverage`, and `dist` | ||
- `release` => release new version (expects globally-installed `release-it`) | ||
- `release:beta` => release new beta version (expects globally-installed `release-it`) | ||
- `prepublishOnly` => run `lint`, `typecheck`, `test`, `clean`, `and `dist` | ||
- `release` => release new version | ||
- `release:beta` => release new beta version | ||
- `test` => run jest tests | ||
- `test:watch` => run `test`, but with persistent watcher | ||
- `typecheck` => run `tsc` against the codebase |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
65486
11
1239
0
246