UNPKG

@embrace-io/web-sdk

Version:
111 lines (110 loc) 3.73 kB
import { getSelector } from "../../../utils/getSelector.js"; import { KEY_EMB_TYPE } from "../../../constants/attributes.js"; import { EmbraceInstrumentationBase } from "../../EmbraceInstrumentationBase/EmbraceInstrumentationBase.js"; import { ATTR_FIRST_INTERACTION_ELEMENT_SELECTOR, ATTR_FIRST_INTERACTION_ELEMENT_TYPE, ATTR_FIRST_INTERACTION_INTERACTION_TYPE, ATTR_FIRST_INTERACTION_TIME, ATTR_FIRST_INTERACTION_X, ATTR_FIRST_INTERACTION_Y, FIRST_INTERACTION_EVENT_NAME } from "./constants.js"; import { SeverityNumber } from "@opentelemetry/api-logs"; //#region src/instrumentations/first-interaction/FirstInteractionInstrumentation/FirstInteractionInstrumentation.ts var FirstInteractionInstrumentation = class extends EmbraceInstrumentationBase { _onClick; _onKeyDown; _onScroll; _listenersAttached = false; constructor({ diag, perf } = {}) { super({ instrumentationName: "FirstInteractionInstrumentation", instrumentationVersion: "1.0.0", diag, perf, config: {} }); this._onClick = (event) => { this._handle({ interactionType: event.pointerType === "touch" ? "tap" : "click", target: event.target instanceof Element ? event.target : null, timestamp: event.timeStamp, x: event.clientX, y: event.clientY }); }; this._onKeyDown = (event) => { this._handle({ interactionType: "keypress", target: event.target instanceof Element ? event.target : null, timestamp: event.timeStamp }); }; this._onScroll = (event) => { this._handle({ interactionType: "scroll", target: null, timestamp: event.timeStamp }); }; if (this._config.enabled) this.enable(); } onEnable() { this._attachListeners(); this.setSessionPartListeners({ start: () => { this._attachListeners(); } }); } onDisable() { this._detachListeners(); } _handle(data) { if (!this._listenersAttached) return; this._detachListeners(); try { this._emit(data); } catch (e) { this._diag.error("failed to process first-interaction candidate", e); } } _attachListeners() { if (this._listenersAttached) return; const opts = { capture: true, passive: true }; document.addEventListener("click", this._onClick, opts); document.addEventListener("keydown", this._onKeyDown, opts); document.addEventListener("scroll", this._onScroll, opts); this._listenersAttached = true; } _detachListeners() { if (!this._listenersAttached) return; const opts = { capture: true }; document.removeEventListener("click", this._onClick, opts); document.removeEventListener("keydown", this._onKeyDown, opts); document.removeEventListener("scroll", this._onScroll, opts); this._listenersAttached = false; } _emit(data) { let elementType = "document"; let elementSelector = ""; if (data.interactionType !== "scroll" && data.target) { elementType = data.target.tagName.toLowerCase(); elementSelector = getSelector(data.target); } const attributes = { [KEY_EMB_TYPE]: "emb.otel_log", [ATTR_FIRST_INTERACTION_INTERACTION_TYPE]: data.interactionType, [ATTR_FIRST_INTERACTION_ELEMENT_TYPE]: elementType, [ATTR_FIRST_INTERACTION_ELEMENT_SELECTOR]: elementSelector, [ATTR_FIRST_INTERACTION_TIME]: this.perf.millisFromZeroTime(data.timestamp) }; if (data.x !== void 0 && data.y !== void 0) { attributes[ATTR_FIRST_INTERACTION_X] = data.x; attributes[ATTR_FIRST_INTERACTION_Y] = data.y; } this.logger.emit({ timestamp: this.perf.epochMillisFromOrigin(data.timestamp), eventName: FIRST_INTERACTION_EVENT_NAME, severityNumber: SeverityNumber.INFO, attributes }); } }; //#endregion export { FirstInteractionInstrumentation }; //# sourceMappingURL=FirstInteractionInstrumentation.js.map