{"version":3,"file":"WebVitalsInstrumentation.cjs","names":["MAX_LOAF_SCRIPT_URL_LENGTH","KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX","getSelector","EmbraceInstrumentationBase","WEB_VITALS_ID_TO_LISTENER","isEntryTypeSupported","page","WEB_VITAL_EVENT_NAME","SeverityNumber","KEY_EMB_TYPE","KEY_BROWSER_WEB_VITAL_NAME","KEY_BROWSER_WEB_VITAL_VALUE","KEY_BROWSER_WEB_VITAL_DELTA","KEY_BROWSER_WEB_VITAL_RATING","KEY_BROWSER_WEB_VITAL_ID","KEY_BROWSER_WEB_VITAL_NAVIGATION_TYPE","KEY_BROWSER_WEB_VITAL_NAVIGATION_ID","KEY_BROWSER_WEB_VITAL_INTERACTION_ID","KEY_BROWSER_URL_FULL","KEY_EMB_PAGE_PATH","KEY_EMB_PAGE_ID","KEY_APP_SURFACE_LABEL"],"sources":["../../../../src/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport type { LogRecord } from '@opentelemetry/api-logs';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport { millisToHrTime } from '@opentelemetry/core';\nimport { safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';\nimport type {\n  CLSMetricWithAttribution,\n  INPAttribution,\n  LCPAttribution,\n  Metric,\n  MetricWithAttribution,\n  TTFBAttribution,\n} from 'web-vitals/attribution';\nimport type { PageManager } from '../../../api-page/index.ts';\nimport { page } from '../../../api-page/index.ts';\nimport type { URLDocument } from '../../../common/index.ts';\nimport {\n  EMB_TYPES,\n  KEY_APP_SURFACE_LABEL,\n  KEY_BROWSER_URL_FULL,\n  KEY_EMB_PAGE_ID,\n  KEY_EMB_PAGE_PATH,\n  KEY_EMB_TYPE,\n} from '../../../constants/index.ts';\nimport { getSelector } from '../../../utils/index.ts';\nimport { isEntryTypeSupported } from '../../../utils/performanceObserver/index.ts';\nimport { EmbraceInstrumentationBase } from '../../EmbraceInstrumentationBase/index.ts';\nimport {\n  KEY_BROWSER_WEB_VITAL_DELTA,\n  KEY_BROWSER_WEB_VITAL_ID,\n  KEY_BROWSER_WEB_VITAL_INTERACTION_ID,\n  KEY_BROWSER_WEB_VITAL_NAME,\n  KEY_BROWSER_WEB_VITAL_NAVIGATION_ID,\n  KEY_BROWSER_WEB_VITAL_NAVIGATION_TYPE,\n  KEY_BROWSER_WEB_VITAL_RATING,\n  KEY_BROWSER_WEB_VITAL_VALUE,\n  KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX,\n} from './attributes.ts';\nimport {\n  ALL_WEB_VITALS,\n  MAX_CLS_LAYOUT_SHIFTS,\n  MAX_LOAF_SCRIPT_ENTRIES,\n  MAX_LOAF_SCRIPT_URL_LENGTH,\n  WEB_VITAL_EVENT_NAME,\n  WEB_VITALS_ID_TO_LISTENER,\n} from './constants.ts';\nimport type {\n  WebVitalListeners,\n  WebVitalsInstrumentationConfig,\n} from './types.ts';\n\ntype AttributedPage = {\n  fullURL: string;\n  path?: string;\n  pageID?: string;\n  label?: string;\n};\n\nconst roundClamp = (value: number): number => Math.round(Math.max(0, value));\n\nconst roundRect = (rect?: DOMRectReadOnly) => ({\n  x: Math.round(rect?.x ?? 0),\n  y: Math.round(rect?.y ?? 0),\n  width: Math.round(rect?.width ?? 0),\n  height: Math.round(rect?.height ?? 0),\n});\n\nconst isPrimitiveValue = (\n  value: unknown,\n): value is string | number | boolean => {\n  const type = typeof value;\n  return type === 'number' || type === 'string' || type === 'boolean';\n};\n\nconst loafScriptsAttribution = (\n  metric: MetricWithAttribution,\n  diag: DiagLogger,\n): Attributes => {\n  const attributes: Attributes = {};\n  const attribution = metric.attribution as INPAttribution;\n\n  try {\n    // suppress LoAF baseline errors\n    /* eslint-disable baseline-js/use-baseline */\n    if (attribution.longAnimationFrameEntries.length > 0) {\n      const scripts = new Map<\n        string,\n        {\n          totalDuration: number;\n          styleAndLayoutDuration: number;\n          count: number;\n        }\n      >();\n      for (const entry of attribution.longAnimationFrameEntries) {\n        for (const script of entry.scripts) {\n          let url = script.sourceURL || '(inline)';\n          if (url.length > MAX_LOAF_SCRIPT_URL_LENGTH) {\n            url = `${url.substring(0, MAX_LOAF_SCRIPT_URL_LENGTH)}...`;\n          }\n          const existing = scripts.get(url);\n          if (existing) {\n            existing.totalDuration += script.duration;\n            existing.styleAndLayoutDuration +=\n              script.forcedStyleAndLayoutDuration;\n            existing.count++;\n          } else {\n            scripts.set(url, {\n              totalDuration: script.duration,\n              styleAndLayoutDuration: script.forcedStyleAndLayoutDuration,\n              count: 1,\n            });\n          }\n        }\n      }\n      if (scripts.size > 0) {\n        attributes[`${KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX}loaf_scripts`] =\n          JSON.stringify(\n            Object.fromEntries(\n              [...scripts]\n                .sort((a, b) => b[1].totalDuration - a[1].totalDuration)\n                .slice(0, MAX_LOAF_SCRIPT_ENTRIES)\n                .map(([url, script]) => [\n                  url,\n                  {\n                    total_duration: Math.round(script.totalDuration),\n                    style_and_layout_duration: Math.round(\n                      script.styleAndLayoutDuration,\n                    ),\n                    count: script.count,\n                  },\n                ]),\n            ),\n          );\n      }\n    }\n    /* eslint-enable baseline-js/use-baseline */\n  } catch (e) {\n    diag.error('error building loaf scripts for INP', e);\n  }\n\n  return attributes;\n};\n\nconst clsLayoutShiftsAttribution = (\n  metric: MetricWithAttribution,\n  diag: DiagLogger,\n): Attributes => {\n  const attributes: Attributes = {};\n\n  try {\n    /* eslint-disable baseline-js/use-baseline */\n    const entries = metric.entries as LayoutShift[];\n\n    if (entries.length > 0) {\n      const shifts = entries.slice(0, MAX_CLS_LAYOUT_SHIFTS).map((entry) => {\n        // web-vitals exposes sources sorted by impact area descending, so the\n        // first source is the element that contributed most to the shift.\n        const source = entry.sources[0];\n        return {\n          selector: getSelector(source?.node ?? null),\n          startRect: roundRect(source?.previousRect),\n          endRect: roundRect(source?.currentRect),\n        };\n      });\n\n      const prefix = KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX;\n      attributes[`${prefix}clsLayoutShifts`] = JSON.stringify(shifts);\n\n      if (entries.length > MAX_CLS_LAYOUT_SHIFTS) {\n        attributes[`${prefix}clsLayoutShiftsDroppedCount`] =\n          entries.length - MAX_CLS_LAYOUT_SHIFTS;\n      }\n    }\n    /* eslint-enable baseline-js/use-baseline */\n  } catch (e) {\n    diag.error('error building CLS layout shifts', e);\n  }\n\n  return attributes;\n};\n\nconst inpAttribution = (\n  metric: MetricWithAttribution,\n  diag: DiagLogger,\n): Attributes => {\n  const attributes: Attributes = {};\n\n  try {\n    /* eslint-disable baseline-js/use-baseline */\n    const target = (metric.entries as PerformanceEventTiming[]).find(\n      (entry) => entry.target,\n    )?.target as Element | null | undefined;\n\n    const tagName = target?.tagName?.toLowerCase();\n\n    if (tagName) {\n      attributes[`${KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX}element_type`] =\n        tagName;\n    }\n\n    /* eslint-enable baseline-js/use-baseline */\n  } catch (e) {\n    diag.error('error building INP element type attribution', e);\n  }\n\n  return attributes;\n};\n\nconst ttfbSubPartsAttribution = (\n  metric: MetricWithAttribution,\n  diag: DiagLogger,\n): Attributes => {\n  const attributes: Attributes = {};\n  const attribution = metric.attribution as TTFBAttribution;\n  const entry = attribution.navigationEntry as\n    | PerformanceNavigationTiming\n    | undefined;\n\n  if (entry) {\n    try {\n      const redirect = roundClamp(entry.redirectEnd - entry.redirectStart);\n      const domainLookup = roundClamp(\n        entry.domainLookupEnd - entry.domainLookupStart,\n      );\n      const tcpConnection = roundClamp(\n        entry.secureConnectionStart > 0\n          ? entry.secureConnectionStart - entry.connectStart\n          : entry.connectEnd - entry.connectStart,\n      );\n      const tlsNegotiation = roundClamp(\n        entry.secureConnectionStart > 0\n          ? entry.connectEnd - entry.secureConnectionStart\n          : 0,\n      );\n      const effectiveResponseStart = Math.max(\n        // @ts-expect-error 103 Early hints are not supported in all browsers\n        // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/finalResponseHeadersStart\n        entry.finalResponseHeadersStart ?? 0,\n        entry.responseStart,\n      );\n      const serverResponse = roundClamp(\n        effectiveResponseStart - entry.requestStart,\n      );\n      const total = Math.round(entry.responseEnd - entry.startTime);\n      const unattributed = roundClamp(\n        total -\n          redirect -\n          domainLookup -\n          tcpConnection -\n          tlsNegotiation -\n          serverResponse,\n      );\n      const prefix = KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX;\n      attributes[`${prefix}redirect`] = redirect;\n      attributes[`${prefix}domainLookup`] = domainLookup;\n      attributes[`${prefix}tcpConnection`] = tcpConnection;\n      attributes[`${prefix}tlsNegotiation`] = tlsNegotiation;\n      attributes[`${prefix}serverResponse`] = serverResponse;\n      attributes[`${prefix}unattributed`] = unattributed;\n    } catch (e) {\n      diag.error('error computing TTFB timing breakdown', e);\n    }\n  } else {\n    diag.debug('TTFB navigationEntry unavailable, skipping timing breakdown');\n  }\n\n  return attributes;\n};\n\nconst lcpElementAttribution = (\n  metric: MetricWithAttribution,\n  diag: DiagLogger,\n): Attributes => {\n  const attributes: Attributes = {};\n\n  try {\n    const attribution = metric.attribution as LCPAttribution;\n    const element = attribution.lcpEntry?.element;\n\n    if (element) {\n      const elementType = element.tagName.toLowerCase();\n      const elementBoundingRect = JSON.stringify(\n        roundRect(element.getBoundingClientRect()),\n      );\n\n      const prefix = KEY_EMB_WEB_VITAL_ATTRIBUTION_PREFIX;\n      attributes[`${prefix}elementType`] = elementType;\n      attributes[`${prefix}elementBoundingRect`] = elementBoundingRect;\n    }\n  } catch (e) {\n    diag.error('error building LCP element attribution', e);\n  }\n\n  return attributes;\n};\n\nexport class WebVitalsInstrumentation extends EmbraceInstrumentationBase {\n  private readonly _listeners: WebVitalListeners;\n  private readonly _urlDocument: URLDocument;\n  private readonly _urlAttribution: boolean;\n  private readonly _includeRawAttribution: boolean;\n  private readonly _softNavsActive: boolean;\n  private readonly _pageManager: PageManager;\n  private readonly _attributedPage: Record<\n    Metric['name'],\n    AttributedPage | undefined\n  > = {\n    INP: undefined,\n    LCP: undefined,\n    CLS: undefined,\n    FCP: undefined,\n    TTFB: undefined,\n  };\n  private _largestShiftTargetForCLS: string | undefined | null = null;\n  private _clsMetricId: string | undefined = undefined;\n  private _applyCustomLogRecordData?: (logRecord: LogRecord) => void;\n  private _listenersRegistered = false;\n\n  public constructor({\n    diag,\n    perf,\n    listeners = WEB_VITALS_ID_TO_LISTENER,\n    urlDocument,\n    urlAttribution = true,\n    includeRawAttribution = true,\n    reportSoftNavs = true,\n    pageManager,\n    applyCustomLogRecordData,\n    ...config\n  }: WebVitalsInstrumentationConfig = {}) {\n    super({\n      instrumentationName: 'WebVitalsInstrumentation',\n      instrumentationVersion: '1.0.0',\n      diag,\n      perf,\n      config,\n    });\n    this._listeners = listeners;\n    this._urlDocument = urlDocument ?? window.document;\n    this._urlAttribution = urlAttribution;\n    this._includeRawAttribution = includeRawAttribution;\n    this._softNavsActive =\n      reportSoftNavs && isEntryTypeSupported('soft-navigation');\n    this._pageManager = pageManager ?? page.getPageManager();\n    this._applyCustomLogRecordData = applyCustomLogRecordData;\n\n    if (this._config.enabled !== false) {\n      this.enable();\n    }\n  }\n\n  public override onDisable(): void {\n    // web-vitals library doesn't support removing listeners, so we just pause emission\n    // https://github.com/GoogleChrome/web-vitals/issues/357#issuecomment-1593439036\n    this._diag.debug('WebVitalsInstrumentation disabled, pausing emission');\n  }\n\n  public override enable(): void {\n    if (typeof PerformanceObserver !== 'undefined') {\n      super.enable();\n    } else {\n      this._diag.debug(\n        'PerformanceObserver not supported, web vitals will not be collected',\n      );\n    }\n  }\n\n  public override onEnable(): void {\n    // web-vitals library doesn't support removing listeners, so only register once\n    if (this._listenersRegistered) {\n      this._diag.debug(\n        'WebVitalsInstrumentation listeners already registered, resuming emission',\n      );\n      return;\n    }\n    this._listenersRegistered = true;\n\n    ALL_WEB_VITALS.forEach((name) => {\n      // web-vitals reports a hardcoded dummy value of zero for TTFB on soft navigations. That\n      // is not a real measurement and would skew the data, so TTFB listeners keep soft\n      // navigation reporting off.\n      const reportSoftNavs = name !== 'TTFB' && this._softNavsActive;\n\n      if (this._urlAttribution) {\n        this._listeners[name]?.(\n          (metric) => {\n            if (!this._isEnabled) {\n              return;\n            }\n            if (metric.name === 'CLS') {\n              const clsMetric = metric as CLSMetricWithAttribution;\n              const target = clsMetric.attribution.largestShiftTarget;\n\n              if (this._clsMetricId !== clsMetric.id) {\n                // A new metric ID means CLS has reset for a soft navigation.\n                this._clsMetricId = clsMetric.id;\n                this._largestShiftTargetForCLS = target;\n                this._attributedPage.CLS = this._currentAttributedPage();\n              } else if (this._largestShiftTargetForCLS !== target) {\n                // When the largest shift target changes, make sure the attributed page is updated\n                // to reflect the page where that shift occurred.\n                this._largestShiftTargetForCLS = target;\n                this._attributedPage.CLS = this._currentAttributedPage();\n              }\n            } else {\n              this._attributedPage[metric.name] = this._currentAttributedPage();\n            }\n          },\n          { reportAllChanges: true, reportSoftNavs },\n        );\n      }\n\n      this._listeners[name]?.(\n        (metric) => {\n          if (!this._isEnabled) {\n            return;\n          }\n          this._emitWebVital(metric);\n        },\n        { reportSoftNavs },\n      );\n    });\n  }\n\n  private _currentAttributedPage(): AttributedPage {\n    return {\n      fullURL: this._urlDocument.URL,\n      path: this._pageManager.getCurrentRoute()?.path,\n      pageID: this._pageManager.getCurrentPageId() ?? undefined,\n      label: this._pageManager.getPageLabel() ?? undefined,\n    };\n  }\n\n  private _getTimeForMetric(metric: MetricWithAttribution): number {\n    // For INP use interactionTime, which is the start time of the user's interaction\n    if (\n      metric.name === 'INP' &&\n      metric.attribution.interactionTime !== undefined\n    ) {\n      return this.perf.epochMillisFromOrigin(\n        metric.attribution.interactionTime,\n      );\n    }\n\n    // For CLS use the first layout shift's startTime, which is the beginning of\n    // the  session window. Fall back to largestShiftTime if the entries aren't\n    // available for some reason.\n    if (metric.name === 'CLS') {\n      const windowStart =\n        metric.entries.length > 0\n          ? Math.min(...metric.entries.map((entry) => entry.startTime))\n          : metric.attribution.largestShiftTime;\n\n      if (windowStart !== undefined) {\n        return this.perf.epochMillisFromOrigin(windowStart);\n      }\n    }\n\n    // For TTFB use the \"zero\" time of the current session part\n    if (metric.name === 'TTFB') {\n      return this.perf.getZeroTime();\n    }\n\n    // For other metrics, use the startTime of the last entry. Note: in practice, web-vitals does\n    // not emit multiple entries for metrics other than CLS. However to future-proof this code,\n    // we are assuming that the last entry is the most relevant one.\n    const metricStartTime =\n      metric.entries[metric.entries.length - 1]?.startTime;\n\n    if (metricStartTime !== undefined) {\n      return this.perf.epochMillisFromOrigin(metricStartTime);\n    }\n\n    // Fall back to when the metric was reported\n    return this.perf.getNowMillis();\n  }\n\n  private _emitWebVital(metric: MetricWithAttribution): void {\n    const attributedPage = this._attributedPage[metric.name];\n    const logRecord: LogRecord = {\n      eventName: WEB_VITAL_EVENT_NAME,\n      severityNumber: SeverityNumber.INFO,\n      attributes: {\n        [KEY_EMB_TYPE]: EMB_TYPES.WebVital,\n        [KEY_BROWSER_WEB_VITAL_NAME]: metric.name.toLowerCase(),\n        [KEY_BROWSER_WEB_VITAL_VALUE]: metric.value,\n        [KEY_BROWSER_WEB_VITAL_DELTA]: metric.delta,\n        [KEY_BROWSER_WEB_VITAL_RATING]: metric.rating,\n        [KEY_BROWSER_WEB_VITAL_ID]: metric.id,\n        [KEY_BROWSER_WEB_VITAL_NAVIGATION_TYPE]: metric.navigationType,\n        ...(metric.navigationId !== undefined\n          ? { [KEY_BROWSER_WEB_VITAL_NAVIGATION_ID]: metric.navigationId }\n          : {}),\n        ...(metric.navigationInteractionId !== undefined\n          ? {\n              [KEY_BROWSER_WEB_VITAL_INTERACTION_ID]:\n                metric.navigationInteractionId,\n            }\n          : {}),\n        ...(attributedPage\n          ? {\n              // The navigationURL emitted by web-vitals is authoritative for which URL the metric\n              // belongs to, since it was captured when the metric occurred. When soft navigations\n              // are not supported, we fall back to the attributed page.\n              [KEY_BROWSER_URL_FULL]:\n                metric.navigationURL != null &&\n                (metric.navigationType === 'soft-navigation' ||\n                  this._softNavsActive)\n                  ? metric.navigationURL\n                  : attributedPage.fullURL,\n              [KEY_EMB_PAGE_PATH]: attributedPage.path,\n              [KEY_EMB_PAGE_ID]: attributedPage.pageID,\n              [KEY_APP_SURFACE_LABEL]: attributedPage.label,\n            }\n          : {}),\n        ...(metric.name === 'INP'\n          ? loafScriptsAttribution(metric, this._diag)\n          : {}),\n        ...(metric.name === 'INP' ? inpAttribution(metric, this._diag) : {}),\n        ...(metric.name === 'TTFB'\n          ? ttfbSubPartsAttribution(metric, this._diag)\n          : {}),\n        ...(metric.name === 'CLS'\n          ? clsLayoutShiftsAttribution(metric, this._diag)\n          : {}),\n        ...(metric.name === 'LCP'\n          ? lcpElementAttribution(metric, this._diag)\n          : {}),\n      },\n      body:\n        this._includeRawAttribution && metric.attribution != null\n          ? JSON.stringify(\n              Object.fromEntries(\n                Object.entries(metric.attribution).filter(([, v]) =>\n                  isPrimitiveValue(v),\n                ),\n              ),\n            )\n          : undefined,\n      timestamp: millisToHrTime(this._getTimeForMetric(metric)),\n    };\n\n    if (this._applyCustomLogRecordData) {\n      safeExecuteInTheMiddle(\n        () => this._applyCustomLogRecordData?.(logRecord),\n        (error) => {\n          if (error) {\n            this._diag.error('applyCustomLogRecordData hook failed', error);\n          }\n        },\n        true,\n      );\n    }\n\n    this.logger.emit(logRecord);\n  }\n}\n"],"mappings":"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"}