Socket
Socket
Sign inDemoInstall

memoize-one

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

memoize-one - npm Package Compare versions

Comparing version 4.1.0 to 5.0.0

16

dist/memoize-one.cjs.js
'use strict';
var simpleIsEqual = function simpleIsEqual(a, b) {
return a === b;
var shallowEqual = function shallowEqual(newValue, oldValue) {
return newValue === oldValue;
};
var simpleIsEqual = function simpleIsEqual(newArgs, lastArgs) {
return newArgs.length === lastArgs.length && newArgs.every(function (newArg, index) {
return shallowEqual(newArg, lastArgs[index]);
});
};
function index (resultFn, isEqual) {

@@ -17,6 +23,2 @@ if (isEqual === void 0) {

var isNewArgEqualToLast = function isNewArgEqualToLast(newArg, index) {
return isEqual(newArg, lastArgs[index], index);
};
var result = function result() {

@@ -27,3 +29,3 @@ for (var _len = arguments.length, newArgs = new Array(_len), _key = 0; _key < _len; _key++) {

if (calledOnce && lastThis === this && newArgs.length === lastArgs.length && newArgs.every(isNewArgEqualToLast)) {
if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
return lastResult;

@@ -30,0 +32,0 @@ }

@@ -1,5 +0,11 @@

var simpleIsEqual = function simpleIsEqual(a, b) {
return a === b;
var shallowEqual = function shallowEqual(newValue, oldValue) {
return newValue === oldValue;
};
var simpleIsEqual = function simpleIsEqual(newArgs, lastArgs) {
return newArgs.length === lastArgs.length && newArgs.every(function (newArg, index) {
return shallowEqual(newArg, lastArgs[index]);
});
};
function index (resultFn, isEqual) {

@@ -15,6 +21,2 @@ if (isEqual === void 0) {

var isNewArgEqualToLast = function isNewArgEqualToLast(newArg, index) {
return isEqual(newArg, lastArgs[index], index);
};
var result = function result() {

@@ -25,3 +27,3 @@ for (var _len = arguments.length, newArgs = new Array(_len), _key = 0; _key < _len; _key++) {

if (calledOnce && lastThis === this && newArgs.length === lastArgs.length && newArgs.every(isNewArgEqualToLast)) {
if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
return lastResult;

@@ -28,0 +30,0 @@ }

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.memoizeOne = factory());
}(this, (function () { 'use strict';
global.memoizeOne = factory();
}(typeof self !== 'undefined' ? self : this, function () { 'use strict';
var simpleIsEqual = function simpleIsEqual(a, b) {
return a === b;
var shallowEqual = function shallowEqual(newValue, oldValue) {
return newValue === oldValue;
};
var simpleIsEqual = function simpleIsEqual(newArgs, lastArgs) {
return newArgs.length === lastArgs.length && newArgs.every(function (newArg, index) {
return shallowEqual(newArg, lastArgs[index]);
});
};
function index (resultFn, isEqual) {

@@ -21,6 +27,2 @@ if (isEqual === void 0) {

var isNewArgEqualToLast = function isNewArgEqualToLast(newArg, index) {
return isEqual(newArg, lastArgs[index], index);
};
var result = function result() {

@@ -31,3 +33,3 @@ for (var _len = arguments.length, newArgs = new Array(_len), _key = 0; _key < _len; _key++) {

if (calledOnce && lastThis === this && newArgs.length === lastArgs.length && newArgs.every(isNewArgEqualToLast)) {
if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
return lastResult;

@@ -48,2 +50,2 @@ }

})));
}));

@@ -1,1 +0,1 @@

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.memoizeOne=n()}(this,function(){"use strict";var e=function(e,n){return e===n};return function(r,t){var i;void 0===t&&(t=e);var o,u=[],f=!1,c=function(e,n){return t(e,u[n],n)};return function(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];return f&&i===this&&n.length===u.length&&n.every(c)||(o=r.apply(this,n),f=!0,i=this,u=n),o}}});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.memoizeOne=n()}("undefined"!=typeof self?self:this,function(){"use strict";var e=function(e,f){return e.length===f.length&&e.every(function(e,n){return t=e,r=f[n],t===r;var t,r})};return function(r,f){var i;void 0===f&&(f=e);var o,u=[],d=!1;return function(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];return d&&i===this&&f(n,u)||(o=r.apply(this,n),d=!0,i=this,u=n),o}}});
{
"name": "memoize-one",
"version": "4.1.0",
"version": "5.0.0",
"description": "A memoization library which only remembers the latest invocation",

@@ -26,3 +26,3 @@ "main": "dist/memoize-one.cjs.js",

"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/core": "^7.2.2",
"@babel/preset-env": "^7.2.0",

@@ -35,9 +35,13 @@ "@babel/preset-flow": "^7.0.0",

"eslint": "5.10.0",
"eslint-config-prettier": "^3.3.0",
"eslint-plugin-flowtype": "^3.2.0",
"eslint-plugin-jest": "^22.1.2",
"flow-bin": "0.88.0",
"eslint-plugin-prettier": "^3.0.0",
"flow-bin": "0.89.0",
"jest": "^23.6.0",
"lodash.isequal": "^4.5.0",
"prettier": "1.15.3",
"rimraf": "2.6.2",
"rollup": "^0.67.4",
"rollup-plugin-babel": "^4.0.3",
"rollup": "^0.68.0",
"rollup-plugin-babel": "^4.1.0",
"rollup-plugin-commonjs": "^9.2.0",

@@ -47,2 +51,5 @@ "rollup-plugin-replace": "^2.1.0",

},
"config": {
"prettier_target": "*.{js,jsx,md,json} src/**/*.{js,jsx,md,json} test/**/*.{js,jsx,md,json}"
},
"scripts": {

@@ -52,3 +59,6 @@ "validate": "yarn run lint && yarn run typecheck",

"typecheck": "flow check",
"lint": "eslint src test",
"prettier:check": "yarn prettier --debug-check $npm_package_config_prettier_target",
"prettier:write": "yarn prettier --write $npm_package_config_prettier_target",
"lint:eslint": "eslint src test",
"lint": "yarn lint:eslint && yarn prettier:check",
"build": "yarn run build:clean && yarn run build:dist && yarn run build:flow",

@@ -55,0 +65,0 @@ "build:clean": "rimraf dist",

@@ -14,10 +14,2 @@ # memoize-one

Cache invalidation is hard:
> There are only two hard things in Computer Science: cache invalidation and naming things.
>
> *Phil Karlton*
So keep things simple and just use a cache size of one!
Unlike other memoization libraries, `memoize-one` only remembers the latest arguments and result. No need to worry about cache busting mechanisms such as `maxAge`, `maxSize`, `exclusions` and so on which can be prone to memory leaks. `memoize-one` simply remembers the last arguments, and if the function is next called with the same arguments then it returns the previous result.

@@ -52,127 +44,81 @@

### Custom equality function
## Installation
You can also pass in a custom function for checking the equality of two items. The equality function will is used to compare the value of every individual argument.
```bash
# yarn
yarn add memoize-one
```js
import memoizeOne from 'memoize-one';
import deepEqual from 'lodash.isEqual';
# npm
npm install memoize-one --save
```
const identity = x => x;
## Module usage
const defaultMemoization = memoizeOne(identity);
const customMemoization = memoizeOne(identity, deepEqual);
### ES6 module
const result1 = defaultMemoization({foo: 'bar'});
const result2 = defaultMemoization({foo: 'bar'});
result1 === result2 // false - difference reference
const result3 = customMemoization({foo: 'bar'});
const result4 = customMemoization({foo: 'bar'});
result3 === result4 // true - arguments are deep equal
```js
import memoizeOne from 'memoize-one';
```
#### Equality function type signature
### CommonJS
Here is the expected [flow](http://flowtype.org) type signature for a custom equality function:
If you are in a CommonJS environment (eg [Node](https://nodejs.org)), then **you will need to add `.default` to your import**:
```js
type EqualityFn = (newValue: mixed, oldValue: mixed, index: number) => boolean;
const memoizeOne = require('memoize-one').default;
```
The default equality function is a simple shallow equal check
## Custom equality function
You can also pass in a custom function for checking the equality of two sets of arguments
```js
const simpleIsEqual: EqualityFn = (a: mixed, b: mixed): boolean => a === b;
const memoized = memoizeOne(fn, isEqual);
type EqualityFn = (newArgs: mixed[], oldArgs: mixed[]) => boolean;
```
#### Equality function with multiple arguments
An equality function should return `true` if the arguments are equal. If `true` is returned then the wrapped function will not be called.
If the function you want to memoize takes multiple arguments, your custom equality function will be called once for each argument and will be passed each argument's new value and last value.
The default equality function is a shallow equal check of all arguments (each argument is compared with `===`). The default equality function also does not check anything if the length of the arguments changes. You are welcome to decide if you want to return `false` if the `length` of the arguments is not equal
```js
import memoizeOne from 'memoize-one';
const simpleIsEqual: EqualityFn = (
newArgs: mixed[],
lastArgs: mixed[],
): boolean =>
newArgs.length === lastArgs.length &&
newArgs.every(
(newArg: mixed, index: number): boolean =>
shallowEqual(newArg, lastArgs[index]),
);
```
const makeCountObj = (first, second, third) => ({
first: first.count,
second: second.count,
third: third.count,
});
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`.
const areCountPropertiesEqual = (newArg, lastArg) => newArg.count === lastArg.count;
// runs once for first's new and last values, once for second's, etc.
Equality functions are not called if the `this` context of the function has changed (see below).
const memoizedMakeCountObj = memoizeOne(makeCountObj, areCountPropertiesEqual);
Here is an example that uses a `lodash.isequal` deep equal equality check
const result1 = memoizedMakeCountObj(
{a: '?', count: 1},
{a: '$', count: 2},
{a: '#', count: 3}
);
const result2 = memoizedMakeCountObj(
{b: null, count: 1},
{b: null, count: 2},
{b: null, count: 3}
);
> `lodash.isequal` correctly handles deep comparing two arrays
result1 === result2; // true - same reference
```
#### Equality function index
For each call of the equality function you are provided with the index of the argument.
```js
import memoizeOne from 'memoize-one';
import deepEqual from 'lodash.isEqual';
import isDeepEqual from 'lodash.isequal';
const myEqualFn = (newArg, lastArg, index) => {
// use deep equal for first arg
if(index === 0) {
return deepEqual(newArg, lastArg);
}
// use shallow equal for all other arguments
return newArg === lastArg;
}
const identity = x => x;
const fn = (...args) => {
console.log('called with', ...args);
};
const memoized = memoizeOne(fn, myEqualFn);
const shallowMemoized = memoizeOne(identity);
const deepMemoized = memoizeOne(identity, isDeepEqual);
memoized({hello: 'world'}, 5);
// console.log('called with', {hello: 'world'}, 5);
const result1 = shallowMemoized({ foo: 'bar' });
const result2 = shallowMemoized({ foo: 'bar' });
memoized({hello: 'world'}, 5);
// no call to console.log
```
result1 === result2; // false - difference reference
## Installation
const result3 = deepMemoized({ foo: 'bar' });
const result4 = deepMemoized({ foo: 'bar' });
```bash
# yarn
yarn add memoize-one
# npm
npm install memoize-one --save
result3 === result4; // true - arguments are deep equal
```
## Module usage
### ES6 module
```js
import memoizeOne from 'memoize-one';
```
### CommonJS
If you are in a CommonJS environment (eg [Node](https://nodejs.org)), then **you will need to add `.default` to your import**:
```js
const memoizeOne = require('memoize-one').default;
```
## `this`

@@ -205,3 +151,3 @@

a: 30,
}
};

@@ -214,3 +160,3 @@ getA.call(temp1); // 20

Generally this will be of no impact if you are not explicity controlling the `this` context of functions you want to memoize with [explicit binding](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md#explicit-binding) or [implicit binding](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md#implicit-binding). `memoize-One` will detect when you are manipulating `this` and will then consider the `this` context as an argument. If `this` changes, it will re-execute the original function even if the arguments have not changed.
Generally this will be of no impact if you are not explicity controlling the `this` context of functions you want to memoize with [explicit binding](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md#explicit-binding) or [implicit binding](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md#implicit-binding). `memoize-One` will detect when you are manipulating `this` and will then consider the `this` context as an argument. If `this` changes, it will re-execute the original function even if the arguments have not changed.

@@ -226,7 +172,7 @@ ## When your result function `throw`s

console.log('called');
if(name === 'throw') {
if (name === 'throw') {
throw new Error(name);
}
return { name };
}
};

@@ -246,3 +192,3 @@ const memoized = memoizeOne(canThrow);

// console.log => 'called'
} catch(e) {
} catch (e) {
firstError = e;

@@ -256,3 +202,3 @@ }

// with the 'throw' string
} catch(e) {
} catch (e) {
secondError = e;

@@ -263,3 +209,2 @@ }

const value3 = memoized('Alex');

@@ -286,3 +231,3 @@ // result function not called as the original memoization cache has not been busted

The comparisions are not exhaustive and are primiarly to show that `memoize-one` accomplishes remembering the latest invocation really fast. The benchmarks do not take into account the differences in feature sets, library sizes, parse time, and so on.
The comparisons are not exhaustive and are primarily to show that `memoize-one` accomplishes remembering the latest invocation really fast. The benchmarks do not take into account the differences in feature sets, library sizes, parse time, and so on.

@@ -289,0 +234,0 @@ ## Code health :thumbsup:

// @flow
type EqualityFn = (newValue: mixed, oldValue: mixed, index: number) => boolean;
export type EqualityFn = (newArgs: mixed[], lastArgs: mixed[]) => boolean;
const simpleIsEqual: EqualityFn = (a: mixed, b: mixed): boolean => a === b;
const shallowEqual = (newValue: mixed, oldValue: mixed): boolean =>
newValue === oldValue;
const simpleIsEqual: EqualityFn = (
newArgs: mixed[],
lastArgs: mixed[],
): boolean =>
newArgs.length === lastArgs.length &&
newArgs.every(
(newArg: mixed, index: number): boolean =>
shallowEqual(newArg, lastArgs[index]),
);
// <ResultFn: (...Array<any>) => mixed>

@@ -12,3 +23,6 @@ // The purpose of this typing is to ensure that the returned memoized

// mixed: The result can be anything but needs to be checked before usage
export default function <ResultFn: (...Array<any>) => mixed>(resultFn: ResultFn, isEqual?: EqualityFn = simpleIsEqual): ResultFn {
export default function<ResultFn: (...Array<any>) => mixed>(
resultFn: ResultFn,
isEqual?: EqualityFn = simpleIsEqual,
): ResultFn {
let lastThis: mixed;

@@ -19,10 +33,5 @@ let lastArgs: Array<mixed> = [];

const isNewArgEqualToLast = (newArg: mixed, index: number): boolean => isEqual(newArg, lastArgs[index], index);
// breaking cache when context (this) or arguments change
const result = function (...newArgs: Array<mixed>) {
if (calledOnce &&
lastThis === this &&
newArgs.length === lastArgs.length &&
newArgs.every(isNewArgEqualToLast)) {
const result = function(...newArgs: Array<mixed>) {
if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
return lastResult;

@@ -43,2 +52,2 @@ }

return (result: any);
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc