UNPKG

3.75 kBJavaScriptView Raw
1// Cache implementation based on Erik Rasmussen's `lru-memoize`:
2// https://github.com/erikras/lru-memoize
3var NOT_FOUND = 'NOT_FOUND';
4
5function createSingletonCache(equals) {
6 var entry;
7 return {
8 get: function get(key) {
9 if (entry && equals(entry.key, key)) {
10 return entry.value;
11 }
12
13 return NOT_FOUND;
14 },
15 put: function put(key, value) {
16 entry = {
17 key: key,
18 value: value
19 };
20 },
21 getEntries: function getEntries() {
22 return entry ? [entry] : [];
23 },
24 clear: function clear() {
25 entry = undefined;
26 }
27 };
28}
29
30function createLruCache(maxSize, equals) {
31 var entries = [];
32
33 function get(key) {
34 var cacheIndex = entries.findIndex(function (entry) {
35 return equals(key, entry.key);
36 }); // We found a cached entry
37
38 if (cacheIndex > -1) {
39 var entry = entries[cacheIndex]; // Cached entry not at top of cache, move it to the top
40
41 if (cacheIndex > 0) {
42 entries.splice(cacheIndex, 1);
43 entries.unshift(entry);
44 }
45
46 return entry.value;
47 } // No entry found in cache, return sentinel
48
49
50 return NOT_FOUND;
51 }
52
53 function put(key, value) {
54 if (get(key) === NOT_FOUND) {
55 // TODO Is unshift slow?
56 entries.unshift({
57 key: key,
58 value: value
59 });
60
61 if (entries.length > maxSize) {
62 entries.pop();
63 }
64 }
65 }
66
67 function getEntries() {
68 return entries;
69 }
70
71 function clear() {
72 entries = [];
73 }
74
75 return {
76 get: get,
77 put: put,
78 getEntries: getEntries,
79 clear: clear
80 };
81}
82
83export var defaultEqualityCheck = function defaultEqualityCheck(a, b) {
84 return a === b;
85};
86export function createCacheKeyComparator(equalityCheck) {
87 return function areArgumentsShallowlyEqual(prev, next) {
88 if (prev === null || next === null || prev.length !== next.length) {
89 return false;
90 } // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible.
91
92
93 var length = prev.length;
94
95 for (var i = 0; i < length; i++) {
96 if (!equalityCheck(prev[i], next[i])) {
97 return false;
98 }
99 }
100
101 return true;
102 };
103}
104// defaultMemoize now supports a configurable cache size with LRU behavior,
105// and optional comparison of the result value with existing values
106export function defaultMemoize(func, equalityCheckOrOptions) {
107 var providedOptions = typeof equalityCheckOrOptions === 'object' ? equalityCheckOrOptions : {
108 equalityCheck: equalityCheckOrOptions
109 };
110 var _providedOptions$equa = providedOptions.equalityCheck,
111 equalityCheck = _providedOptions$equa === void 0 ? defaultEqualityCheck : _providedOptions$equa,
112 _providedOptions$maxS = providedOptions.maxSize,
113 maxSize = _providedOptions$maxS === void 0 ? 1 : _providedOptions$maxS,
114 resultEqualityCheck = providedOptions.resultEqualityCheck;
115 var comparator = createCacheKeyComparator(equalityCheck);
116 var cache = maxSize === 1 ? createSingletonCache(comparator) : createLruCache(maxSize, comparator); // we reference arguments instead of spreading them for performance reasons
117
118 function memoized() {
119 var value = cache.get(arguments);
120
121 if (value === NOT_FOUND) {
122 // @ts-ignore
123 value = func.apply(null, arguments);
124
125 if (resultEqualityCheck) {
126 var entries = cache.getEntries();
127 var matchingEntry = entries.find(function (entry) {
128 return resultEqualityCheck(entry.value, value);
129 });
130
131 if (matchingEntry) {
132 value = matchingEntry.value;
133 }
134 }
135
136 cache.put(arguments, value);
137 }
138
139 return value;
140 }
141
142 memoized.clearCache = function () {
143 return cache.clear();
144 };
145
146 return memoized;
147}
\No newline at end of file