import { getArrayCombinations } from './get-array-combinations.js' /** * Generates an ordered list of group names associated with the provided * modifiers and selectors. The groups are generated by combining all possible * combinations of modifiers with each selector at the end. Selectors are * prioritized over the quantity of modifiers. For example, `protected abstract * override get fields();` should prioritize the `'get-method'` group over the * `'protected-abstract-override-method'` group. * * @param props - The properties including selectors, modifiers, and cache. * @param props.selectors - The list of selectors. * @param props.modifiers - The list of modifiers. * @param props.cache - Cache to store computed groups. * @returns An array of generated group names. */ function generatePredefinedGroups({ selectors, modifiers, cache }) { let modifiersAndSelectorsKey = `${modifiers.join('&')}/${selectors.join('&')}` let cachedValue = cache.get(modifiersAndSelectorsKey) if (cachedValue) { return cachedValue } let allModifiersCombinations = [] for (let i = modifiers.length; i > 0; i--) { allModifiersCombinations.push(...getArrayCombinations(modifiers, i)) } let allModifiersCombinationPermutations = allModifiersCombinations.flatMap( result => getPermutations(result), ) let returnValue = [] for (let selector of selectors) { returnValue.push( ...allModifiersCombinationPermutations.map( modifiersCombinationPermutation => [...modifiersCombinationPermutation, selector].join('-'), ), selector, ) } cache.set(modifiersAndSelectorsKey, returnValue) return returnValue } /** * Generates all permutations of an array. This allows variations like * `'abstract-override-protected-get-method'`, * `'override-protected-abstract-get-method'`, * `'protected-abstract-override-get-method'`, etc., to be entered by the user * and always match the same group. Note that this can theoretically cause * performance issues if too many modifiers are entered at once (e.g., 8 * modifiers result in 40,320 permutations, 9 in 362,880). * * @param elements - The array of elements to permute. * @returns An array containing all permutations of the input elements. */ function getPermutations(elements) { let result = [] function backtrack(first) { if (first === elements.length) { result.push([...elements]) return } for (let i = first; i < elements.length; i++) { ;[elements[first], elements[i]] = [elements[i], elements[first]] backtrack(first + 1) ;[elements[first], elements[i]] = [elements[i], elements[first]] } } backtrack(0) return result } export { generatePredefinedGroups }