{"version":3,"file":"UserTimingInstrumentation.cjs","names":["EmbraceInstrumentationBase","createPerformanceObserver","KEY_EMB_TYPE","KEY_EMB_INSTRUMENTATION","KEY_EMB_USER_TIMING_ENTRY_TYPE","KEY_EMB_USER_TIMING_START_TIME","KEY_EMB_USER_TIMING_DURATION","USER_TIMING_EVENT_NAME","SeverityNumber","KEY_EMB_USER_TIMING_NAME"],"sources":["../../../../src/instrumentations/user-timing/UserTimingInstrumentation/UserTimingInstrumentation.ts"],"sourcesContent":["import { SeverityNumber } from '@opentelemetry/api-logs';\nimport { EMB_PERFORMANCE_INSTRUMENTATIONS } from '../../../constants/attributes.ts';\nimport {\n  EMB_TYPES,\n  KEY_EMB_INSTRUMENTATION,\n  KEY_EMB_TYPE,\n} from '../../../constants/index.ts';\nimport { createPerformanceObserver } from '../../../utils/index.ts';\nimport { EmbraceInstrumentationBase } from '../../EmbraceInstrumentationBase/index.ts';\nimport {\n  KEY_EMB_USER_TIMING_DETAIL,\n  KEY_EMB_USER_TIMING_DURATION,\n  KEY_EMB_USER_TIMING_ENTRY_TYPE,\n  KEY_EMB_USER_TIMING_NAME,\n  KEY_EMB_USER_TIMING_START_TIME,\n  USER_TIMING_EVENT_NAME,\n} from './constants.ts';\nimport type {\n  UserTimingEntryFilter,\n  UserTimingInstrumentationArgs,\n} from './types.ts';\n\nexport class UserTimingInstrumentation extends EmbraceInstrumentationBase {\n  private _markObserver: PerformanceObserver | null = null;\n  private _measureObserver: PerformanceObserver | null = null;\n  private _seenEntries: Set<string> = new Set();\n  private _isEnabled = false;\n  private readonly _allowedEntries: UserTimingEntryFilter | undefined;\n\n  public constructor({\n    diag,\n    perf,\n    limitManager,\n    allowedEntries,\n  }: UserTimingInstrumentationArgs = {}) {\n    super({\n      instrumentationName: 'UserTimingInstrumentation',\n      instrumentationVersion: '1.0.0',\n      diag,\n      perf,\n      limitManager,\n      config: {},\n    });\n    this._allowedEntries = allowedEntries;\n\n    if (this._config.enabled) {\n      this.enable();\n    }\n  }\n\n  public enable(): void {\n    if (this._isEnabled) {\n      return;\n    }\n\n    this._isEnabled = true;\n    this._seenEntries = new Set();\n\n    if (this._markObserver) {\n      this._markObserver.disconnect();\n    }\n    if (this._measureObserver) {\n      this._measureObserver.disconnect();\n    }\n\n    this._markObserver = createPerformanceObserver<PerformanceMark>(\n      'mark',\n      this._processEntry.bind(this),\n      { diag: this._diag },\n    );\n\n    if (!this._markObserver) {\n      this._diag.error('failed to enable mark observer');\n    }\n\n    this._measureObserver = createPerformanceObserver<PerformanceMeasure>(\n      'measure',\n      (entry) => this._processEntry(entry),\n      { diag: this._diag },\n    );\n\n    if (!this._measureObserver) {\n      this._diag.error('failed to enable measure observer');\n    }\n\n    if (!this._markObserver && !this._measureObserver) {\n      this._isEnabled = false;\n    }\n  }\n\n  public disable(): void {\n    this._isEnabled = false;\n\n    if (this._markObserver) {\n      this._markObserver.disconnect();\n      this._markObserver = null;\n    }\n\n    if (this._measureObserver) {\n      this._measureObserver.disconnect();\n      this._measureObserver = null;\n    }\n\n    this._seenEntries = new Set();\n  }\n\n  private _processEntry(entry: PerformanceMark | PerformanceMeasure): void {\n    if (!this._isEnabled) {\n      return;\n    }\n\n    if (this._allowedEntries !== undefined) {\n      const allowed = Array.isArray(this._allowedEntries)\n        ? this._allowedEntries.includes(entry.name)\n        : this._allowedEntries(entry);\n      if (!allowed) {\n        return;\n      }\n    }\n\n    const key = `${location.href}::${entry.name}`;\n    // De-duplicate entries by name and page URL, only processing the first occurrence of each unique name on each page URL\n    if (this._seenEntries.has(key)) {\n      return;\n    }\n    this._seenEntries.add(key);\n\n    if (\n      this.limitManager?.limitUserTimingEntry(\n        entry.entryType as 'mark' | 'measure',\n      )\n    ) {\n      return;\n    }\n\n    if (entry.entryType === 'measure') {\n      const measureDetail = (entry as PerformanceMeasure).detail;\n      const span = this.tracer.startSpan(entry.name, {\n        startTime: this.perf.epochMillisFromOriginOffset(entry.startTime),\n        attributes: {\n          [KEY_EMB_TYPE]: EMB_TYPES.UserTiming,\n          [KEY_EMB_INSTRUMENTATION]:\n            EMB_PERFORMANCE_INSTRUMENTATIONS.UserTiming,\n          [KEY_EMB_USER_TIMING_ENTRY_TYPE]: entry.entryType,\n          [KEY_EMB_USER_TIMING_START_TIME]: this.perf.millisFromZeroTime(\n            entry.startTime,\n          ),\n          [KEY_EMB_USER_TIMING_DURATION]: entry.duration,\n          ...(measureDetail != null && {\n            [KEY_EMB_USER_TIMING_DETAIL]: JSON.stringify(measureDetail),\n          }),\n        },\n      });\n      span.end(\n        this.perf.epochMillisFromOriginOffset(entry.startTime + entry.duration),\n      );\n      return;\n    }\n\n    const detail = (entry as PerformanceMark).detail;\n    const body = detail != null ? JSON.stringify(detail) : undefined;\n\n    this.logger.emit({\n      timestamp: this.perf.epochMillisFromOriginOffset(entry.startTime),\n      eventName: USER_TIMING_EVENT_NAME,\n      severityNumber: SeverityNumber.INFO,\n      attributes: {\n        [KEY_EMB_TYPE]: EMB_TYPES.UserTiming,\n        [KEY_EMB_USER_TIMING_NAME]: entry.name,\n        [KEY_EMB_USER_TIMING_START_TIME]: this.perf.millisFromZeroTime(\n          entry.startTime,\n        ),\n        [KEY_EMB_USER_TIMING_DURATION]: entry.duration,\n        [KEY_EMB_USER_TIMING_ENTRY_TYPE]: entry.entryType,\n      },\n      body,\n    });\n  }\n}\n"],"mappings":"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"}