UNPKG

9.67 kBSource Map (JSON)View Raw
1{"version":3,"file":"memoize.js","sourceRoot":"../src/","sources":["memoize.ts"],"names":[],"mappings":"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","sourcesContent":["import { Stylesheet } from '@uifabric/merge-styles';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ndeclare class WeakMap {\n public get(key: any): any;\n public set(key: any, value: any): void;\n public has(key: any): boolean;\n}\n\nlet _initializedStylesheetResets = false;\nlet _resetCounter = 0;\nconst _emptyObject = { empty: true };\nconst _dictionary: any = {};\nlet _weakMap = typeof WeakMap === 'undefined' ? null : WeakMap;\n\ninterface IMemoizeNode {\n map: WeakMap | null;\n value?: any;\n}\n\n/**\n * Test utility for providing a custom weakmap.\n *\n * @internal\n * */\nexport function setMemoizeWeakMap(weakMap: any): void {\n _weakMap = weakMap;\n}\n\n/**\n * Reset memoizations.\n */\nexport function resetMemoizations(): void {\n _resetCounter++;\n}\n\n/**\n * Memoize decorator to be used on class methods. WARNING: the `this` reference\n * will be inaccessible within a memoized method, given that a cached method's `this`\n * would not be instance-specific.\n *\n * @public\n */\nexport function memoize<T extends Function>(\n target: any,\n key: string,\n descriptor: TypedPropertyDescriptor<T>,\n): {\n configurable: boolean;\n get(): T;\n} {\n // We bind to \"null\" to prevent people from inadvertently pulling values from \"this\",\n // rather than passing them in as input values which can be memoized.\n let fn = memoizeFunction(descriptor.value && descriptor.value.bind(null));\n\n return {\n configurable: true,\n get(): T {\n return fn;\n },\n };\n}\n\n/**\n * Memoizes a function; when you pass in the same parameters multiple times, it returns a cached result.\n * Be careful when passing in objects, you need to pass in the same INSTANCE for caching to work. Otherwise\n * it will grow the cache unnecessarily. Also avoid using default values that evaluate functions; passing in\n * undefined for a value and relying on a default function will execute it the first time, but will not\n * re-evaluate subsequent times which may have been unexpected.\n *\n * By default, the cache will reset after 100 permutations, to avoid abuse cases where the function is\n * unintendedly called with unique objects. Without a reset, the cache could grow infinitely, so we safeguard\n * by resetting. To override this behavior, pass a value of 0 to the maxCacheSize parameter.\n *\n * @public\n * @param cb - The function to memoize.\n * @param maxCacheSize - Max results to cache. If the cache exceeds this value, it will reset on the next call.\n * @param ignoreNullOrUndefinedResult - Flag to decide whether to cache callback result if it is undefined/null.\n * If the flag is set to true, the callback result is recomputed every time till the callback result is\n * not undefined/null for the first time, and then the non-undefined/null version gets cached.\n * @returns A memoized version of the function.\n */\nexport function memoizeFunction<T extends (...args: any[]) => RetType, RetType>(\n cb: T,\n maxCacheSize: number = 100,\n ignoreNullOrUndefinedResult: boolean = false,\n): T {\n // Avoid breaking scenarios which don't have weak map.\n if (!_weakMap) {\n return cb;\n }\n\n if (!_initializedStylesheetResets) {\n const stylesheet = Stylesheet.getInstance();\n\n if (stylesheet && stylesheet.onReset) {\n Stylesheet.getInstance().onReset(resetMemoizations);\n }\n _initializedStylesheetResets = true;\n }\n\n let rootNode: any;\n let cacheSize = 0;\n let localResetCounter = _resetCounter;\n\n return function memoizedFunction(...args: any[]): RetType {\n let currentNode: any = rootNode;\n\n if (\n rootNode === undefined ||\n localResetCounter !== _resetCounter ||\n (maxCacheSize > 0 && cacheSize > maxCacheSize)\n ) {\n rootNode = _createNode();\n cacheSize = 0;\n localResetCounter = _resetCounter;\n }\n\n currentNode = rootNode;\n\n // Traverse the tree until we find the match.\n for (let i = 0; i < args.length; i++) {\n let arg = _normalizeArg(args[i]);\n\n if (!currentNode.map.has(arg)) {\n currentNode.map.set(arg, _createNode());\n }\n\n currentNode = currentNode.map.get(arg);\n }\n\n if (!currentNode.hasOwnProperty('value')) {\n currentNode.value = cb(...args);\n cacheSize++;\n }\n\n if (ignoreNullOrUndefinedResult && (currentNode.value === null || currentNode.value === undefined)) {\n currentNode.value = cb(...args);\n }\n\n return currentNode.value;\n } as any;\n}\n\n/**\n * Creates a memoizer for a single-value function, backed by a WeakMap.\n * With a WeakMap, the memoized values are only kept as long as the source objects,\n * ensuring that there is no memory leak.\n *\n * This function assumes that the input values passed to the wrapped function will be\n * `function` or `object` types. To memoize functions which accept other inputs, use\n * `memoizeFunction`, which memoizes against arbitrary inputs using a lookup cache.\n *\n * @public\n */\nexport function createMemoizer<F extends (input: any) => any>(getValue: F): F {\n if (!_weakMap) {\n // Without a `WeakMap` implementation, memoization is not possible.\n return getValue;\n }\n\n const cache = new _weakMap();\n\n function memoizedGetValue(input: any): any {\n if (!input || (typeof input !== 'function' && typeof input !== 'object')) {\n // A WeakMap can only be used to test against reference values, i.e. 'function' and 'object'.\n // All other inputs cannot be memoized against in this manner.\n return getValue(input);\n }\n\n if (cache.has(input)) {\n return cache.get(input)!;\n }\n\n const value = getValue(input);\n\n cache.set(input, value);\n\n return value;\n }\n\n return memoizedGetValue as F;\n}\n\nfunction _normalizeArg(val: null | undefined): { empty: boolean } | any;\nfunction _normalizeArg(val: object): any;\nfunction _normalizeArg(val: any): any {\n if (!val) {\n return _emptyObject;\n } else if (typeof val === 'object' || typeof val === 'function') {\n return val;\n } else if (!_dictionary[val]) {\n _dictionary[val] = { val };\n }\n\n return _dictionary[val];\n}\n\nfunction _createNode(): IMemoizeNode {\n return {\n map: _weakMap ? new _weakMap() : null,\n };\n}\n"]}
\No newline at end of file