{"version":3,"file":"merge.cjs","sources":["../../../../src/transformations/transformers/merge.ts"],"sourcesContent":["import { omit } from 'lodash';\nimport { map } from 'rxjs/operators';\n\nimport { MutableDataFrame } from '../../dataframe/MutableDataFrame';\nimport { DataFrame, Field } from '../../types/dataFrame';\nimport { DataTransformerInfo, TransformationApplicabilityLevels } from '../../types/transformations';\n\nimport { DataTransformerID } from './ids';\n\ninterface ValuePointer {\n  key: string;\n  index: number;\n}\n\nexport interface MergeTransformerOptions {}\n\nexport const mergeTransformer: DataTransformerInfo<MergeTransformerOptions> = {\n  id: DataTransformerID.merge,\n  name: 'Merge series/tables',\n  description: 'Merges multiple series/tables into a single serie/table',\n  defaultOptions: {},\n  isApplicable: (data: DataFrame[]) => {\n    return data.length > 1\n      ? TransformationApplicabilityLevels.Applicable\n      : TransformationApplicabilityLevels.NotApplicable;\n  },\n  isApplicableDescription: (data: DataFrame[]) => {\n    return `The merge transformation requires at least 2 data series to work. There is currently ${data.length} data series.`;\n  },\n  operator: (options) => (source) =>\n    source.pipe(\n      map((dataFrames) => {\n        if (!Array.isArray(dataFrames) || dataFrames.length <= 1) {\n          return dataFrames;\n        }\n\n        const data = dataFrames.filter((frame) => frame.fields.length > 0);\n\n        if (data.length === 0) {\n          return [dataFrames[0]];\n        }\n\n        const fieldNames = new Set<string>();\n        const fieldIndexByName: Record<string, Record<number, number>> = {};\n        const fieldNamesForKey: string[] = [];\n        const dataFrame = new MutableDataFrame({\n          refId: `${DataTransformerID.merge}-${data.map((frame) => frame.refId).join('-')}`,\n          fields: [],\n        });\n\n        for (let frameIndex = 0; frameIndex < data.length; frameIndex++) {\n          const frame = data[frameIndex];\n\n          for (let fieldIndex = 0; fieldIndex < frame.fields.length; fieldIndex++) {\n            const field = frame.fields[fieldIndex];\n\n            if (!fieldNames.has(field.name)) {\n              dataFrame.addField(copyFieldStructure(field));\n              fieldNames.add(field.name);\n            }\n\n            fieldIndexByName[field.name] = fieldIndexByName[field.name] || {};\n            fieldIndexByName[field.name][frameIndex] = fieldIndex;\n\n            if (data.length - 1 !== frameIndex) {\n              continue;\n            }\n\n            if (fieldExistsInAllFrames(fieldIndexByName, field, data)) {\n              fieldNamesForKey.push(field.name);\n            }\n          }\n        }\n\n        if (fieldNamesForKey.length === 0) {\n          return dataFrames;\n        }\n\n        const valuesByKey: Record<string, Array<Record<string, unknown>>> = {};\n        const valuesInOrder: ValuePointer[] = [];\n        const keyFactory = createKeyFactory(data, fieldIndexByName, fieldNamesForKey);\n        const valueMapper = createValueMapper(data, fieldNames, fieldIndexByName);\n\n        for (let frameIndex = 0; frameIndex < data.length; frameIndex++) {\n          const frame = data[frameIndex];\n\n          for (let valueIndex = 0; valueIndex < frame.length; valueIndex++) {\n            const key = keyFactory(frameIndex, valueIndex);\n            const value = valueMapper(frameIndex, valueIndex);\n\n            if (!Array.isArray(valuesByKey[key])) {\n              valuesByKey[key] = [value];\n              valuesInOrder.push(createPointer(key, valuesByKey));\n              continue;\n            }\n\n            let valueWasMerged = false;\n\n            valuesByKey[key] = valuesByKey[key].map((existing) => {\n              if (!isMergable(existing, value)) {\n                return existing;\n              }\n              valueWasMerged = true;\n              return { ...existing, ...value };\n            });\n\n            if (!valueWasMerged) {\n              valuesByKey[key].push(value);\n              valuesInOrder.push(createPointer(key, valuesByKey));\n            }\n          }\n        }\n\n        for (const pointer of valuesInOrder) {\n          const value = valuesByKey[pointer.key][pointer.index];\n\n          if (value) {\n            dataFrame.add(value);\n          }\n        }\n\n        return [dataFrame];\n      })\n    ),\n};\n\nconst copyFieldStructure = (field: Field): Field => {\n  return {\n    ...omit(field, ['values', 'state', 'labels', 'config']),\n    values: [],\n    config: {\n      ...omit(field.config, 'displayName'),\n    },\n  };\n};\n\nconst createKeyFactory = (\n  data: DataFrame[],\n  fieldPointerByName: Record<string, Record<string, number>>,\n  keyFieldNames: string[]\n) => {\n  const factoryIndex = keyFieldNames.reduce((index: Record<string, number[]>, fieldName) => {\n    return Object.keys(fieldPointerByName[fieldName]).reduce((index: Record<string, number[]>, frameIndex) => {\n      index[frameIndex] = index[frameIndex] || [];\n      index[frameIndex].push(fieldPointerByName[fieldName][frameIndex]);\n      return index;\n    }, index);\n  }, {});\n\n  return (frameIndex: number, valueIndex: number): string => {\n    return factoryIndex[frameIndex].reduce((key: string, fieldIndex: number) => {\n      return key + data[frameIndex].fields[fieldIndex].values[valueIndex];\n    }, '');\n  };\n};\n\nconst createValueMapper = (\n  data: DataFrame[],\n  fieldByName: Set<string>,\n  fieldIndexByName: Record<string, Record<number, number>>\n) => {\n  return (frameIndex: number, valueIndex: number) => {\n    const value: Record<string, unknown> = {};\n    const fieldNames = Array.from(fieldByName);\n\n    for (const fieldName of fieldNames) {\n      const fieldIndexByFrameIndex = fieldIndexByName[fieldName];\n      if (!fieldIndexByFrameIndex) {\n        continue;\n      }\n\n      const fieldIndex = fieldIndexByFrameIndex[frameIndex];\n      if (typeof fieldIndex !== 'number') {\n        continue;\n      }\n\n      const frame = data[frameIndex];\n      if (!frame || !frame.fields) {\n        continue;\n      }\n\n      const field = frame.fields[fieldIndex];\n      if (!field || !field.values) {\n        continue;\n      }\n\n      value[fieldName] = field.values[valueIndex];\n    }\n\n    return value;\n  };\n};\n\nconst isMergable = (existing: Record<string, unknown>, value: Record<string, unknown>): boolean => {\n  let mergable = true;\n\n  for (const prop in value) {\n    if (typeof existing[prop] === 'undefined') {\n      continue;\n    }\n\n    if (existing[prop] === null) {\n      continue;\n    }\n\n    if (existing[prop] !== value[prop]) {\n      mergable = false;\n      break;\n    }\n  }\n\n  return mergable;\n};\n\nconst fieldExistsInAllFrames = (\n  fieldIndexByName: Record<string, Record<number, number>>,\n  field: Field,\n  data: DataFrame[]\n) => {\n  return Object.keys(fieldIndexByName[field.name]).length === data.length;\n};\n\nconst createPointer = (key: string, valuesByKey: Record<string, Array<Record<string, unknown>>>): ValuePointer => {\n  return {\n    key,\n    index: valuesByKey[key].length - 1,\n  };\n};\n"],"names":["DataTransformerID","TransformationApplicabilityLevels","map","MutableDataFrame","omit","index"],"mappings":"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"}