UNPKG

@mui/x-data-grid

Version:

The Community plan edition of the Data Grid components (MUI X).

243 lines (226 loc) 10.6 kB
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; };