@mui/x-data-grid
Version:
The Community plan edition of the Data Grid components (MUI X).
134 lines (131 loc) • 4.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.weakMapMemoize = weakMapMemoize;
// Original source:
// - https://github.com/reduxjs/reselect/blob/1c3fc05f041d32cd69c11a7f7deccf0bce6f4598/src/weakMapMemoize.ts
class StrongRef {
constructor(value) {
this.value = value;
}
deref() {
return this.value;
}
}
const getWeakRef = () => typeof WeakRef === 'undefined' ? StrongRef : WeakRef;
const Ref = /** @__PURE__ */getWeakRef();
const UNTERMINATED = 0;
const TERMINATED = 1;
function createCacheNode() {
return {
s: UNTERMINATED,
v: undefined,
o: null,
p: null
};
}
/**
* Derefences the argument if it is a Ref. Else if it is a value already, return it.
*
* @param r - the object to maybe deref
* @returns The derefenced value if the argument is a Ref, else the argument value itself.
*/
function maybeDeref(r) {
if (r instanceof Ref) {
return r.deref();
}
return r;
}
/**
* Inspired by the `weakMapMemoize` function from the `reselect` library.
*
* @see {@link https://github.com/reduxjs/reselect/blob/1c3fc05f041d32cd69c11a7f7deccf0bce6f4598/src/weakMapMemoize.ts `original source code`}
* @see {@link https://reselect.js.org/api/weakMapMemoize `weakMapMemoize api docs`}
*/
function weakMapMemoize(func, options = {}) {
let fnNode = createCacheNode();
const {
resultEqualityCheck
} = options;
let lastResult;
let resultsCount = 0;
function memoized() {
let cacheNode = fnNode;
// eslint-disable-next-line prefer-rest-params
const {
length
} = arguments;
for (let i = 0, l = length; i < l; i += 1) {
// eslint-disable-next-line prefer-rest-params
let arg = arguments[i];
if (typeof arg === 'function' || typeof arg === 'object' && arg !== null) {
// Following logic is added over the original `weakMapMemoize` to support the proper memoization of the `GridApiRef`
if ('current' in arg && 'instanceId' in arg.current) {
arg = arg.current.state;
}
// Objects go into a WeakMap
let objectCache = cacheNode.o;
if (objectCache === null) {
objectCache = new WeakMap();
cacheNode.o = objectCache;
}
const objectNode = objectCache.get(arg);
if (objectNode === undefined) {
cacheNode = createCacheNode();
objectCache.set(arg, cacheNode);
} else {
cacheNode = objectNode;
}
} else {
// Primitives go into a regular Map
let primitiveCache = cacheNode.p;
if (primitiveCache === null) {
primitiveCache = new Map();
cacheNode.p = primitiveCache;
}
const primitiveNode = primitiveCache.get(arg);
if (primitiveNode === undefined) {
cacheNode = createCacheNode();
primitiveCache.set(arg, cacheNode);
} else {
cacheNode = primitiveNode;
}
}
}
const terminatedNode = cacheNode;
let result;
if (cacheNode.s === TERMINATED) {
result = cacheNode.v;
} else {
// Allow errors to propagate
// eslint-disable-next-line prefer-spread, prefer-rest-params
result = func.apply(null, arguments);
resultsCount += 1;
if (resultEqualityCheck) {
// Deref lastResult if it is a Ref
const lastResultValue = maybeDeref(lastResult);
if (lastResultValue != null && resultEqualityCheck(lastResultValue, result)) {
result = lastResultValue;
if (resultsCount !== 0) {
resultsCount -= 1;
}
}
const needsWeakRef = typeof result === 'object' && result !== null || typeof result === 'function';
lastResult = needsWeakRef ? /** @__PURE__ */new Ref(result) : result;
}
}
terminatedNode.s = TERMINATED;
terminatedNode.v = result;
return result;
}
memoized.clearCache = () => {
fnNode = createCacheNode();
memoized.resetResultsCount();
};
memoized.resultsCount = () => resultsCount;
memoized.resetResultsCount = () => {
resultsCount = 0;
};
return memoized;
}