source: node_modules/reselect/src/utils.ts

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 5.4 KB
Line 
1import { runIdentityFunctionCheck } from './devModeChecks/identityFunctionCheck'
2import { runInputStabilityCheck } from './devModeChecks/inputStabilityCheck'
3import { globalDevModeChecks } from './devModeChecks/setGlobalDevModeChecks'
4// eslint-disable-next-line @typescript-eslint/consistent-type-imports
5import type {
6 DevModeChecks,
7 Selector,
8 SelectorArray,
9 DevModeChecksExecutionInfo
10} from './types'
11
12export const NOT_FOUND = 'NOT_FOUND'
13export type NOT_FOUND_TYPE = typeof NOT_FOUND
14
15/**
16 * Assert that the provided value is a function. If the assertion fails,
17 * a `TypeError` is thrown with an optional custom error message.
18 *
19 * @param func - The value to be checked.
20 * @param errorMessage - An optional custom error message to use if the assertion fails.
21 * @throws A `TypeError` if the assertion fails.
22 */
23export function assertIsFunction<FunctionType extends Function>(
24 func: unknown,
25 errorMessage = `expected a function, instead received ${typeof func}`
26): asserts func is FunctionType {
27 if (typeof func !== 'function') {
28 throw new TypeError(errorMessage)
29 }
30}
31
32/**
33 * Assert that the provided value is an object. If the assertion fails,
34 * a `TypeError` is thrown with an optional custom error message.
35 *
36 * @param object - The value to be checked.
37 * @param errorMessage - An optional custom error message to use if the assertion fails.
38 * @throws A `TypeError` if the assertion fails.
39 */
40export function assertIsObject<ObjectType extends Record<string, unknown>>(
41 object: unknown,
42 errorMessage = `expected an object, instead received ${typeof object}`
43): asserts object is ObjectType {
44 if (typeof object !== 'object') {
45 throw new TypeError(errorMessage)
46 }
47}
48
49/**
50 * Assert that the provided array is an array of functions. If the assertion fails,
51 * a `TypeError` is thrown with an optional custom error message.
52 *
53 * @param array - The array to be checked.
54 * @param errorMessage - An optional custom error message to use if the assertion fails.
55 * @throws A `TypeError` if the assertion fails.
56 */
57export function assertIsArrayOfFunctions<FunctionType extends Function>(
58 array: unknown[],
59 errorMessage = `expected all items to be functions, instead received the following types: `
60): asserts array is FunctionType[] {
61 if (
62 !array.every((item): item is FunctionType => typeof item === 'function')
63 ) {
64 const itemTypes = array
65 .map(item =>
66 typeof item === 'function'
67 ? `function ${item.name || 'unnamed'}()`
68 : typeof item
69 )
70 .join(', ')
71 throw new TypeError(`${errorMessage}[${itemTypes}]`)
72 }
73}
74
75/**
76 * Ensure that the input is an array. If it's already an array, it's returned as is.
77 * If it's not an array, it will be wrapped in a new array.
78 *
79 * @param item - The item to be checked.
80 * @returns An array containing the input item. If the input is already an array, it's returned without modification.
81 */
82export const ensureIsArray = (item: unknown) => {
83 return Array.isArray(item) ? item : [item]
84}
85
86/**
87 * Extracts the "dependencies" / "input selectors" from the arguments of `createSelector`.
88 *
89 * @param createSelectorArgs - Arguments passed to `createSelector` as an array.
90 * @returns An array of "input selectors" / "dependencies".
91 * @throws A `TypeError` if any of the input selectors is not function.
92 */
93export function getDependencies(createSelectorArgs: unknown[]) {
94 const dependencies = Array.isArray(createSelectorArgs[0])
95 ? createSelectorArgs[0]
96 : createSelectorArgs
97
98 assertIsArrayOfFunctions<Selector>(
99 dependencies,
100 `createSelector expects all input-selectors to be functions, but received the following types: `
101 )
102
103 return dependencies as SelectorArray
104}
105
106/**
107 * Runs each input selector and returns their collective results as an array.
108 *
109 * @param dependencies - An array of "dependencies" or "input selectors".
110 * @param inputSelectorArgs - An array of arguments being passed to the input selectors.
111 * @returns An array of input selector results.
112 */
113export function collectInputSelectorResults(
114 dependencies: SelectorArray,
115 inputSelectorArgs: unknown[] | IArguments
116) {
117 const inputSelectorResults = []
118 const { length } = dependencies
119 for (let i = 0; i < length; i++) {
120 // @ts-ignore
121 // apply arguments instead of spreading and mutate a local list of params for performance.
122 inputSelectorResults.push(dependencies[i].apply(null, inputSelectorArgs))
123 }
124 return inputSelectorResults
125}
126
127/**
128 * Retrieves execution information for development mode checks.
129 *
130 * @param devModeChecks - Custom Settings for development mode checks. These settings will override the global defaults.
131 * @param firstRun - Indicates whether it is the first time the selector has run.
132 * @returns An object containing the execution information for each development mode check.
133 */
134export const getDevModeChecksExecutionInfo = (
135 firstRun: boolean,
136 devModeChecks: Partial<DevModeChecks>
137) => {
138 const { identityFunctionCheck, inputStabilityCheck } = {
139 ...globalDevModeChecks,
140 ...devModeChecks
141 }
142 return {
143 identityFunctionCheck: {
144 shouldRun:
145 identityFunctionCheck === 'always' ||
146 (identityFunctionCheck === 'once' && firstRun),
147 run: runIdentityFunctionCheck
148 },
149 inputStabilityCheck: {
150 shouldRun:
151 inputStabilityCheck === 'always' ||
152 (inputStabilityCheck === 'once' && firstRun),
153 run: runInputStabilityCheck
154 }
155 } satisfies DevModeChecksExecutionInfo
156}
Note: See TracBrowser for help on using the repository browser.