function.js (3758B)
1 "use strict"; 2 3 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); 4 5 Object.defineProperty(exports, "__esModule", { 6 value: true 7 }); 8 exports.maxArgumentCount = maxArgumentCount; 9 exports.memoize = memoize; 10 exports.memoizeCompare = memoizeCompare; 11 12 var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); 13 14 var _lruQueue = require("./lruQueue.js"); 15 16 // function utils 17 18 /** 19 * Memoize a given function by caching the computed result. 20 * The cache of a memoized function can be cleared by deleting the `cache` 21 * property of the function. 22 * 23 * @param {function} fn The function to be memoized. 24 * Must be a pure function. 25 * @param {Object} [options] 26 * @param {function(args: Array): string} [options.hasher] 27 * A custom hash builder. Is JSON.stringify by default. 28 * @param {number | undefined} [options.limit] 29 * Maximum number of values that may be cached. Undefined indicates 30 * unlimited (default) 31 * @return {function} Returns the memoized function 32 */ 33 function memoize(fn) { 34 var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 35 hasher = _ref.hasher, 36 limit = _ref.limit; 37 38 limit = limit == null ? Number.POSITIVE_INFINITY : limit; 39 hasher = hasher == null ? JSON.stringify : hasher; 40 return function memoize() { 41 if ((0, _typeof2.default)(memoize.cache) !== 'object') { 42 memoize.cache = { 43 values: new Map(), 44 lru: (0, _lruQueue.lruQueue)(limit || Number.POSITIVE_INFINITY) 45 }; 46 } 47 48 var args = []; 49 50 for (var i = 0; i < arguments.length; i++) { 51 args[i] = arguments[i]; 52 } 53 54 var hash = hasher(args); 55 56 if (memoize.cache.values.has(hash)) { 57 memoize.cache.lru.hit(hash); 58 return memoize.cache.values.get(hash); 59 } 60 61 var newVal = fn.apply(fn, args); 62 memoize.cache.values.set(hash, newVal); 63 memoize.cache.values.delete(memoize.cache.lru.hit(hash)); 64 return newVal; 65 }; 66 } 67 /** 68 * Memoize a given function by caching all results and the arguments, 69 * and comparing against the arguments of previous results before 70 * executing again. 71 * This is less performant than `memoize` which calculates a hash, 72 * which is very fast to compare. Use `memoizeCompare` only when it is 73 * not possible to create a unique serializable hash from the function 74 * arguments. 75 * The isEqual function must compare two sets of arguments 76 * and return true when equal (can be a deep equality check for example). 77 * @param {function} fn 78 * @param {function(a: *, b: *) : boolean} isEqual 79 * @returns {function} 80 */ 81 82 83 function memoizeCompare(fn, isEqual) { 84 var memoize = function memoize() { 85 var args = []; 86 87 for (var i = 0; i < arguments.length; i++) { 88 args[i] = arguments[i]; 89 } 90 91 for (var c = 0; c < memoize.cache.length; c++) { 92 var cached = memoize.cache[c]; 93 94 if (isEqual(args, cached.args)) { 95 // TODO: move this cache entry to the top so recently used entries move up? 96 return cached.res; 97 } 98 } 99 100 var res = fn.apply(fn, args); 101 memoize.cache.unshift({ 102 args: args, 103 res: res 104 }); 105 return res; 106 }; 107 108 memoize.cache = []; 109 return memoize; 110 } 111 /** 112 * Find the maximum number of arguments expected by a typed function. 113 * @param {function} fn A typed function 114 * @return {number} Returns the maximum number of expected arguments. 115 * Returns -1 when no signatures where found on the function. 116 */ 117 118 119 function maxArgumentCount(fn) { 120 return Object.keys(fn.signatures || {}).reduce(function (args, signature) { 121 var count = (signature.match(/,/g) || []).length + 1; 122 return Math.max(args, count); 123 }, -1); 124 }