(realFn)
| 116 | * @returns {MakeCacheableResult<T> & { bindCache: BindCache<T> }} cacheable function |
| 117 | */ |
| 118 | const makeCacheable = (realFn) => { |
| 119 | /** |
| 120 | * Defines the cache item type used by this module. |
| 121 | * @template T |
| 122 | * @typedef {Map<string, T>} CacheItem |
| 123 | */ |
| 124 | /** @type {WeakMap<AssociatedObjectForCache, CacheItem<T>>} */ |
| 125 | const cache = new WeakMap(); |
| 126 | |
| 127 | /** |
| 128 | * Returns cache item. |
| 129 | * @param {AssociatedObjectForCache} associatedObjectForCache an object to which the cache will be attached |
| 130 | * @returns {CacheItem<T>} cache item |
| 131 | */ |
| 132 | const getCache = (associatedObjectForCache) => { |
| 133 | const entry = cache.get(associatedObjectForCache); |
| 134 | if (entry !== undefined) return entry; |
| 135 | /** @type {Map<string, T>} */ |
| 136 | const map = new Map(); |
| 137 | cache.set(associatedObjectForCache, map); |
| 138 | return map; |
| 139 | }; |
| 140 | |
| 141 | /** @type {MakeCacheableResult<T> & { bindCache: BindCache<T> }} */ |
| 142 | const fn = (str, associatedObjectForCache) => { |
| 143 | if (!associatedObjectForCache) return realFn(str); |
| 144 | const cache = getCache(associatedObjectForCache); |
| 145 | const entry = cache.get(str); |
| 146 | if (entry !== undefined) return entry; |
| 147 | const result = realFn(str); |
| 148 | cache.set(str, result); |
| 149 | return result; |
| 150 | }; |
| 151 | |
| 152 | /** @type {BindCache<T>} */ |
| 153 | fn.bindCache = (associatedObjectForCache) => { |
| 154 | const cache = getCache(associatedObjectForCache); |
| 155 | /** |
| 156 | * Returns value. |
| 157 | * @param {string} str string |
| 158 | * @returns {T} value |
| 159 | */ |
| 160 | return (str) => { |
| 161 | const entry = cache.get(str); |
| 162 | if (entry !== undefined) return entry; |
| 163 | const result = realFn(str); |
| 164 | cache.set(str, result); |
| 165 | return result; |
| 166 | }; |
| 167 | }; |
| 168 | |
| 169 | return fn; |
| 170 | }; |
| 171 | |
| 172 | /** @typedef {(context: string, value: string, associatedObjectForCache?: AssociatedObjectForCache) => string} MakeCacheableWithContextResult */ |
| 173 | /** @typedef {(context: string, value: string) => string} BindCacheForContextResultFn */ |
no test coverage detected