{"version":3,"file":"DataFrameJSON.cjs","sources":["../../../src/dataframe/DataFrameJSON.ts"],"sourcesContent":["import { Labels, QueryResultMeta } from '../types/data';\nimport { FieldType, DataFrame, Field, FieldConfig } from '../types/dataFrame';\n\nimport { guessFieldTypeFromNameAndValue } from './processDataFrame';\n\n/**\n * The JSON transfer object for DataFrames.  Values are stored in simple JSON\n *\n * @alpha\n */\nexport interface DataFrameJSON {\n  /**\n   * The schema defines the field type and configuration.\n   */\n  schema?: DataFrameSchema;\n\n  /**\n   * The field data\n   */\n  data?: DataFrameData;\n}\n\ntype FieldValues = unknown[];\n\n/**\n * @alpha\n */\nexport interface DataFrameData {\n  /**\n   * A columnar store that matches fields defined by schema.\n   */\n  values: FieldValues[];\n\n  /**\n   * Since JSON cannot encode NaN, Inf, -Inf, and undefined, these entities\n   * are decoded after JSON.parse() using this struct\n   */\n  entities?: Array<FieldValueEntityLookup | null>;\n\n  /**\n   * Holds value bases per field so we can encode numbers from fixed points\n   * e.g. [1612900958, 1612900959, 1612900960] -> 1612900958 + [0, 1, 2]\n   */\n  bases?: number[];\n\n  /**\n   * Holds value multipliers per field so we can encode large numbers concisely\n   * e.g. [4900000000, 35000000000] -> 1e9 + [4.9, 35]\n   */\n  factors?: number[];\n\n  /**\n   * Holds enums per field so we can encode recurring string values as ints\n   * e.g. [\"foo\", \"foo\", \"baz\", \"foo\"] -> [\"foo\", \"baz\"] + [0,0,1,0]\n   *\n   * NOTE: currently only decoding is implemented\n   */\n  enums?: Array<string[] | null>;\n\n  /**\n   * Holds integers between 0 and 999999, used by time-fields\n   * to store the nanosecond-precision that cannot be represented\n   * by the millisecond-based base value.\n   */\n  nanos?: Array<number[] | null>;\n}\n\n/**\n * The JSON transfer object for DataFrames.  Values are stored in simple JSON\n *\n * @alpha\n */\nexport interface DataFrameSchema {\n  /**\n   * Matches the query target refId\n   */\n  refId?: string;\n\n  /**\n   * Initial response global metadata\n   */\n  meta?: QueryResultMeta;\n\n  /**\n   * Frame name\n   */\n  name?: string;\n\n  /**\n   * Field definition without any metadata\n   */\n  fields: FieldSchema[];\n}\n\n/**\n * Field object passed over JSON\n *\n * @alpha\n */\nexport interface FieldSchema {\n  name: string; // The column name\n  type?: FieldType;\n  config?: FieldConfig;\n  labels?: Labels;\n}\n\n/**\n * Since JSON cannot encode NaN, Inf, -Inf, and undefined, the locations\n * of these entities in field value arrays are stored here for restoration\n * after JSON.parse()\n *\n * @alpha\n */\nexport interface FieldValueEntityLookup {\n  NaN?: number[];\n  Undef?: number[]; // Missing because of absence or join\n  Inf?: number[];\n  NegInf?: number[];\n}\n\nconst ENTITY_MAP: Record<keyof FieldValueEntityLookup, number | undefined> = {\n  Inf: Infinity,\n  NegInf: -Infinity,\n  Undef: undefined,\n  NaN: NaN,\n};\n\n/**\n * @internal use locally\n */\nexport function decodeFieldValueEntities(lookup: FieldValueEntityLookup, values: FieldValues) {\n  let key: keyof typeof lookup;\n  for (key in lookup) {\n    const repl = ENTITY_MAP[key];\n    for (const idx of lookup[key]!) {\n      if (idx < values.length) {\n        values[idx] = repl;\n      }\n    }\n  }\n}\n\n/**\n * @internal use locally\n */\nexport function decodeFieldValueEnums(lookup: string[], values: FieldValues) {\n  for (let i = 0; i < values.length; i++) {\n    values[i] = lookup[Number(values[i])];\n  }\n}\n\nfunction guessFieldType(name: string, values: FieldValues): FieldType {\n  for (const v of values) {\n    if (v != null) {\n      return guessFieldTypeFromNameAndValue(name, v);\n    }\n  }\n  return FieldType.other;\n}\n\n/**\n * NOTE: dto.data.values will be mutated and decoded/inflated using entities,bases,factors,enums\n *\n * @alpha\n */\nexport function dataFrameFromJSON(dto: DataFrameJSON): DataFrame {\n  const { schema, data } = dto;\n\n  if (!schema || !schema.fields) {\n    throw new Error('JSON needs a fields definition');\n  }\n\n  // Find the longest field length\n  const length = data ? data.values.reduce((max, vals) => Math.max(max, vals.length), 0) : 0;\n  const fields = schema.fields.map((f, index) => {\n    let buffer = data ? data.values[index] : [];\n    let origLen = buffer.length;\n    let type = f.type;\n\n    if (origLen !== length) {\n      buffer.length = length;\n      // avoid sparse arrays\n      buffer.fill(undefined, origLen);\n    }\n\n    let entities = data?.entities?.[index];\n\n    if (entities) {\n      decodeFieldValueEntities(entities, buffer);\n    }\n\n    let enums = data?.enums?.[index];\n\n    if (enums) {\n      decodeFieldValueEnums(enums, buffer);\n      type = FieldType.string;\n    }\n\n    const nanos = data?.nanos?.[index];\n\n    // TODO: expand arrays further using bases,factors\n\n    const dataFrameField: Field & { entities: FieldValueEntityLookup } = {\n      ...f,\n      type: type ?? guessFieldType(f.name, buffer),\n      config: f.config ?? {},\n      values: buffer,\n      // the presence of this prop is an optimization signal & lookup for consumers\n      entities: entities ?? {},\n    };\n\n    if (nanos != null) {\n      dataFrameField.nanos = nanos;\n    }\n\n    return dataFrameField;\n  });\n\n  return {\n    ...schema,\n    fields,\n    length,\n  };\n}\n\n/**\n * This converts DataFrame to a json representation with distinct schema+data\n *\n * @alpha\n */\nexport function dataFrameToJSON(frame: DataFrame): DataFrameJSON {\n  const data: DataFrameData = {\n    values: [],\n  };\n\n  const allNanos: Array<number[] | null> = [];\n  let hasNanos = false;\n\n  const schema: DataFrameSchema = {\n    refId: frame.refId,\n    meta: frame.meta,\n    name: frame.name,\n    fields: frame.fields.map((f) => {\n      const { values, nanos, state, display, ...sfield } = f;\n      if ('entities' in sfield) {\n        delete sfield.entities;\n      }\n      data.values.push(values);\n\n      if (nanos != null) {\n        allNanos.push(nanos);\n        hasNanos = true;\n      } else {\n        allNanos.push(null);\n      }\n\n      return sfield;\n    }),\n  };\n\n  if (hasNanos) {\n    data.nanos = allNanos;\n  }\n\n  return {\n    schema,\n    data,\n  };\n}\n"],"names":["guessFieldTypeFromNameAndValue","FieldType"],"mappings":"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"}