@mui/x-data-grid
Version:
The Community plan edition of the Data Grid components (MUI X).
243 lines (226 loc) • 10.6 kB
JavaScript
import { lruMemoize, createSelectorCreator } from 'reselect';
import { warnOnce } from '@mui/x-internals/warning';
import { argsEqual } from "../hooks/utils/useGridSelector.js";
const reselectCreateSelector = createSelectorCreator({
memoize: lruMemoize,
memoizeOptions: {
maxSize: 1,
equalityCheck: Object.is
}
});
// TODO v8: Remove this type
// TODO v8: Rename this type to `OutputSelector`
// TODO v8: Remove this type
// TODO v8: Rename this type to `SelectorArgs`
// TODO v8: Remove this type
// TODO v8: Rename this type to `CreateSelectorFunction`
const cache = new WeakMap();
function checkIsAPIRef(value) {
return 'current' in value && 'instanceId' in value.current;
}
const DEFAULT_INSTANCE_ID = {
id: 'default'
};
// TODO v8: Remove this function
export const createSelector = (a, b, c, d, e, f, ...other) => {
if (other.length > 0) {
throw new Error('Unsupported number of selectors');
}
let selector;
// eslint-disable-next-line id-denylist
if (a && b && c && d && e && f) {
selector = (stateOrApiRef, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, instanceId);
const vb = b(state, instanceId);
const vc = c(state, instanceId);
const vd = d(state, instanceId);
const ve = e(state, instanceId);
return f(va, vb, vc, vd, ve);
};
// eslint-disable-next-line id-denylist
} else if (a && b && c && d && e) {
selector = (stateOrApiRef, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, instanceId);
const vb = b(state, instanceId);
const vc = c(state, instanceId);
const vd = d(state, instanceId);
return e(va, vb, vc, vd);
};
} else if (a && b && c && d) {
selector = (stateOrApiRef, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, instanceId);
const vb = b(state, instanceId);
const vc = c(state, instanceId);
return d(va, vb, vc);
};
} else if (a && b && c) {
selector = (stateOrApiRef, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, instanceId);
const vb = b(state, instanceId);
return c(va, vb);
};
} else if (a && b) {
selector = (stateOrApiRef, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, instanceId);
return b(va);
};
} else {
throw new Error('Missing arguments');
}
// We use this property to detect if the selector was created with createSelector
// or it's only a simple function the receives the state and returns part of it.
selector.acceptsApiRef = true;
return selector;
};
// TODO v8: Rename this function to `createSelector`
export const createSelectorV8 = (a, b, c, d, e, f, ...other) => {
if (other.length > 0) {
throw new Error('Unsupported number of selectors');
}
let selector;
// eslint-disable-next-line id-denylist
if (a && b && c && d && e && f) {
selector = (stateOrApiRef, args, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, args, instanceId);
const vb = b(state, args, instanceId);
const vc = c(state, args, instanceId);
const vd = d(state, args, instanceId);
const ve = e(state, args, instanceId);
return f(va, vb, vc, vd, ve, args);
};
// eslint-disable-next-line id-denylist
} else if (a && b && c && d && e) {
selector = (stateOrApiRef, args, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, args, instanceId);
const vb = b(state, args, instanceId);
const vc = c(state, args, instanceId);
const vd = d(state, args, instanceId);
return e(va, vb, vc, vd, args);
};
} else if (a && b && c && d) {
selector = (stateOrApiRef, args, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, args, instanceId);
const vb = b(state, args, instanceId);
const vc = c(state, args, instanceId);
return d(va, vb, vc, args);
};
} else if (a && b && c) {
selector = (stateOrApiRef, args, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, args, instanceId);
const vb = b(state, args, instanceId);
return c(va, vb, args);
};
} else if (a && b) {
selector = (stateOrApiRef, args, instanceIdParam) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const instanceId = instanceIdParam ?? (isAPIRef ? stateOrApiRef.current.instanceId : DEFAULT_INSTANCE_ID);
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
const va = a(state, args, instanceId);
return b(va, args);
};
} else {
throw new Error('Missing arguments');
}
// We use this property to detect if the selector was created with createSelector
// or it's only a simple function the receives the state and returns part of it.
selector.acceptsApiRef = true;
return selector;
};
// TODO v8: Remove this function
export const createSelectorMemoized = (...args) => {
const selector = (stateOrApiRef, instanceId) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const cacheKey = isAPIRef ? stateOrApiRef.current.instanceId : instanceId ?? DEFAULT_INSTANCE_ID;
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
if (process.env.NODE_ENV !== 'production') {
if (cacheKey.id === 'default') {
warnOnce(['MUI X: A selector was called without passing the instance ID, which may impact the performance of the grid.', 'To fix, call it with `apiRef`, for example `mySelector(apiRef)`, or pass the instance ID explicitly, for example `mySelector(state, apiRef.current.instanceId)`.']);
}
}
const cacheArgsInit = cache.get(cacheKey);
const cacheArgs = cacheArgsInit ?? new Map();
const cacheFn = cacheArgs?.get(args);
if (cacheArgs && cacheFn) {
// We pass the cache key because the called selector might have as
// dependency another selector created with this `createSelector`.
return cacheFn(state, cacheKey);
}
const fn = reselectCreateSelector(...args);
if (!cacheArgsInit) {
cache.set(cacheKey, cacheArgs);
}
cacheArgs.set(args, fn);
return fn(state, cacheKey);
};
// We use this property to detect if the selector was created with createSelector
// or it's only a simple function the receives the state and returns part of it.
selector.acceptsApiRef = true;
return selector;
};
// TODO v8: Rename this function to `createSelectorMemoized`
export const createSelectorMemoizedV8 = (...args) => {
const selector = (stateOrApiRef, selectorArgs, instanceId) => {
const isAPIRef = checkIsAPIRef(stateOrApiRef);
const cacheKey = isAPIRef ? stateOrApiRef.current.instanceId : instanceId ?? DEFAULT_INSTANCE_ID;
const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
if (process.env.NODE_ENV !== 'production') {
if (cacheKey.id === 'default') {
warnOnce(['MUI X: A selector was called without passing the instance ID, which may impact the performance of the grid.', 'To fix, call it with `apiRef`, for example `mySelector(apiRef)`, or pass the instance ID explicitly, for example `mySelector(state, apiRef.current.instanceId)`.']);
}
}
const cacheArgsInit = cache.get(cacheKey);
const cacheArgs = cacheArgsInit ?? new Map();
const cacheFn = cacheArgs?.get(args);
if (cacheArgs && cacheFn) {
if (!argsEqual(cacheFn.selectorArgs, selectorArgs)) {
const reselectArgs = selectorArgs !== undefined ? [...args.slice(0, args.length - 1), () => selectorArgs, args[args.length - 1]] : args;
const fn = reselectCreateSelector(...reselectArgs);
fn.selectorArgs = selectorArgs;
cacheArgs.set(args, fn);
return fn(state, selectorArgs, cacheKey);
}
// We pass the cache key because the called selector might have as
// dependency another selector created with this `createSelector`.
return cacheFn(state, selectorArgs, cacheKey);
}
const reselectArgs = selectorArgs !== undefined ? [...args.slice(0, args.length - 1), () => selectorArgs, args[args.length - 1]] : args;
const fn = reselectCreateSelector(...reselectArgs);
fn.selectorArgs = selectorArgs;
if (!cacheArgsInit) {
cache.set(cacheKey, cacheArgs);
}
cacheArgs.set(args, fn);
return fn(state, selectorArgs, cacheKey);
};
// We use this property to detect if the selector was created with createSelector
// or it's only a simple function the receives the state and returns part of it.
selector.acceptsApiRef = true;
return selector;
};