micro-memoize
Advanced tools
Comparing version 3.0.0-beta.5 to 3.0.0-beta.6
@@ -5,2 +5,3 @@ import { | ||
createUpdateAsyncCache, | ||
getCustomOptions, | ||
isSameValueZero, | ||
@@ -197,2 +198,15 @@ mergeOptions, | ||
describe('getCustomOptions', () => { | ||
it('will return the custom options and no default options', () => { | ||
const options = { | ||
maxSize: 10, | ||
foo: 'bar', | ||
}; | ||
const result = getCustomOptions(options); | ||
expect(result).toEqual({ foo: options.foo }); | ||
}); | ||
}); | ||
describe('isSameValueZero', () => { | ||
@@ -199,0 +213,0 @@ it('will return true when the objects are equal', () => { |
# micro-memoize CHANGELOG | ||
## 3.0.0 | ||
- Rewrite in TypeScript | ||
- Use `rollup` for builds of all packages | ||
#### BREAKING CHANGES | ||
- Types contract is much stricter | ||
- Utility methods are no longer deep-linkable | ||
- Not technically exposed in the API, but was relied upon by other libraries) | ||
## 2.1.2 | ||
@@ -4,0 +15,0 @@ |
'use strict'; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
} | ||
var DEFAULT_OPTIONS_KEYS = { | ||
isEqual: true, | ||
isMatchingKey: true, | ||
isPromise: true, | ||
maxSize: true, | ||
onCacheAdd: true, | ||
onCacheChange: true, | ||
onCacheHit: true, | ||
transformKey: true, | ||
}; | ||
/** | ||
* @function createGetKeyIndex | ||
* | ||
* @description | ||
* create a method that will get the matching key index if found | ||
* | ||
* @param options the memoization options passed | ||
* @returns the method to get the key index | ||
*/ | ||
function createGetKeyIndex(options) { | ||
@@ -84,2 +78,21 @@ if (typeof options.isMatchingKey === 'function') { | ||
/** | ||
* @function getCustomOptions | ||
* | ||
* @description | ||
* get the custom options on the object passed | ||
* | ||
* @param options the memoization options passed | ||
* @returns the custom options passed | ||
*/ | ||
function getCustomOptions(options) { | ||
var customOptions = {}; | ||
for (var key in options) { | ||
if (!DEFAULT_OPTIONS_KEYS[key]) { | ||
// @ts-ignore | ||
customOptions[key] = options[key]; | ||
} | ||
} | ||
return customOptions; | ||
} | ||
/** | ||
* @function isSameValueZero | ||
@@ -176,3 +189,5 @@ * | ||
// utils | ||
var slice = Array.prototype.slice; | ||
var defineProperties = Object.defineProperties; | ||
function createMemoizedFunction(fn, options) { | ||
@@ -184,4 +199,4 @@ if (options === void 0) { options = {}; } | ||
} | ||
var _a = options.isEqual, isEqual = _a === void 0 ? isSameValueZero : _a, isMatchingKey = options.isMatchingKey, _b = options.isPromise, isPromise = _b === void 0 ? false : _b, _c = options.maxSize, maxSize = _c === void 0 ? 1 : _c, onCacheAdd = options.onCacheAdd, onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit, transformKey = options.transformKey, extraOptions = __rest(options, ["isEqual", "isMatchingKey", "isPromise", "maxSize", "onCacheAdd", "onCacheChange", "onCacheHit", "transformKey"]); | ||
var normalizedOptions = mergeOptions(extraOptions, { | ||
var _a = options.isEqual, isEqual = _a === void 0 ? isSameValueZero : _a, isMatchingKey = options.isMatchingKey, _b = options.isPromise, isPromise = _b === void 0 ? false : _b, _c = options.maxSize, maxSize = _c === void 0 ? 1 : _c, onCacheAdd = options.onCacheAdd, onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit, transformKey = options.transformKey; | ||
var normalizedOptions = mergeOptions(getCustomOptions(options), { | ||
isEqual: isEqual, | ||
@@ -236,3 +251,3 @@ isMatchingKey: isMatchingKey, | ||
} | ||
Object.defineProperties(memoized, { | ||
defineProperties(memoized, { | ||
cache: { | ||
@@ -239,0 +254,0 @@ configurable: true, |
@@ -1,26 +0,20 @@ | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
} | ||
var DEFAULT_OPTIONS_KEYS = { | ||
isEqual: true, | ||
isMatchingKey: true, | ||
isPromise: true, | ||
maxSize: true, | ||
onCacheAdd: true, | ||
onCacheChange: true, | ||
onCacheHit: true, | ||
transformKey: true, | ||
}; | ||
/** | ||
* @function createGetKeyIndex | ||
* | ||
* @description | ||
* create a method that will get the matching key index if found | ||
* | ||
* @param options the memoization options passed | ||
* @returns the method to get the key index | ||
*/ | ||
function createGetKeyIndex(options) { | ||
@@ -82,2 +76,21 @@ if (typeof options.isMatchingKey === 'function') { | ||
/** | ||
* @function getCustomOptions | ||
* | ||
* @description | ||
* get the custom options on the object passed | ||
* | ||
* @param options the memoization options passed | ||
* @returns the custom options passed | ||
*/ | ||
function getCustomOptions(options) { | ||
var customOptions = {}; | ||
for (var key in options) { | ||
if (!DEFAULT_OPTIONS_KEYS[key]) { | ||
// @ts-ignore | ||
customOptions[key] = options[key]; | ||
} | ||
} | ||
return customOptions; | ||
} | ||
/** | ||
* @function isSameValueZero | ||
@@ -174,3 +187,5 @@ * | ||
// utils | ||
var slice = Array.prototype.slice; | ||
var defineProperties = Object.defineProperties; | ||
function createMemoizedFunction(fn, options) { | ||
@@ -182,4 +197,4 @@ if (options === void 0) { options = {}; } | ||
} | ||
var _a = options.isEqual, isEqual = _a === void 0 ? isSameValueZero : _a, isMatchingKey = options.isMatchingKey, _b = options.isPromise, isPromise = _b === void 0 ? false : _b, _c = options.maxSize, maxSize = _c === void 0 ? 1 : _c, onCacheAdd = options.onCacheAdd, onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit, transformKey = options.transformKey, extraOptions = __rest(options, ["isEqual", "isMatchingKey", "isPromise", "maxSize", "onCacheAdd", "onCacheChange", "onCacheHit", "transformKey"]); | ||
var normalizedOptions = mergeOptions(extraOptions, { | ||
var _a = options.isEqual, isEqual = _a === void 0 ? isSameValueZero : _a, isMatchingKey = options.isMatchingKey, _b = options.isPromise, isPromise = _b === void 0 ? false : _b, _c = options.maxSize, maxSize = _c === void 0 ? 1 : _c, onCacheAdd = options.onCacheAdd, onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit, transformKey = options.transformKey; | ||
var normalizedOptions = mergeOptions(getCustomOptions(options), { | ||
isEqual: isEqual, | ||
@@ -234,3 +249,3 @@ isMatchingKey: isMatchingKey, | ||
} | ||
Object.defineProperties(memoized, { | ||
defineProperties(memoized, { | ||
cache: { | ||
@@ -237,0 +252,0 @@ configurable: true, |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global = global || self, global['micro-memoize'] = factory()); | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global = global || self, global['micro-memoize'] = factory()); | ||
}(this, function () { 'use strict'; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
var DEFAULT_OPTIONS_KEYS = { | ||
isEqual: true, | ||
isMatchingKey: true, | ||
isPromise: true, | ||
maxSize: true, | ||
onCacheAdd: true, | ||
onCacheChange: true, | ||
onCacheHit: true, | ||
transformKey: true, | ||
}; | ||
/** | ||
* @function createGetKeyIndex | ||
* | ||
* @description | ||
* create a method that will get the matching key index if found | ||
* | ||
* @param options the memoization options passed | ||
* @returns the method to get the key index | ||
*/ | ||
function createGetKeyIndex(options) { | ||
if (typeof options.isMatchingKey === 'function') { | ||
var isMatchingKey_1 = options.isMatchingKey, maxSize_1 = options.maxSize; | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
if (isMatchingKey_1(allKeys[0], keyToMatch)) { | ||
return 0; | ||
} | ||
if (maxSize_1 > 1) { | ||
var keysLength = allKeys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey_1(allKeys[index], keyToMatch)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
var isEqual = options.isEqual; | ||
if (options.maxSize > 1) { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var keysLength = allKeys.length; | ||
var keyLength = keyToMatch.length; | ||
var existingKey; | ||
for (var index = 0; index < keysLength; index++) { | ||
existingKey = allKeys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], keyToMatch[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var existingKey = allKeys[0]; | ||
var keyLength = existingKey.length; | ||
if (keyToMatch.length !== keyLength) { | ||
return -1; | ||
} | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], keyToMatch[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
} | ||
/** | ||
* @function getCustomOptions | ||
* | ||
* @description | ||
* get the custom options on the object passed | ||
* | ||
* @param options the memoization options passed | ||
* @returns the custom options passed | ||
*/ | ||
function getCustomOptions(options) { | ||
var customOptions = {}; | ||
for (var key in options) { | ||
if (!DEFAULT_OPTIONS_KEYS[key]) { | ||
// @ts-ignore | ||
customOptions[key] = options[key]; | ||
} | ||
} | ||
return customOptions; | ||
} | ||
/** | ||
* @function isSameValueZero | ||
* | ||
* @description | ||
* are the objects equal based on SameValueZero equality | ||
* | ||
* @param object1 the first object to compare | ||
* @param object2 the second object to compare | ||
* @returns are the two objects equal | ||
*/ | ||
function isSameValueZero(object1, object2) { | ||
return object1 === object2 || (object1 !== object1 && object2 !== object2); | ||
} | ||
/** | ||
* @function mergeOptions | ||
* | ||
* @description | ||
* merge the options into the target | ||
* | ||
* @param extraOptions the extra options passed | ||
* @param providedOptions the defaulted options provided | ||
* @returns the merged options | ||
*/ | ||
function mergeOptions(extraOptions, providedOptions) { | ||
var target = {}; | ||
for (var key in extraOptions) { | ||
target[key] = extraOptions[key]; | ||
} | ||
for (var key in providedOptions) { | ||
target[key] = providedOptions[key]; | ||
} | ||
return target; | ||
} | ||
/** | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param keys the keys to order | ||
* @param newKey the new key to move to the front | ||
* @param values the values to order | ||
* @param newValue the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
function orderByLru(cache, newKey, newValue, startingIndex, maxSize) { | ||
var index = startingIndex; | ||
while (index--) { | ||
cache.keys[index + 1] = cache.keys[index]; | ||
cache.values[index + 1] = cache.values[index]; | ||
} | ||
cache.keys[0] = newKey; | ||
cache.values[0] = newValue; | ||
if (startingIndex >= maxSize) { | ||
cache.keys.length = maxSize; | ||
cache.values.length = maxSize; | ||
} | ||
} | ||
function createUpdateAsyncCache(options) { | ||
var getKeyIndex = createGetKeyIndex(options); | ||
var onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
/** | ||
* @function updateAsyncCache | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param cache the memoized function's cache | ||
* @param memoized the memoized function | ||
*/ | ||
return function (cache, memoized) { | ||
var key = cache.keys[0]; | ||
cache.values[0] = cache.values[0] | ||
.then(function (value) { | ||
shouldUpdateOnHit && onCacheHit(cache, options, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, options, memoized); | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = getKeyIndex(cache.keys, key); | ||
if (keyIndex !== -1) { | ||
cache.keys.splice(keyIndex, 1); | ||
cache.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
} | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
// utils | ||
var slice = Array.prototype.slice; | ||
var defineProperties = Object.defineProperties; | ||
function createMemoizedFunction(fn, options) { | ||
if (options === void 0) { options = {}; } | ||
// @ts-ignore | ||
if (fn.isMemoized) { | ||
return fn; | ||
} | ||
var _a = options.isEqual, isEqual = _a === void 0 ? isSameValueZero : _a, isMatchingKey = options.isMatchingKey, _b = options.isPromise, isPromise = _b === void 0 ? false : _b, _c = options.maxSize, maxSize = _c === void 0 ? 1 : _c, onCacheAdd = options.onCacheAdd, onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit, transformKey = options.transformKey; | ||
var normalizedOptions = mergeOptions(getCustomOptions(options), { | ||
isEqual: isEqual, | ||
isMatchingKey: isMatchingKey, | ||
isPromise: isPromise, | ||
maxSize: maxSize, | ||
onCacheAdd: onCacheAdd, | ||
onCacheChange: onCacheChange, | ||
onCacheHit: onCacheHit, | ||
transformKey: transformKey, | ||
}); | ||
var getKeyIndex = createGetKeyIndex(normalizedOptions); | ||
var updateAsyncCache = createUpdateAsyncCache(normalizedOptions); | ||
var keys = []; | ||
var values = []; | ||
var cache = { | ||
keys: keys, | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
values: values, | ||
}; | ||
var canTransformKey = typeof transformKey === 'function'; | ||
var shouldCloneArguments = !!(transformKey || isMatchingKey); | ||
var shouldUpdateOnAdd = typeof onCacheAdd === 'function'; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
function memoized() { | ||
var normalizedArgs = shouldCloneArguments | ||
? slice.call(arguments, 0) | ||
: arguments; | ||
var key = canTransformKey ? transformKey(normalizedArgs) : normalizedArgs; | ||
var keyIndex = keys.length ? getKeyIndex(keys, key) : -1; | ||
if (keyIndex !== -1) { | ||
shouldUpdateOnHit && onCacheHit(cache, normalizedOptions, memoized); | ||
if (keyIndex) { | ||
orderByLru(cache, keys[keyIndex], values[keyIndex], keyIndex, maxSize); | ||
shouldUpdateOnChange && | ||
onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
} | ||
else { | ||
var newValue = fn.apply(this, arguments); | ||
var newKey = shouldCloneArguments ? key : slice.call(arguments, 0); | ||
orderByLru(cache, newKey, newValue, keys.length, maxSize); | ||
isPromise && updateAsyncCache(cache, memoized); | ||
shouldUpdateOnAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
return values[0]; | ||
} | ||
defineProperties(memoized, { | ||
cache: { | ||
configurable: true, | ||
value: cache, | ||
}, | ||
cacheSnapshot: { | ||
configurable: true, | ||
get: function () { | ||
return { | ||
keys: slice.call(cache.keys, 0), | ||
size: cache.size, | ||
values: slice.call(cache.values, 0), | ||
}; | ||
}, | ||
}, | ||
isMemoized: { | ||
configurable: true, | ||
value: true, | ||
}, | ||
options: { | ||
configurable: true, | ||
value: normalizedOptions, | ||
}, | ||
}); | ||
return memoized; | ||
} | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
return createMemoizedFunction; | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
} | ||
function createGetKeyIndex(options) { | ||
if (typeof options.isMatchingKey === 'function') { | ||
var isMatchingKey_1 = options.isMatchingKey, maxSize_1 = options.maxSize; | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
if (isMatchingKey_1(allKeys[0], keyToMatch)) { | ||
return 0; | ||
} | ||
if (maxSize_1 > 1) { | ||
var keysLength = allKeys.length; | ||
for (var index = 1; index < keysLength; index++) { | ||
if (isMatchingKey_1(allKeys[index], keyToMatch)) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
var isEqual = options.isEqual; | ||
if (options.maxSize > 1) { | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var keysLength = allKeys.length; | ||
var keyLength = keyToMatch.length; | ||
var existingKey; | ||
for (var index = 0; index < keysLength; index++) { | ||
existingKey = allKeys[index]; | ||
if (existingKey.length === keyLength) { | ||
var argIndex = 0; | ||
for (; argIndex < keyLength; argIndex++) { | ||
if (!isEqual(existingKey[argIndex], keyToMatch[argIndex])) { | ||
break; | ||
} | ||
} | ||
if (argIndex === keyLength) { | ||
return index; | ||
} | ||
} | ||
} | ||
return -1; | ||
}; | ||
} | ||
return function getKeyIndex(allKeys, keyToMatch) { | ||
var existingKey = allKeys[0]; | ||
var keyLength = existingKey.length; | ||
if (keyToMatch.length !== keyLength) { | ||
return -1; | ||
} | ||
for (var index = 0; index < keyLength; index++) { | ||
if (!isEqual(existingKey[index], keyToMatch[index])) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
}; | ||
} | ||
/** | ||
* @function isSameValueZero | ||
* | ||
* @description | ||
* are the objects equal based on SameValueZero equality | ||
* | ||
* @param object1 the first object to compare | ||
* @param object2 the second object to compare | ||
* @returns are the two objects equal | ||
*/ | ||
function isSameValueZero(object1, object2) { | ||
return object1 === object2 || (object1 !== object1 && object2 !== object2); | ||
} | ||
/** | ||
* @function mergeOptions | ||
* | ||
* @description | ||
* merge the options into the target | ||
* | ||
* @param extraOptions the extra options passed | ||
* @param providedOptions the defaulted options provided | ||
* @returns the merged options | ||
*/ | ||
function mergeOptions(extraOptions, providedOptions) { | ||
var target = {}; | ||
for (var key in extraOptions) { | ||
target[key] = extraOptions[key]; | ||
} | ||
for (var key in providedOptions) { | ||
target[key] = providedOptions[key]; | ||
} | ||
return target; | ||
} | ||
/** | ||
* @function orderByLru | ||
* | ||
* @description | ||
* order the array based on a Least-Recently-Used basis | ||
* | ||
* @param keys the keys to order | ||
* @param newKey the new key to move to the front | ||
* @param values the values to order | ||
* @param newValue the new value to move to the front | ||
* @param startingIndex the index of the item to move to the front | ||
*/ | ||
function orderByLru(cache, newKey, newValue, startingIndex, maxSize) { | ||
var index = startingIndex; | ||
while (index--) { | ||
cache.keys[index + 1] = cache.keys[index]; | ||
cache.values[index + 1] = cache.values[index]; | ||
} | ||
cache.keys[0] = newKey; | ||
cache.values[0] = newValue; | ||
if (startingIndex >= maxSize) { | ||
cache.keys.length = maxSize; | ||
cache.values.length = maxSize; | ||
} | ||
} | ||
function createUpdateAsyncCache(options) { | ||
var getKeyIndex = createGetKeyIndex(options); | ||
var onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
/** | ||
* @function updateAsyncCache | ||
* | ||
* @description | ||
* update the promise method to auto-remove from cache if rejected, and | ||
* if resolved then fire cache hit / changed | ||
* | ||
* @param cache the memoized function's cache | ||
* @param memoized the memoized function | ||
*/ | ||
return function (cache, memoized) { | ||
var key = cache.keys[0]; | ||
cache.values[0] = cache.values[0] | ||
.then(function (value) { | ||
shouldUpdateOnHit && onCacheHit(cache, options, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, options, memoized); | ||
return value; | ||
}) | ||
.catch(function (error) { | ||
var keyIndex = getKeyIndex(cache.keys, key); | ||
if (keyIndex !== -1) { | ||
cache.keys.splice(keyIndex, 1); | ||
cache.values.splice(keyIndex, 1); | ||
} | ||
throw error; | ||
}); | ||
}; | ||
} | ||
var slice = Array.prototype.slice; | ||
function createMemoizedFunction(fn, options) { | ||
if (options === void 0) { options = {}; } | ||
// @ts-ignore | ||
if (fn.isMemoized) { | ||
return fn; | ||
} | ||
var _a = options.isEqual, isEqual = _a === void 0 ? isSameValueZero : _a, isMatchingKey = options.isMatchingKey, _b = options.isPromise, isPromise = _b === void 0 ? false : _b, _c = options.maxSize, maxSize = _c === void 0 ? 1 : _c, onCacheAdd = options.onCacheAdd, onCacheChange = options.onCacheChange, onCacheHit = options.onCacheHit, transformKey = options.transformKey, extraOptions = __rest(options, ["isEqual", "isMatchingKey", "isPromise", "maxSize", "onCacheAdd", "onCacheChange", "onCacheHit", "transformKey"]); | ||
var normalizedOptions = mergeOptions(extraOptions, { | ||
isEqual: isEqual, | ||
isMatchingKey: isMatchingKey, | ||
isPromise: isPromise, | ||
maxSize: maxSize, | ||
onCacheAdd: onCacheAdd, | ||
onCacheChange: onCacheChange, | ||
onCacheHit: onCacheHit, | ||
transformKey: transformKey, | ||
}); | ||
var getKeyIndex = createGetKeyIndex(normalizedOptions); | ||
var updateAsyncCache = createUpdateAsyncCache(normalizedOptions); | ||
var keys = []; | ||
var values = []; | ||
var cache = { | ||
keys: keys, | ||
get size() { | ||
return cache.keys.length; | ||
}, | ||
values: values, | ||
}; | ||
var canTransformKey = typeof transformKey === 'function'; | ||
var shouldCloneArguments = !!(transformKey || isMatchingKey); | ||
var shouldUpdateOnAdd = typeof onCacheAdd === 'function'; | ||
var shouldUpdateOnChange = typeof onCacheChange === 'function'; | ||
var shouldUpdateOnHit = typeof onCacheHit === 'function'; | ||
function memoized() { | ||
var normalizedArgs = shouldCloneArguments | ||
? slice.call(arguments, 0) | ||
: arguments; | ||
var key = canTransformKey ? transformKey(normalizedArgs) : normalizedArgs; | ||
var keyIndex = keys.length ? getKeyIndex(keys, key) : -1; | ||
if (keyIndex !== -1) { | ||
shouldUpdateOnHit && onCacheHit(cache, normalizedOptions, memoized); | ||
if (keyIndex) { | ||
orderByLru(cache, keys[keyIndex], values[keyIndex], keyIndex, maxSize); | ||
shouldUpdateOnChange && | ||
onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
} | ||
else { | ||
var newValue = fn.apply(this, arguments); | ||
var newKey = shouldCloneArguments ? key : slice.call(arguments, 0); | ||
orderByLru(cache, newKey, newValue, keys.length, maxSize); | ||
isPromise && updateAsyncCache(cache, memoized); | ||
shouldUpdateOnAdd && onCacheAdd(cache, normalizedOptions, memoized); | ||
shouldUpdateOnChange && onCacheChange(cache, normalizedOptions, memoized); | ||
} | ||
return values[0]; | ||
} | ||
Object.defineProperties(memoized, { | ||
cache: { | ||
configurable: true, | ||
value: cache, | ||
}, | ||
cacheSnapshot: { | ||
configurable: true, | ||
get: function () { | ||
return { | ||
keys: slice.call(cache.keys, 0), | ||
size: cache.size, | ||
values: slice.call(cache.values, 0), | ||
}; | ||
}, | ||
}, | ||
isMemoized: { | ||
configurable: true, | ||
value: true, | ||
}, | ||
options: { | ||
configurable: true, | ||
value: normalizedOptions, | ||
}, | ||
}); | ||
return memoized; | ||
} | ||
return createMemoizedFunction; | ||
})); | ||
//# sourceMappingURL=micro-memoize.js.map |
@@ -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)["micro-memoize"]=n()}(this,function(){"use strict";function w(e){if("function"==typeof e.isMatchingKey){var r=e.isMatchingKey,o=e.maxSize;return function(e,n){if(r(e[0],n))return 0;if(1<o)for(var t=e.length,i=1;i<t;i++)if(r(e[i],n))return i;return-1}}var f=e.isEqual;return 1<e.maxSize?function(e,n){for(var t,i=e.length,r=n.length,o=0;o<i;o++)if((t=e[o]).length===r){for(var a=0;a<r&&f(t[a],n[a]);a++);if(a===r)return o}return-1}:function(e,n){var t=e[0],i=t.length;if(n.length!==i)return-1;for(var r=0;r<i;r++)if(!f(t[r],n[r]))return-1;return 0}}function A(e,n){return e===n||e!=e&&n!=n}function E(e,n,t,i,r){for(var o=i;o--;)e.keys[o+1]=e.keys[o],e.values[o+1]=e.values[o];e.keys[0]=n,e.values[0]=t,r<=i&&(e.keys.length=r,e.values.length=r)}var H=Array.prototype.slice;return function(o,e){if(void 0===e&&(e={}),o.isMemoized)return o;var r,a,f,u,c,s,n=e.isEqual,t=void 0===n?A:n,i=e.isMatchingKey,l=e.isPromise,h=void 0!==l&&l,y=e.maxSize,v=void 0===y?1:y,g=e.onCacheAdd,p=e.onCacheChange,d=e.onCacheHit,m=e.transformKey,C=function(e,n){var t={};for(var i in e)t[i]=e[i];for(var i in n)t[i]=n[i];return t}(function(e,n){var t={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&n.indexOf(i)<0&&(t[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);r<i.length;r++)n.indexOf(i[r])<0&&(t[i[r]]=e[i[r]])}return t}(e,["isEqual","isMatchingKey","isPromise","maxSize","onCacheAdd","onCacheChange","onCacheHit","transformKey"]),{isEqual:t,isMatchingKey:i,isPromise:h,maxSize:v,onCacheAdd:g,onCacheChange:p,onCacheHit:d,transformKey:m}),b=w(C),k=(a=w(r=C),f=r.onCacheChange,u=r.onCacheHit,c="function"==typeof f,s="function"==typeof u,function(t,n){var i=t.keys[0];t.values[0]=t.values[0].then(function(e){return s&&u(t,r,n),c&&f(t,r,n),e}).catch(function(e){var n=a(t.keys,i);throw-1!==n&&(t.keys.splice(n,1),t.values.splice(n,1)),e})}),z=[],x=[],O={keys:z,get size(){return O.keys.length},values:x},K="function"==typeof m,S=!(!m&&!i),M="function"==typeof g,P="function"==typeof p,j="function"==typeof d;function q(){var e=S?H.call(arguments,0):arguments,n=K?m(e):e,t=z.length?b(z,n):-1;if(-1!==t)j&&d(O,C,q),t&&(E(O,z[t],x[t],t,v),P&&p(O,C,q));else{var i=o.apply(this,arguments),r=S?n:H.call(arguments,0);E(O,r,i,z.length,v),h&&k(O,q),M&&g(O,C,q),P&&p(O,C,q)}return x[0]}return Object.defineProperties(q,{cache:{configurable:!0,value:O},cacheSnapshot:{configurable:!0,get:function(){return{keys:H.call(O.keys,0),size:O.size,values:H.call(O.values,0)}}},isMemoized:{configurable:!0,value:!0},options:{configurable:!0,value:C}}),q}}); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self)["micro-memoize"]=n()}(this,function(){"use strict";var P={isEqual:!0,isMatchingKey:!0,isPromise:!0,maxSize:!0,onCacheAdd:!0,onCacheChange:!0,onCacheHit:!0,transformKey:!0};function j(e){if("function"==typeof e.isMatchingKey){var r=e.isMatchingKey,o=e.maxSize;return function(e,n){if(r(e[0],n))return 0;if(1<o)for(var i=e.length,t=1;t<i;t++)if(r(e[t],n))return t;return-1}}var u=e.isEqual;return 1<e.maxSize?function(e,n){for(var i,t=e.length,r=n.length,o=0;o<t;o++)if((i=e[o]).length===r){for(var a=0;a<r&&u(i[a],n[a]);a++);if(a===r)return o}return-1}:function(e,n){var i=e[0],t=i.length;if(n.length!==t)return-1;for(var r=0;r<t;r++)if(!u(i[r],n[r]))return-1;return 0}}function w(e,n){return e===n||e!=e&&n!=n}function O(e,n,i,t,r){for(var o=t;o--;)e.keys[o+1]=e.keys[o],e.values[o+1]=e.values[o];e.keys[0]=n,e.values[0]=i,r<=t&&(e.keys.length=r,e.values.length=r)}var B=Array.prototype.slice,D=Object.defineProperties;return function(o,e){if(void 0===e&&(e={}),o.isMemoized)return o;var r,a,u,f,c,s,n=e.isEqual,i=void 0===n?w:n,t=e.isMatchingKey,l=e.isPromise,h=void 0!==l&&l,v=e.maxSize,y=void 0===v?1:v,g=e.onCacheAdd,d=e.onCacheChange,p=e.onCacheHit,m=e.transformKey,C=function(e,n){var i={};for(var t in e)i[t]=e[t];for(var t in n)i[t]=n[t];return i}(function(e){var n={};for(var i in e)P[i]||(n[i]=e[i]);return n}(e),{isEqual:i,isMatchingKey:t,isPromise:h,maxSize:y,onCacheAdd:g,onCacheChange:d,onCacheHit:p,transformKey:m}),k=j(C),z=(a=j(r=C),u=r.onCacheChange,f=r.onCacheHit,c="function"==typeof u,s="function"==typeof f,function(i,n){var t=i.keys[0];i.values[0]=i.values[0].then(function(e){return s&&f(i,r,n),c&&u(i,r,n),e}).catch(function(e){var n=a(i.keys,t);throw-1!==n&&(i.keys.splice(n,1),i.values.splice(n,1)),e})}),K=[],x=[],M={keys:K,get size(){return M.keys.length},values:x},b="function"==typeof m,S=!(!m&&!t),q="function"==typeof g,A="function"==typeof d,E="function"==typeof p;function H(){var e=S?B.call(arguments,0):arguments,n=b?m(e):e,i=K.length?k(K,n):-1;if(-1!==i)E&&p(M,C,H),i&&(O(M,K[i],x[i],i,y),A&&d(M,C,H));else{var t=o.apply(this,arguments),r=S?n:B.call(arguments,0);O(M,r,t,K.length,y),h&&z(M,H),q&&g(M,C,H),A&&d(M,C,H)}return x[0]}return D(H,{cache:{configurable:!0,value:M},cacheSnapshot:{configurable:!0,get:function(){return{keys:B.call(M.keys,0),size:M.size,values:B.call(M.values,0)}}},isMemoized:{configurable:!0,value:!0},options:{configurable:!0,value:C}}),H}}); |
@@ -1,6 +0,1 @@ | ||
type PlainObject = { | ||
[key: string]: any; | ||
[index: number]: any; | ||
}; | ||
declare namespace MicroMemoize { | ||
@@ -58,4 +53,4 @@ export type Key = any[]; | ||
export default function memoize<T extends Function>( | ||
fn: T, | ||
fn: T | MicroMemoize.Memoized, | ||
options?: MicroMemoize.Options, | ||
): MicroMemoize.Memoized; |
@@ -99,3 +99,3 @@ { | ||
"types": "./index.d.ts", | ||
"version": "3.0.0-beta.5" | ||
"version": "3.0.0-beta.6" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
426016
0
2637