diff --git a/src/system/footer/shared_2.js b/src/system/footer/shared_2.js index 7885c9e6e..6b4c53498 100644 --- a/src/system/footer/shared_2.js +++ b/src/system/footer/shared_2.js @@ -5,6 +5,22 @@ import omit from 'omit.js' /* eslint-disable max-nested-callbacks, max-lines-per-function, complexity, max-lines, fp/no-loops, max-statements, max-depth, no-unreachable-loop */ const mainLogic = function (systems) { + const propDimensions = getPropDimensions(systems) + const groupedPropDimensions = groupPropDimensions(propDimensions) + const reducedPropDimensions = reducePropDimensions( + groupedPropDimensions, + systems, + ) + const finalPropDimensions = addTopSharedSystem(reducedPropDimensions) + const sortedGroupedPropDimensions = sortSystems(finalPropDimensions) + const systemsA = finalizeSystems(sortedGroupedPropDimensions) + systemsA.forEach(({ dimensions, ...props }) => { + console.log(props, dimensions) + }) + return systemsA +} + +const getPropDimensions = function (systems) { const systemsA = systems.map(({ dimensions, ...props }) => ({ dimensions, props, @@ -23,6 +39,10 @@ const mainLogic = function (systems) { .map(({ dimensions }) => dimensions) return [propName, propValue, allDimensions] }) + return propDimensions +} + +const groupPropDimensions = function (propDimensions) { const uniqueAllDimensions = propDimensions .map(([, , allDimensions]) => allDimensions) .filter((allDimensions, index, allAllDimensions) => @@ -38,134 +58,159 @@ const mainLogic = function (systems) { .map(([propName, propValue]) => [propName, propValue]) return [propEntries, allDimensions] }) - const groupedPropDimensionsA = groupedPropDimensions.map( - ([propEntries, allDimensions]) => { - const allDimensionsC = allDimensions.reduce( - (allDimensionsA, dimensions, index) => - Object.keys(dimensions) - .reverse() - .reduce((allDimensionsB, dimensionName) => { - const matching = systemsA.filter((system) => - allDimensionsB.some((dimensionsB, indexB) => - Object.entries(dimensionsB).every( - ([dimensionNameB, dimensionValueB]) => - system.dimensions[dimensionNameB] === dimensionValueB || - (indexB === index && dimensionNameB === dimensionName), - ), - ), - ) - - if (matching.length !== allDimensionsB.length) { - return allDimensionsB - } - - return [ - ...allDimensionsB.slice(0, index), - omit.default(allDimensionsB[index], [dimensionName]), - ...allDimensionsB.slice(index + 1), - ] - }, allDimensionsA), - allDimensions, - ) + return groupedPropDimensions +} - const allDimensionsE = allDimensionsC.filter( - (dimensions, index, allDimensionsD) => - allDimensionsD - .slice(index + 1) - .every( - (dimensionsB) => !isDeepStrictEqual(dimensions, dimensionsB), - ), - ) +const reducePropDimensions = function (groupedPropDimensions, systems) { + return groupedPropDimensions.map(([propEntries, allDimensions]) => + reduceEachPropDimensions(propEntries, allDimensions, systems), + ) +} - const allDimensionsF = allDimensionsE.filter( - (dimensions) => Object.keys(dimensions).length !== 0, - ) +const reduceEachPropDimensions = function ( + propEntries, + allDimensions, + systems, +) { + const allDimensionsC = reduceAllPropDimensions(allDimensions, systems) + const allDimensionsE = removeDuplicateDimensions(allDimensionsC) + const allDimensionsF = normalizeTopSystem(allDimensionsE) + const allDimensionsG = appendValues(allDimensionsF) + return [propEntries, allDimensionsG] +} - let allDimensionsG = allDimensionsF.map((dimensions) => - mapObj(dimensions, (dimensionName, dimensionValue) => [ - dimensionName, - [dimensionValue], - ]), - ) +const reduceAllPropDimensions = function (allDimensions, systems) { + return allDimensions.reduce( + (allDimensionsA, dimensions, index) => + Object.keys(dimensions).reduceRight((allDimensionsB, dimensionName) => { + const matching = systems.filter((system) => + allDimensionsB.some((dimensionsB, indexB) => + Object.entries(dimensionsB).every( + ([dimensionNameB, dimensionValueB]) => + system.dimensions[dimensionNameB] === dimensionValueB || + (indexB === index && dimensionNameB === dimensionName), + ), + ), + ) - let clean = true - - do { - clean = true - - for ( - let firstIndex = 0; - clean && firstIndex < allDimensionsG.length - 1; - firstIndex += 1 - ) { - const firstDimensions = allDimensionsG[firstIndex] - const dimensionNames = Object.keys(firstDimensions) - - for ( - let secondIndex = firstIndex + 1; - clean && secondIndex < allDimensionsG.length; - secondIndex += 1 - ) { - const secondDimensions = allDimensionsG[secondIndex] - const secondDimensionNames = Object.keys(secondDimensions) - - if (!isSameArray(dimensionNames, secondDimensionNames)) { - continue - } - - const differentDimensionNames = dimensionNames.filter( - (dimensionName) => - !isSameArray( - firstDimensions[dimensionName], - secondDimensions[dimensionName], - ), - ) - - if (differentDimensionNames.length !== 1) { - continue - } - - const [differentDimensionName] = differentDimensionNames - const newDimensionValue = [ - ...firstDimensions[differentDimensionName], - ...secondDimensions[differentDimensionName], - ] - const newDimensions = mapObj( - firstDimensions, - (dimensionName, dimensionValue) => [ - dimensionName, - dimensionName === differentDimensionName - ? newDimensionValue - : dimensionValue, - ], - ) - allDimensionsG = allDimensionsG - .map((dimensions, index) => - index === firstIndex ? newDimensions : dimensions, - ) - .filter((dimensions, index) => index !== secondIndex) - clean = false - } + if (matching.length !== allDimensionsB.length) { + return allDimensionsB } - } while (!clean) - return [propEntries, allDimensionsG] - }, + return [ + ...allDimensionsB.slice(0, index), + omit.default(allDimensionsB[index], [dimensionName]), + ...allDimensionsB.slice(index + 1), + ] + }, allDimensionsA), + allDimensions, ) - const groupedPropDimensionsB = groupedPropDimensionsA.some( +} + +const removeDuplicateDimensions = function (allDimensions) { + return allDimensions.filter((dimensions, index, allDimensionsA) => + allDimensionsA + .slice(index + 1) + .every((dimensionsB) => !isDeepStrictEqual(dimensions, dimensionsB)), + ) +} + +const normalizeTopSystem = function (allDimensions) { + return allDimensions.filter( + (dimensions) => Object.keys(dimensions).length !== 0, + ) +} + +const appendValues = function (allDimensions) { + let allDimensionsA = allDimensions.map((dimensions) => + mapObj(dimensions, (dimensionName, dimensionValue) => [ + dimensionName, + [dimensionValue], + ]), + ) + + let clean = true + + do { + clean = true + + for ( + let firstIndex = 0; + clean && firstIndex < allDimensionsA.length - 1; + firstIndex += 1 + ) { + const firstDimensions = allDimensionsA[firstIndex] + const dimensionNames = Object.keys(firstDimensions) + + for ( + let secondIndex = firstIndex + 1; + clean && secondIndex < allDimensionsA.length; + secondIndex += 1 + ) { + const secondDimensions = allDimensionsA[secondIndex] + const secondDimensionNames = Object.keys(secondDimensions) + + if (!isSameArray(dimensionNames, secondDimensionNames)) { + continue + } + + const differentDimensionNames = dimensionNames.filter( + (dimensionName) => + !isSameArray( + firstDimensions[dimensionName], + secondDimensions[dimensionName], + ), + ) + + if (differentDimensionNames.length !== 1) { + continue + } + + const [differentDimensionName] = differentDimensionNames + const newDimensionValue = [ + ...firstDimensions[differentDimensionName], + ...secondDimensions[differentDimensionName], + ] + const newDimensions = mapObj( + firstDimensions, + (dimensionName, dimensionValue) => [ + dimensionName, + dimensionName === differentDimensionName + ? newDimensionValue + : dimensionValue, + ], + ) + allDimensionsA = allDimensionsA + .map((dimensions, index) => + index === firstIndex ? newDimensions : dimensions, + ) + .filter((dimensions, index) => index !== secondIndex) + clean = false + } + } + } while (!clean) + + return allDimensionsA +} + +const addTopSharedSystem = function (reducedPropDimensions) { + return reducedPropDimensions.some( ([, allDimensions]) => allDimensions.length === 0, ) - ? groupedPropDimensionsA - : [[[], []], ...groupedPropDimensionsA] - const sortableGroupedPropDimensionsA = groupedPropDimensionsB + ? reducedPropDimensions + : [[[], []], ...reducedPropDimensions] +} + +const sortSystems = function (finalPropDimensions) { + return finalPropDimensions .map(([propEntries, allDimensions]) => { const hasNoDimensions = allDimensions.length === 0 - const sortedPropEntries = propEntries.sort(([propNameA], [propNameB]) => { + const propEntriesA = propEntries.sort(([propNameA], [propNameB]) => { const propOrderA = PROP_ORDER.indexOf(propNameA) const propOrderB = PROP_ORDER.indexOf(propNameB) return propOrderA > propOrderB ? 1 : -1 }) - return { hasNoDimensions, propEntries: sortedPropEntries, allDimensions } + return { hasNoDimensions, propEntries: propEntriesA, allDimensions } }) .sort((first, second) => { if (first.hasNoDimensions) { @@ -206,19 +251,13 @@ const mainLogic = function (systems) { return 1 }) - const sortedGroupedPropDimensions = sortableGroupedPropDimensionsA.map( - ({ propEntries, allDimensions }) => [propEntries, allDimensions], - ) - const systemsB = sortedGroupedPropDimensions.map( - ([propEntries, allDimensions]) => { - const props = Object.fromEntries(propEntries) - return { dimensions: allDimensions, ...props } - }, - ) - systemsB.forEach(({ dimensions, ...props }) => { - console.log(props, dimensions) +} + +const finalizeSystems = function (sortedGroupedPropDimensions) { + return sortedGroupedPropDimensions.map(({ propEntries, allDimensions }) => { + const props = Object.fromEntries(propEntries) + return { dimensions: allDimensions, ...props } }) - return systemsB } const isSameArray = function (arrayA, arrayB) { @@ -253,6 +292,8 @@ const getSystemTitle = function (allDimensions) { // - transform each id string into { id: string, title: string } // - add `system.title` // - fix `PROP_ORDER` with real order (use one from `serialize.js`) +// - [SPYD_VERSION_NAME] should always be in shared system, using the latest +// system's value const SYSTEMS = [ { dimensions: { os: 'linux', node_version: 'node_10', machine: 'one' },