memoization-registry
Version:
A generalized multi-key memoization solution that does not leak memory.
67 lines (66 loc) • 3.44 kB
JavaScript
/* IMPORT */
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _MemoizationRegistry_root, _MemoizationRegistry_finalizationRegistry;
import MildMap from 'mild-map';
import { isObject, isUndefined, last, traverse, weakize, unweakize } from './utils.js';
/* MAIN */
class MemoizationRegistry {
/* CONSTRUCTOR */
constructor() {
/* VARIABLES */
_MemoizationRegistry_root.set(this, void 0);
_MemoizationRegistry_finalizationRegistry.set(this, void 0);
/* API */
this.register = (keys, factory) => {
if (!keys.length)
throw new Error('Missing required memoization keys');
const nodes = traverse(__classPrivateFieldGet(this, _MemoizationRegistry_root, "f"), keys);
const leaf = last(nodes);
const cached = leaf.ref?.deref();
if (!isUndefined(cached))
return cached;
const value = factory();
if (isObject(value)) {
leaf.ref = new WeakRef(value);
__classPrivateFieldGet(this, _MemoizationRegistry_finalizationRegistry, "f").register(value, weakize(keys));
}
else {
leaf.ref = { deref: () => value };
}
return value;
};
this.unregister = (keys) => {
if (!keys.length)
throw new Error('Missing required memoization keys');
const nodes = traverse(__classPrivateFieldGet(this, _MemoizationRegistry_root, "f"), unweakize(keys));
const leaf = last(nodes);
if (!leaf)
return;
leaf.ref = undefined;
for (let i = nodes.length - 1; i >= 0; i--) {
const node = nodes[i];
if (node.ref)
break;
if (node.size)
break;
const parent = nodes[i - 1] || __classPrivateFieldGet(this, _MemoizationRegistry_root, "f");
parent.delete(keys[i]);
}
};
__classPrivateFieldSet(this, _MemoizationRegistry_root, new MildMap(), "f");
__classPrivateFieldSet(this, _MemoizationRegistry_finalizationRegistry, new FinalizationRegistry(this.unregister), "f");
}
}
_MemoizationRegistry_root = new WeakMap(), _MemoizationRegistry_finalizationRegistry = new WeakMap();
/* EXPORT */
export default MemoizationRegistry;