{"version":3,"file":"browser-aggregator.js","sources":["../../../src/metrics/browser-aggregator.ts"],"sourcesContent":["import type { Client, MeasurementUnit, MetricsAggregator, Primitive } from '@sentry/types';\nimport { timestampInSeconds } from '@sentry/utils';\nimport { updateMetricSummaryOnActiveSpan } from '../utils/spanUtils';\nimport { DEFAULT_BROWSER_FLUSH_INTERVAL, SET_METRIC_TYPE } from './constants';\nimport { captureAggregateMetrics } from './envelope';\nimport { METRIC_MAP } from './instance';\nimport type { MetricBucket, MetricType } from './types';\nimport { getBucketKey, sanitizeMetricKey, sanitizeTags, sanitizeUnit } from './utils';\n\n/**\n * A simple metrics aggregator that aggregates metrics in memory and flushes them periodically.\n * Default flush interval is 5 seconds.\n *\n * @experimental This API is experimental and might change in the future.\n */\nexport class BrowserMetricsAggregator implements MetricsAggregator {\n // TODO(@anonrig): Use FinalizationRegistry to have a proper way of flushing the buckets\n // when the aggregator is garbage collected.\n // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry\n private _buckets: MetricBucket;\n private readonly _interval: ReturnType;\n\n public constructor(private readonly _client: Client) {\n this._buckets = new Map();\n this._interval = setInterval(() => this.flush(), DEFAULT_BROWSER_FLUSH_INTERVAL);\n }\n\n /**\n * @inheritDoc\n */\n public add(\n metricType: MetricType,\n unsanitizedName: string,\n value: number | string,\n unsanitizedUnit: MeasurementUnit | undefined = 'none',\n unsanitizedTags: Record | undefined = {},\n maybeFloatTimestamp: number | undefined = timestampInSeconds(),\n ): void {\n const timestamp = Math.floor(maybeFloatTimestamp);\n const name = sanitizeMetricKey(unsanitizedName);\n const tags = sanitizeTags(unsanitizedTags);\n const unit = sanitizeUnit(unsanitizedUnit as string);\n\n const bucketKey = getBucketKey(metricType, name, unit, tags);\n\n let bucketItem = this._buckets.get(bucketKey);\n // If this is a set metric, we need to calculate the delta from the previous weight.\n const previousWeight = bucketItem && metricType === SET_METRIC_TYPE ? bucketItem.metric.weight : 0;\n\n if (bucketItem) {\n bucketItem.metric.add(value);\n // TODO(abhi): Do we need this check?\n if (bucketItem.timestamp < timestamp) {\n bucketItem.timestamp = timestamp;\n }\n } else {\n bucketItem = {\n // @ts-expect-error we don't need to narrow down the type of value here, saves bundle size.\n metric: new METRIC_MAP[metricType](value),\n timestamp,\n metricType,\n name,\n unit,\n tags,\n };\n this._buckets.set(bucketKey, bucketItem);\n }\n\n // If value is a string, it's a set metric so calculate the delta from the previous weight.\n const val = typeof value === 'string' ? bucketItem.metric.weight - previousWeight : value;\n updateMetricSummaryOnActiveSpan(metricType, name, val, unit, unsanitizedTags, bucketKey);\n }\n\n /**\n * @inheritDoc\n */\n public flush(): void {\n // short circuit if buckets are empty.\n if (this._buckets.size === 0) {\n return;\n }\n\n const metricBuckets = Array.from(this._buckets.values());\n captureAggregateMetrics(this._client, metricBuckets);\n\n this._buckets.clear();\n }\n\n /**\n * @inheritDoc\n */\n public close(): void {\n clearInterval(this._interval);\n this.flush();\n }\n}\n"],"names":["DEFAULT_BROWSER_FLUSH_INTERVAL","timestampInSeconds","sanitizeMetricKey","sanitizeTags","sanitizeUnit","getBucketKey","SET_METRIC_TYPE","METRIC_MAP","updateMetricSummaryOnActiveSpan","captureAggregateMetrics"],"mappings":";;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,0BAAsD;AACnE;AACA;AACA;;AAIA,GAAS,WAAW,GAAkB,OAAO,EAAU,CAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACvD,IAAI,IAAI,CAAC,QAAA,GAAW,IAAI,GAAG,EAAE;AAC7B,IAAI,IAAI,CAAC,SAAA,GAAY,WAAW,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAEA,wCAA8B,CAAC;AACpF;;AAEA;AACA;AACA;AACA,GAAS,GAAG;AACZ,IAAI,UAAU;AACd,IAAI,eAAe;AACnB,IAAI,KAAK;AACT,IAAI,eAAe,GAAgC,MAAM;AACzD,IAAI,eAAe,GAA0C,EAAE;AAC/D,IAAI,mBAAmB,GAAuBC,0BAAkB,EAAE;AAClE,IAAU;AACV,IAAI,MAAM,YAAY,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC;AACrD,IAAI,MAAM,IAAK,GAAEC,uBAAiB,CAAC,eAAe,CAAC;AACnD,IAAI,MAAM,IAAK,GAAEC,kBAAY,CAAC,eAAe,CAAC;AAC9C,IAAI,MAAM,IAAK,GAAEC,kBAAY,CAAC,iBAA0B;;AAExD,IAAI,MAAM,SAAA,GAAYC,kBAAY,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;;AAEhE,IAAI,IAAI,UAAW,GAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;AACjD;AACA,IAAI,MAAM,cAAA,GAAiB,UAAA,IAAc,UAAW,KAAIC,yBAAgB,GAAE,UAAU,CAAC,MAAM,CAAC,MAAA,GAAS,CAAC;;AAEtG,IAAI,IAAI,UAAU,EAAE;AACpB,MAAM,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AAClC;AACA,MAAM,IAAI,UAAU,CAAC,SAAU,GAAE,SAAS,EAAE;AAC5C,QAAQ,UAAU,CAAC,SAAU,GAAE,SAAS;AACxC;AACA,WAAW;AACX,MAAM,aAAa;AACnB;AACA,QAAQ,MAAM,EAAE,IAAIC,mBAAU,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC;AACjD,QAAQ,SAAS;AACjB,QAAQ,UAAU;AAClB,QAAQ,IAAI;AACZ,QAAQ,IAAI;AACZ,QAAQ,IAAI;AACZ,OAAO;AACP,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC;AAC9C;;AAEA;AACA,IAAI,MAAM,GAAI,GAAE,OAAO,KAAA,KAAU,QAAS,GAAE,UAAU,CAAC,MAAM,CAAC,MAAA,GAAS,cAAA,GAAiB,KAAK;AAC7F,IAAIC,yCAA+B,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,CAAC;AAC5F;;AAEA;AACA;AACA;AACA,GAAS,KAAK,GAAS;AACvB;AACA,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAA,KAAS,CAAC,EAAE;AAClC,MAAM;AACN;;AAEA,IAAI,MAAM,aAAA,GAAgB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC5D,IAAIC,gCAAuB,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC;;AAExD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;AACzB;;AAEA;AACA;AACA;AACA,GAAS,KAAK,GAAS;AACvB,IAAI,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC;AACjC,IAAI,IAAI,CAAC,KAAK,EAAE;AAChB;AACA;;;;"}