Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
76 lines
2.1 KiB
Plaintext
76 lines
2.1 KiB
Plaintext
export function memoize(fn, options) {
|
|
const cache = options && options.cache ? options.cache : cacheDefault;
|
|
const serializer = options && options.serializer ? options.serializer : serializerDefault;
|
|
const strategy = options && options.strategy ? options.strategy : strategyDefault;
|
|
return strategy(fn, {
|
|
cache,
|
|
serializer
|
|
});
|
|
}
|
|
//
|
|
// Strategy
|
|
//
|
|
function isPrimitive(value) {
|
|
return value == null || typeof value === "number" || typeof value === "boolean";
|
|
}
|
|
function monadic(fn, cache, serializer, arg) {
|
|
const cacheKey = isPrimitive(arg) ? arg : serializer(arg);
|
|
let computedValue = cache.get(cacheKey);
|
|
if (typeof computedValue === "undefined") {
|
|
computedValue = fn.call(this, arg);
|
|
cache.set(cacheKey, computedValue);
|
|
}
|
|
return computedValue;
|
|
}
|
|
function variadic(fn, cache, serializer) {
|
|
const args = Array.prototype.slice.call(arguments, 3);
|
|
const cacheKey = serializer(args);
|
|
let computedValue = cache.get(cacheKey);
|
|
if (typeof computedValue === "undefined") {
|
|
computedValue = fn.apply(this, args);
|
|
cache.set(cacheKey, computedValue);
|
|
}
|
|
return computedValue;
|
|
}
|
|
function assemble(fn, context, strategy, cache, serialize) {
|
|
return strategy.bind(context, fn, cache, serialize);
|
|
}
|
|
function strategyDefault(fn, options) {
|
|
const strategy = fn.length === 1 ? monadic : variadic;
|
|
return assemble(fn, this, strategy, options.cache.create(), options.serializer);
|
|
}
|
|
function strategyVariadic(fn, options) {
|
|
return assemble(fn, this, variadic, options.cache.create(), options.serializer);
|
|
}
|
|
function strategyMonadic(fn, options) {
|
|
return assemble(fn, this, monadic, options.cache.create(), options.serializer);
|
|
}
|
|
//
|
|
// Serializer
|
|
//
|
|
const serializerDefault = function() {
|
|
return JSON.stringify(arguments);
|
|
};
|
|
//
|
|
// Cache
|
|
//
|
|
class ObjectWithoutPrototypeCache {
|
|
cache;
|
|
constructor() {
|
|
this.cache = Object.create(null);
|
|
}
|
|
get(key) {
|
|
return this.cache[key];
|
|
}
|
|
set(key, value) {
|
|
this.cache[key] = value;
|
|
}
|
|
}
|
|
const cacheDefault = { create: function create() {
|
|
return new ObjectWithoutPrototypeCache();
|
|
} };
|
|
export const strategies = {
|
|
variadic: strategyVariadic,
|
|
monadic: strategyMonadic
|
|
};
|