{"version":3,"file":"annotations.cjs","sources":["../../src/annotations.ts"],"sourcesContent":["import { Observable, of } from 'rxjs';\n\nimport {\n  type AnnotationEvent,\n  type AnnotationQuery,\n  type AnnotationSupport,\n  type DataFrame,\n  rangeUtil,\n  renderLegendFormat,\n} from '@grafana/data';\n\nimport { AnnotationQueryEditor } from './components/AnnotationQueryEditor';\nimport { type PrometheusDatasource } from './datasource';\nimport { type PromQuery } from './types';\n\nconst ANNOTATION_QUERY_STEP_DEFAULT = '60s';\n\nexport const PrometheusAnnotationSupport = (ds: PrometheusDatasource): AnnotationSupport<PromQuery> => {\n  return {\n    QueryEditor: AnnotationQueryEditor,\n    prepareAnnotation(json: AnnotationQuery<PromQuery>): AnnotationQuery<PromQuery> {\n      // Initialize target if it doesn't exist\n      if (!json.target) {\n        json.target = {\n          expr: '',\n          refId: 'Anno',\n        };\n      }\n\n      // Create a new target, preserving existing values when present\n      json.target = {\n        ...json.target,\n        refId: json.target.refId || json.refId || 'Anno',\n        expr: json.target.expr || json.expr || '',\n        interval: json.target.interval || json.step || '',\n      };\n\n      // Remove properties that have been transferred to target\n      delete json.expr;\n      delete json.step;\n\n      return json;\n    },\n    processEvents(anno: AnnotationQuery<PromQuery>, frames: DataFrame[]): Observable<AnnotationEvent[] | undefined> {\n      if (!frames.length) {\n        return new Observable<undefined>();\n      }\n\n      const { tagKeys = '', titleFormat = '', textFormat = '' } = anno;\n\n      const input = frames[0].meta?.executedQueryString || '';\n      const regex = /Step:\\s*([\\d\\w]+)/;\n      const match = input.match(regex);\n      const stepValue = match ? match[1] : null;\n      const step = rangeUtil.intervalToSeconds(stepValue || ANNOTATION_QUERY_STEP_DEFAULT) * 1000;\n      const tagKeysArray = tagKeys.split(',');\n\n      const eventList: AnnotationEvent[] = [];\n\n      for (const frame of frames) {\n        if (frame.fields.length === 0) {\n          continue;\n        }\n        const timeField = frame.fields[0];\n        const valueField = frame.fields[1];\n        const labels = valueField?.labels || {};\n\n        const tags = Object.keys(labels)\n          .filter((label) => tagKeysArray.includes(label))\n          .map((label) => labels[label]);\n\n        const timeValueTuple: Array<[number, number]> = [];\n\n        let idx = 0;\n        valueField.values.forEach((value: string) => {\n          let timeStampValue: number;\n          let valueValue: number;\n          const time = timeField.values[idx];\n\n          // If we want to use value as a time, we use value as timeStampValue and valueValue will be 1\n          if (anno.useValueForTime) {\n            timeStampValue = Math.floor(parseFloat(value));\n            valueValue = 1;\n          } else {\n            timeStampValue = Math.floor(parseFloat(time));\n            valueValue = parseFloat(value);\n          }\n\n          idx++;\n          timeValueTuple.push([timeStampValue, valueValue]);\n        });\n\n        const activeValues = timeValueTuple.filter((value) => value[1] > 0);\n        const activeValuesTimestamps = activeValues.map((value) => value[0]);\n\n        // Instead of creating singular annotation for each active event we group events into region if they are less\n        // or equal to `step` apart.\n        let latestEvent: AnnotationEvent | null = null;\n\n        for (const timestamp of activeValuesTimestamps) {\n          // We already have event `open` and we have new event that is inside the `step` so we just update the end.\n          if (latestEvent && (latestEvent.timeEnd ?? 0) + step >= timestamp) {\n            latestEvent.timeEnd = timestamp;\n            continue;\n          }\n\n          // Event exists but new one is outside of the `step` so we add it to eventList.\n          if (latestEvent) {\n            eventList.push(latestEvent);\n          }\n\n          // We start a new region.\n          latestEvent = {\n            time: timestamp,\n            timeEnd: timestamp,\n            annotation: anno,\n            title: renderLegendFormat(titleFormat, labels),\n            tags,\n            text: renderLegendFormat(textFormat, labels),\n          };\n        }\n\n        // Finish up last point if we have one\n        if (latestEvent) {\n          latestEvent.timeEnd = activeValuesTimestamps[activeValuesTimestamps.length - 1];\n          eventList.push(latestEvent);\n        }\n      }\n\n      return of(eventList);\n    },\n  };\n};\n"],"names":["AnnotationQueryEditor","Observable","rangeUtil","renderLegendFormat","of"],"mappings":"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"}