memoize-one
Advanced tools
Comparing version 5.1.1 to 5.2.0
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var safeIsNaN = Number.isNaN || | ||
function ponyfill(value) { | ||
return typeof value === 'number' && value !== value; | ||
}; | ||
function isEqual(first, second) { | ||
if (first === second) { | ||
return true; | ||
} | ||
if (safeIsNaN(first) && safeIsNaN(second)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
function areInputsEqual(newInputs, lastInputs) { | ||
@@ -8,3 +23,3 @@ if (newInputs.length !== lastInputs.length) { | ||
for (var i = 0; i < newInputs.length; i++) { | ||
if (newInputs[i] !== lastInputs[i]) { | ||
if (!isEqual(newInputs[i], lastInputs[i])) { | ||
return false; | ||
@@ -39,2 +54,3 @@ } | ||
module.exports = memoizeOne; | ||
exports.default = memoizeOne; | ||
exports.memoizeOne = memoizeOne; |
export declare type EqualityFn = (newArgs: any[], lastArgs: any[]) => boolean; | ||
export default function memoizeOne<ResultFn extends (this: any, ...newArgs: any[]) => ReturnType<ResultFn>>(resultFn: ResultFn, isEqual?: EqualityFn): ResultFn; | ||
declare function memoizeOne<ResultFn extends (this: any, ...newArgs: any[]) => ReturnType<ResultFn>>(resultFn: ResultFn, isEqual?: EqualityFn): ResultFn; | ||
export default memoizeOne; | ||
export { memoizeOne }; |
@@ -0,1 +1,14 @@ | ||
var safeIsNaN = Number.isNaN || | ||
function ponyfill(value) { | ||
return typeof value === 'number' && value !== value; | ||
}; | ||
function isEqual(first, second) { | ||
if (first === second) { | ||
return true; | ||
} | ||
if (safeIsNaN(first) && safeIsNaN(second)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
function areInputsEqual(newInputs, lastInputs) { | ||
@@ -6,3 +19,3 @@ if (newInputs.length !== lastInputs.length) { | ||
for (var i = 0; i < newInputs.length; i++) { | ||
if (newInputs[i] !== lastInputs[i]) { | ||
if (!isEqual(newInputs[i], lastInputs[i])) { | ||
return false; | ||
@@ -38,1 +51,2 @@ } | ||
export default memoizeOne; | ||
export { memoizeOne }; |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global = global || self, global.memoizeOne = factory()); | ||
}(this, function () { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.memoizeOne = {})); | ||
}(this, (function (exports) { 'use strict'; | ||
var safeIsNaN = Number.isNaN || | ||
function ponyfill(value) { | ||
return typeof value === 'number' && value !== value; | ||
}; | ||
function isEqual(first, second) { | ||
if (first === second) { | ||
return true; | ||
} | ||
if (safeIsNaN(first) && safeIsNaN(second)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
function areInputsEqual(newInputs, lastInputs) { | ||
@@ -12,3 +25,3 @@ if (newInputs.length !== lastInputs.length) { | ||
for (var i = 0; i < newInputs.length; i++) { | ||
if (newInputs[i] !== lastInputs[i]) { | ||
if (!isEqual(newInputs[i], lastInputs[i])) { | ||
return false; | ||
@@ -43,4 +56,7 @@ } | ||
return memoizeOne; | ||
exports.default = memoizeOne; | ||
exports.memoizeOne = memoizeOne; | ||
})); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
}))); |
@@ -1,1 +0,1 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).memoizeOne=n()}(this,function(){"use strict";function e(e,n){if(e.length!==n.length)return!1;for(var t=0;t<e.length;t++)if(e[t]!==n[t])return!1;return!0}return function(n,t){var r;void 0===t&&(t=e);var i,f=[],o=!1;return function(){for(var e=[],u=0;u<arguments.length;u++)e[u]=arguments[u];return o&&r===this&&t(e,f)?i:(i=n.apply(this,e),o=!0,r=this,f=e,i)}}}); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).memoizeOne={})}(this,(function(e){"use strict";var n=Number.isNaN||function(e){return"number"==typeof e&&e!=e};function t(e,t){if(e.length!==t.length)return!1;for(var r=0;r<e.length;r++)if(i=e[r],o=t[r],!(i===o||n(i)&&n(o)))return!1;var i,o;return!0}function r(e,n){var r;void 0===n&&(n=t);var i,o=[],f=!1;return function(){for(var t=[],u=0;u<arguments.length;u++)t[u]=arguments[u];return f&&r===this&&n(t,o)||(i=e.apply(this,t),f=!0,r=this,o=t),i}}e.default=r,e.memoizeOne=r,Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "memoize-one", | ||
"version": "5.1.1", | ||
"version": "5.2.0", | ||
"description": "A memoization library which only remembers the latest invocation", | ||
@@ -19,2 +19,20 @@ "main": "dist/memoize-one.cjs.js", | ||
], | ||
"size-limit": [ | ||
{ | ||
"path": "dist/memoize-one.min.js", | ||
"limit": "214B" | ||
}, | ||
{ | ||
"path": "dist/memoize-one.js", | ||
"limit": "216B" | ||
}, | ||
{ | ||
"path": "dist/memoize-one.cjs.js", | ||
"limit": "213B" | ||
}, | ||
{ | ||
"path": "dist/memoize-one.esm.js", | ||
"limit": "218B" | ||
} | ||
], | ||
"keywords": [ | ||
@@ -28,24 +46,26 @@ "memoize", | ||
"devDependencies": { | ||
"@types/jest": "^24.0.18", | ||
"@size-limit/preset-small-lib": "^4.10.2", | ||
"@types/jest": "^26.0.22", | ||
"@types/lodash.isequal": "^4.5.5", | ||
"@typescript-eslint/eslint-plugin": "^2.0.0", | ||
"@typescript-eslint/parser": "^2.0.0", | ||
"@typescript-eslint/eslint-plugin": "^4.22.0", | ||
"@typescript-eslint/parser": "^4.22.0", | ||
"benchmark": "^2.1.4", | ||
"cross-env": "^5.2.0", | ||
"eslint": "6.2.0", | ||
"eslint-config-prettier": "^6.1.0", | ||
"eslint-plugin-jest": "^22.15.1", | ||
"eslint-plugin-prettier": "^3.1.0", | ||
"jest": "^24.9.0", | ||
"cross-env": "^7.0.3", | ||
"eslint": "7.24.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"eslint-plugin-jest": "^24.3.5", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"jest": "^26.6.3", | ||
"lodash.isequal": "^4.5.0", | ||
"prettier": "1.18.2", | ||
"rimraf": "3.0.0", | ||
"rollup": "^1.19.4", | ||
"prettier": "2.2.1", | ||
"rimraf": "3.0.2", | ||
"rollup": "^2.45.1", | ||
"rollup-plugin-replace": "^2.2.0", | ||
"rollup-plugin-terser": "^5.1.1", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"rollup-plugin-typescript": "^1.0.1", | ||
"ts-jest": "^24.0.2", | ||
"ts-node": "^8.3.0", | ||
"tslib": "^1.10.0", | ||
"typescript": "^3.5.3" | ||
"size-limit": "^4.10.2", | ||
"ts-jest": "^26.5.4", | ||
"ts-node": "^9.1.1", | ||
"tslib": "^2.2.0", | ||
"typescript": "^4.2.4" | ||
}, | ||
@@ -58,2 +78,3 @@ "config": { | ||
"test": "yarn jest", | ||
"test:size": "yarn build && size-limit", | ||
"typecheck": "yarn tsc --noEmit", | ||
@@ -60,0 +81,0 @@ "prettier:check": "yarn prettier --debug-check $npm_package_config_prettier_target", |
@@ -5,2 +5,4 @@ # memoize-one | ||
> Also [async version](https://github.com/microlinkhq/async-memoize-one). | ||
[![Build Status](https://travis-ci.org/alexreardon/memoize-one.svg?branch=master)](https://travis-ci.org/alexreardon/memoize-one) | ||
@@ -20,3 +22,3 @@ [![npm](https://img.shields.io/npm/v/memoize-one.svg)](https://www.npmjs.com/package/memoize-one) | ||
```js | ||
import memoizeOne from 'memoize-one'; | ||
import { memoizeOne } from 'memoize-one'; | ||
@@ -43,2 +45,11 @@ const add = (a, b) => a + b; | ||
You can use the default export or a named import | ||
```js | ||
// Named import | ||
import { memoizeOne } from 'memoize-one'; | ||
// Default import | ||
import memoizeOne from 'memoize-one'; | ||
``` | ||
## Installation | ||
@@ -54,2 +65,53 @@ | ||
## Function argument equality | ||
By default, we apply our own _fast_ and _naive_ equality function to determine whether the arguments provided to your function are equal. You can see the full code here: [are-inputs-equal.ts](https://github.com/alexreardon/memoize-one/blob/master/src/are-inputs-equal.ts). | ||
(By default) function arguments are considered equal if: | ||
1. there is same amount of arguments | ||
2. each new argument has strict equality (`===`) with the previous argument | ||
3. **[special case]** if the arguments are not `===` and they are both `NaN` then the argument is treated as equal | ||
What this looks like in practice: | ||
```js | ||
import { memoizeOne } from 'memoize-one'; | ||
// add all numbers provided to the function | ||
const add = (...args = []) => | ||
args.reduce((current, value) => { | ||
return current + value; | ||
}, 0); | ||
const memoizedAdd = memoizeOne(add); | ||
``` | ||
> 1. there is same amount of arguments | ||
```js | ||
memoizedAdd(1, 2); | ||
// the amount of arguments has changed, so underlying add function is called | ||
memoizedAdd(1, 2, 3); | ||
``` | ||
> 2. new arguments have strict equality (`===`) with the previous argument | ||
```js | ||
memoizedAdd(1, 2); | ||
// each argument is `===` to the last argument, so cache is used | ||
memoizedAdd(1, 2); | ||
// second argument has changed, so add function is called again | ||
memoizedAdd(1, 3); | ||
// the first value is not `===` to the previous first value (1 !== 3), so add function is called again | ||
memoizedAdd(3, 1); | ||
``` | ||
> 3. **[special case]** if the arguments are not `===` and they are both `NaN` then the argument is treated as equal | ||
```js | ||
memoizedAdd(NaN); | ||
// Even though NaN !== NaN these arguments are treated as equal | ||
memoizedAdd(NaN); | ||
``` | ||
## Custom equality function | ||
@@ -79,4 +141,2 @@ | ||
The default equality function is a shallow equal check of all arguments (each argument is compared with `===`). If the `length` of arguments change, then the default equality function makes no shallow equality checks. You are welcome to decide if you want to return `false` if the `length` of the arguments is not equal | ||
A custom equality function needs to compare `Arrays`. The `newArgs` array will be a new reference every time so a simple `newArgs === lastArgs` will always return `false`. | ||
@@ -86,11 +146,11 @@ | ||
Here is an example that uses a `lodash.isequal` deep equal equality check | ||
Here is an example that uses a [dequal](https://github.com/lukeed/dequal) deep equal equality check | ||
> `lodash.isequal` correctly handles deep comparing two arrays | ||
> `dequal` correctly handles deep comparing two arrays | ||
```js | ||
import memoizeOne from 'memoize-one'; | ||
import isDeepEqual from 'lodash.isequal'; | ||
import { dequal as isDeepEqual } from 'dequal'; | ||
const identity = x => x; | ||
const identity = (x) => x; | ||
@@ -216,3 +276,3 @@ const shallowMemoized = memoizeOne(identity); | ||
- Tested with all built in [JavaScript types](https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch1.md). | ||
- Tested with all built in [JavaScript types](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/types%20%26%20grammar/ch1.md). | ||
- 100% code coverage | ||
@@ -219,0 +279,0 @@ - [Continuous integration](https://travis-ci.org/alexreardon/memoize-one) to run tests and type checks. |
@@ -0,1 +1,23 @@ | ||
// Number.isNaN as it is not supported in IE11 so conditionally using ponyfill | ||
// Using Number.isNaN where possible as it is ~10% faster | ||
const safeIsNaN = | ||
Number.isNaN || | ||
function ponyfill(value: unknown): boolean { | ||
return typeof value === 'number' && value !== value; | ||
}; | ||
function isEqual(first: unknown, second: unknown): boolean { | ||
if (first === second) { | ||
return true; | ||
} | ||
// Special case for NaN (NaN !== NaN) | ||
if (safeIsNaN(first) && safeIsNaN(second)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
export default function areInputsEqual( | ||
@@ -11,6 +33,4 @@ newInputs: readonly unknown[], | ||
// https://github.com/alexreardon/memoize-one/pull/59 | ||
for (let i = 0; i < newInputs.length; i++) { | ||
// using shallow equality check | ||
if (newInputs[i] !== lastInputs[i]) { | ||
if (!isEqual(newInputs[i], lastInputs[i])) { | ||
return false; | ||
@@ -17,0 +37,0 @@ } |
@@ -6,3 +6,3 @@ import areInputsEqual from './are-inputs-equal'; | ||
export default function memoizeOne< | ||
function memoizeOne< | ||
// Need to use 'any' rather than 'unknown' here as it has | ||
@@ -35,1 +35,6 @@ // The correct Generic narrowing behaviour. | ||
} | ||
// default export | ||
export default memoizeOne; | ||
// named export | ||
export { memoizeOne }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
22442
227
276
24
1