Socket
Socket
Sign inDemoInstall

@datadog/browser-rum

Package Overview
Dependencies
Maintainers
1
Versions
256
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@datadog/browser-rum - npm Package Compare versions

Comparing version 4.37.0 to 4.38.0

cjs/domain/record/assembly.d.ts

2

cjs/domain/record/observers/focusObserver.d.ts

@@ -0,4 +1,4 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { FocusRecord } from '../../../types';
import type { ListenerHandler } from './utils';
export type FocusCallback = (data: FocusRecord['data']) => void;
export declare function initFocusObserver(focusCb: FocusCallback): ListenerHandler;

@@ -0,5 +1,6 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { LifeCycle } from '@datadog/browser-rum-core';
import type { FrustrationRecord } from '../../../types';
import type { ListenerHandler } from './utils';
import type { RecordIds } from './recordIds';
export type FrustrationCallback = (record: FrustrationRecord) => void;
export declare function initFrustrationObserver(lifeCycle: LifeCycle, frustrationCb: FrustrationCallback): ListenerHandler;
export declare function initFrustrationObserver(lifeCycle: LifeCycle, frustrationCb: FrustrationCallback, recordIds: RecordIds): ListenerHandler;

@@ -5,4 +5,3 @@ "use strict";

var types_1 = require("../../../types");
var utils_1 = require("./utils");
function initFrustrationObserver(lifeCycle, frustrationCb) {
function initFrustrationObserver(lifeCycle, frustrationCb, recordIds) {
return lifeCycle.subscribe(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, function (data) {

@@ -20,3 +19,3 @@ var _a, _b, _c;

frustrationTypes: data.rawRumEvent.action.frustration.type,
recordIds: data.domainContext.events.map(function (e) { return (0, utils_1.getRecordIdForEvent)(e); }),
recordIds: data.domainContext.events.map(function (e) { return recordIds.getIdForEvent(e); }),
},

@@ -23,0 +22,0 @@ });

export { initObservers } from './observers';
export { InputCallback, initInputObserver } from './inputObserver';
export { initMutationObserver, MutationCallBack, RumMutationRecord } from './mutationObserver';
export { DEFAULT_CONFIGURATION } from './observers.specHelper';
export { DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initMutationObserver = exports.initInputObserver = exports.initObservers = void 0;
exports.DEFAULT_SHADOW_ROOT_CONTROLLER = exports.DEFAULT_CONFIGURATION = exports.initMutationObserver = exports.initInputObserver = exports.initObservers = void 0;
var observers_1 = require("./observers");

@@ -10,2 +10,6 @@ Object.defineProperty(exports, "initObservers", { enumerable: true, get: function () { return observers_1.initObservers; } });

Object.defineProperty(exports, "initMutationObserver", { enumerable: true, get: function () { return mutationObserver_1.initMutationObserver; } });
var observers_specHelper_1 = require("./observers.specHelper");
Object.defineProperty(exports, "DEFAULT_CONFIGURATION", { enumerable: true, get: function () { return observers_specHelper_1.DEFAULT_CONFIGURATION; } });
var observers_specHelper_2 = require("./observers.specHelper");
Object.defineProperty(exports, "DEFAULT_SHADOW_ROOT_CONTROLLER", { enumerable: true, get: function () { return observers_specHelper_2.DEFAULT_SHADOW_ROOT_CONTROLLER; } });
//# sourceMappingURL=index.js.map

@@ -1,5 +0,4 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import { DOM_EVENT } from '@datadog/browser-core';
import type { InputState } from '../../../types';
import type { ListenerHandler } from './utils';
type InputObserverOptions = {

@@ -6,0 +5,0 @@ domEvents?: Array<DOM_EVENT.INPUT | DOM_EVENT.CHANGE>;

@@ -6,5 +6,5 @@ "use strict";

var constants_1 = require("../../../constants");
var eventsUtils_1 = require("../eventsUtils");
var privacy_1 = require("../privacy");
var serialization_1 = require("../serialization");
var utils_1 = require("./utils");
function initInputObserver(cb, defaultPrivacyLevel, _a) {

@@ -38,3 +38,3 @@ var _b = _a === void 0 ? {} : _a, _c = _b.domEvents, domEvents = _c === void 0 ? ["input" /* DOM_EVENT.INPUT */, "change" /* DOM_EVENT.CHANGE */] : _c, _d = _b.target, target = _d === void 0 ? document : _d;

if (type === 'radio' && name && target.checked) {
(0, utils_1.forEach)(document.querySelectorAll("input[type=\"radio\"][name=\"".concat(name, "\"]")), function (el) {
(0, browser_core_1.forEach)(document.querySelectorAll("input[type=\"radio\"][name=\"".concat(name, "\"]")), function (el) {
if (el !== target) {

@@ -65,3 +65,3 @@ // TODO: Consider the privacy implications for various differing input privacy levels

var stopEventListeners = (0, browser_core_1.addEventListeners)(target, domEvents, function (event) {
var target = (0, utils_1.getEventTarget)(event);
var target = (0, eventsUtils_1.getEventTarget)(event);
if (target instanceof HTMLInputElement ||

@@ -68,0 +68,0 @@ target instanceof HTMLTextAreaElement ||

@@ -1,5 +0,4 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import type { MediaInteraction } from '../../../types';
import type { ListenerHandler } from './utils';
export type MediaInteractionCallback = (p: MediaInteraction) => void;
export declare function initMediaInteractionObserver(mediaInteractionCb: MediaInteractionCallback, defaultPrivacyLevel: DefaultPrivacyLevel): ListenerHandler;

@@ -7,8 +7,8 @@ "use strict";

var types_1 = require("../../../types");
var eventsUtils_1 = require("../eventsUtils");
var privacy_1 = require("../privacy");
var serialization_1 = require("../serialization");
var utils_1 = require("./utils");
function initMediaInteractionObserver(mediaInteractionCb, defaultPrivacyLevel) {
var handler = function (event) {
var target = (0, utils_1.getEventTarget)(event);
var target = (0, eventsUtils_1.getEventTarget)(event);
if (!target ||

@@ -15,0 +15,0 @@ (0, privacy_1.getNodePrivacyLevel)(target, defaultPrivacyLevel) === constants_1.NodePrivacyLevel.HIDDEN ||

@@ -1,5 +0,5 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import type { BrowserIncrementalSnapshotRecord } from '../../../types';
import type { ListenerHandler } from './utils';
import type { RecordIds } from './recordIds';
export type MouseInteractionCallBack = (record: BrowserIncrementalSnapshotRecord) => void;
export declare function initMouseInteractionObserver(cb: MouseInteractionCallBack, defaultPrivacyLevel: DefaultPrivacyLevel): ListenerHandler;
export declare function initMouseInteractionObserver(cb: MouseInteractionCallBack, defaultPrivacyLevel: DefaultPrivacyLevel, recordIds: RecordIds): ListenerHandler;

@@ -8,7 +8,7 @@ "use strict";

var types_1 = require("../../../types");
var assembly_1 = require("../assembly");
var eventsUtils_1 = require("../eventsUtils");
var privacy_1 = require("../privacy");
var serialization_1 = require("../serialization");
var utils_1 = require("../utils");
var moveObserver_1 = require("./moveObserver");
var utils_2 = require("./utils");
var eventTypeToMouseInteraction = (_a = {},

@@ -33,5 +33,5 @@ // Listen for pointerup DOM events instead of mouseup for MouseInteraction/MouseUp records. This

_a);
function initMouseInteractionObserver(cb, defaultPrivacyLevel) {
function initMouseInteractionObserver(cb, defaultPrivacyLevel, recordIds) {
var handler = function (event) {
var target = (0, utils_2.getEventTarget)(event);
var target = (0, eventsUtils_1.getEventTarget)(event);
if ((0, privacy_1.getNodePrivacyLevel)(target, defaultPrivacyLevel) === constants_1.NodePrivacyLevel.HIDDEN || !(0, serialization_1.hasSerializedNode)(target)) {

@@ -53,3 +53,3 @@ return;

}
var record = (0, browser_core_1.assign)({ id: (0, utils_2.getRecordIdForEvent)(event) }, (0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.MouseInteraction, interaction));
var record = (0, browser_core_1.assign)({ id: recordIds.getIdForEvent(event) }, (0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.MouseInteraction, interaction));
cb(record);

@@ -56,0 +56,0 @@ };

@@ -0,4 +1,4 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { MousePosition } from '../../../types';
import { IncrementalSource } from '../../../types';
import type { ListenerHandler } from './utils';
export type MousemoveCallBack = (p: MousePosition[], source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove) => void;

@@ -5,0 +5,0 @@ export declare function initMoveObserver(cb: MousemoveCallBack): ListenerHandler;

@@ -6,10 +6,9 @@ "use strict";

var serialization_1 = require("../serialization");
var utils_1 = require("../utils");
var types_1 = require("../../../types");
var eventsUtils_1 = require("../eventsUtils");
var viewports_1 = require("../viewports");
var utils_2 = require("./utils");
var MOUSE_MOVE_OBSERVER_THRESHOLD = 50;
function initMoveObserver(cb) {
var updatePosition = (0, browser_core_1.throttle)(function (event) {
var target = (0, utils_2.getEventTarget)(event);
var target = (0, eventsUtils_1.getEventTarget)(event);
if ((0, serialization_1.hasSerializedNode)(target)) {

@@ -26,3 +25,3 @@ var coordinates = tryToComputeCoordinates(event);

};
cb([position], (0, utils_1.isTouchEvent)(event) ? types_1.IncrementalSource.TouchMove : types_1.IncrementalSource.MouseMove);
cb([position], (0, eventsUtils_1.isTouchEvent)(event) ? types_1.IncrementalSource.TouchMove : types_1.IncrementalSource.MouseMove);
}

@@ -39,3 +38,3 @@ }, MOUSE_MOVE_OBSERVER_THRESHOLD, {

function tryToComputeCoordinates(event) {
var _a = (0, utils_1.isTouchEvent)(event) ? event.changedTouches[0] : event, x = _a.clientX, y = _a.clientY;
var _a = (0, eventsUtils_1.isTouchEvent)(event) ? event.changedTouches[0] : event, x = _a.clientX, y = _a.clientY;
if (window.visualViewport) {

@@ -42,0 +41,0 @@ var _b = (0, viewports_1.convertMouseEventToLayoutCoordinates)(x, y), visualViewportX = _b.visualViewportX, visualViewportY = _b.visualViewportY;

@@ -0,1 +1,2 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { LifeCycle, RumConfiguration } from '@datadog/browser-rum-core';

@@ -14,3 +15,2 @@ import type { ElementsScrollPositions } from '../elementsScrollPositions';

import type { FocusCallback } from './focusObserver';
import type { ListenerHandler } from './utils';
interface ObserverParam {

@@ -17,0 +17,0 @@ lifeCycle: LifeCycle;

@@ -14,6 +14,8 @@ "use strict";

var focusObserver_1 = require("./focusObserver");
var recordIds_1 = require("./recordIds");
function initObservers(o) {
var recordIds = (0, recordIds_1.initRecordIds)();
var mutationHandler = (0, mutationObserver_1.initMutationObserver)(o.mutationCb, o.configuration, o.shadowRootsController, document);
var mousemoveHandler = (0, moveObserver_1.initMoveObserver)(o.mousemoveCb);
var mouseInteractionHandler = (0, mouseInteractionObserver_1.initMouseInteractionObserver)(o.mouseInteractionCb, o.configuration.defaultPrivacyLevel);
var mouseInteractionHandler = (0, mouseInteractionObserver_1.initMouseInteractionObserver)(o.mouseInteractionCb, o.configuration.defaultPrivacyLevel, recordIds);
var scrollHandler = (0, scrollObserver_1.initScrollObserver)(o.scrollCb, o.configuration.defaultPrivacyLevel, o.elementsScrollPositions);

@@ -26,3 +28,3 @@ var viewportResizeHandler = (0, viewportResizeObserver_1.initViewportResizeObserver)(o.viewportResizeCb);

var visualViewportResizeHandler = (0, viewportResizeObserver_1.initVisualViewportResizeObserver)(o.visualViewportResizeCb);
var frustrationHandler = (0, frustrationObserver_1.initFrustrationObserver)(o.lifeCycle, o.frustrationCb);
var frustrationHandler = (0, frustrationObserver_1.initFrustrationObserver)(o.lifeCycle, o.frustrationCb, recordIds);
return {

@@ -29,0 +31,0 @@ flush: function () {

@@ -1,6 +0,5 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import type { ElementsScrollPositions } from '../elementsScrollPositions';
import type { ScrollPosition } from '../../../types';
import type { ListenerHandler } from './utils';
export type ScrollCallback = (p: ScrollPosition) => void;
export declare function initScrollObserver(cb: ScrollCallback, defaultPrivacyLevel: DefaultPrivacyLevel, elementsScrollPositions: ElementsScrollPositions): ListenerHandler;

@@ -5,2 +5,3 @@ "use strict";

var browser_core_1 = require("@datadog/browser-core");
var eventsUtils_1 = require("../eventsUtils");
var privacy_1 = require("../privacy");

@@ -10,7 +11,6 @@ var serialization_1 = require("../serialization");

var constants_1 = require("../../../constants");
var utils_1 = require("./utils");
var SCROLL_OBSERVER_THRESHOLD = 100;
function initScrollObserver(cb, defaultPrivacyLevel, elementsScrollPositions) {
var updatePosition = (0, browser_core_1.throttle)(function (event) {
var target = (0, utils_1.getEventTarget)(event);
var target = (0, eventsUtils_1.getEventTarget)(event);
if (!target ||

@@ -17,0 +17,0 @@ (0, privacy_1.getNodePrivacyLevel)(target, defaultPrivacyLevel) === constants_1.NodePrivacyLevel.HIDDEN ||

@@ -0,4 +1,5 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { StyleSheetRule } from '../../../types';
import type { ListenerHandler } from './utils';
export type StyleSheetCallback = (s: StyleSheetRule) => void;
export declare function initStyleSheetObserver(cb: StyleSheetCallback): ListenerHandler;
export declare function getPathToNestedCSSRule(rule: CSSRule): number[] | undefined;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initStyleSheetObserver = void 0;
exports.getPathToNestedCSSRule = exports.initStyleSheetObserver = void 0;
var browser_core_1 = require("@datadog/browser-core");
var serialization_1 = require("../serialization");
var utils_1 = require("../utils");
function initStyleSheetObserver(cb) {

@@ -37,3 +36,3 @@ function checkStyleSheetAndCallback(styleSheet, callback) {

checkStyleSheetAndCallback(this.parentStyleSheet, function (id) {
var path = (0, utils_1.getPathToNestedCSSRule)(_this);
var path = getPathToNestedCSSRule(_this);
if (path) {

@@ -49,3 +48,3 @@ path.push(index || 0);

checkStyleSheetAndCallback(this.parentStyleSheet, function (id) {
var path = (0, utils_1.getPathToNestedCSSRule)(_this);
var path = getPathToNestedCSSRule(_this);
if (path) {

@@ -62,2 +61,21 @@ path.push(index);

exports.initStyleSheetObserver = initStyleSheetObserver;
function getPathToNestedCSSRule(rule) {
var path = [];
var currentRule = rule;
while (currentRule.parentRule) {
var rules_1 = Array.from(currentRule.parentRule.cssRules);
var index_1 = rules_1.indexOf(currentRule);
path.unshift(index_1);
currentRule = currentRule.parentRule;
}
// A rule may not be attached to a stylesheet
if (!currentRule.parentStyleSheet) {
return;
}
var rules = Array.from(currentRule.parentStyleSheet.cssRules);
var index = rules.indexOf(currentRule);
path.unshift(index);
return path;
}
exports.getPathToNestedCSSRule = getPathToNestedCSSRule;
//# sourceMappingURL=styleSheetObserver.js.map

@@ -0,3 +1,3 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { ViewportResizeDimension, VisualViewportRecord } from '../../../types';
import type { ListenerHandler } from './utils';
export type ViewportResizeCallback = (d: ViewportResizeDimension) => void;

@@ -4,0 +4,0 @@ export type VisualViewportResizeCallback = (data: VisualViewportRecord['data']) => void;

@@ -7,6 +7,6 @@ "use strict";

var types_1 = require("../../types");
var assembly_1 = require("./assembly");
var serialization_1 = require("./serialization");
var observers_1 = require("./observers");
var viewports_1 = require("./viewports");
var utils_1 = require("./utils");
var elementsScrollPositions_1 = require("./elementsScrollPositions");

@@ -22,5 +22,5 @@ var shadowRootsController_1 = require("./shadowRootsController");

var mutationCb = function (mutation) {
emit((0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.Mutation, mutation));
emit((0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.Mutation, mutation));
};
var inputCb = function (s) { return emit((0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.Input, s)); };
var inputCb = function (s) { return emit((0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.Input, s)); };
var shadowRootsController = (0, shadowRootsController_1.initShadowRootsController)(options.configuration, { mutationCb: mutationCb, inputCb: inputCb });

@@ -77,10 +77,10 @@ var takeFullSnapshot = function (timestamp, serializationContext) {

mediaInteractionCb: function (p) {
return emit((0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.MediaInteraction, p));
return emit((0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.MediaInteraction, p));
},
mouseInteractionCb: function (mouseInteractionRecord) { return emit(mouseInteractionRecord); },
mousemoveCb: function (positions, source) { return emit((0, utils_1.assembleIncrementalSnapshot)(source, { positions: positions })); },
mousemoveCb: function (positions, source) { return emit((0, assembly_1.assembleIncrementalSnapshot)(source, { positions: positions })); },
mutationCb: mutationCb,
scrollCb: function (p) { return emit((0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.Scroll, p)); },
styleSheetCb: function (r) { return emit((0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.StyleSheetRule, r)); },
viewportResizeCb: function (d) { return emit((0, utils_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.ViewportResize, d)); },
scrollCb: function (p) { return emit((0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.Scroll, p)); },
styleSheetCb: function (r) { return emit((0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.StyleSheetRule, r)); },
viewportResizeCb: function (d) { return emit((0, assembly_1.assembleIncrementalSnapshot)(types_1.IncrementalSource.ViewportResize, d)); },
frustrationCb: function (frustrationRecord) { return emit(frustrationRecord); },

@@ -87,0 +87,0 @@ focusCb: function (data) {

@@ -32,3 +32,3 @@ "use strict";

controllerByShadowRootSize: controllerByShadowRoot.size,
html: shadowRoot && (0, browser_core_1.isExperimentalFeatureEnabled)('shadow_dom_debug')
html: shadowRoot && (0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.SHADOW_DOM_DEBUG)
? shadowRoot.innerHTML.substring(0, 2000)

@@ -35,0 +35,0 @@ : undefined,

@@ -0,4 +1,4 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { FocusRecord } from '../../../types';
import type { ListenerHandler } from './utils';
export type FocusCallback = (data: FocusRecord['data']) => void;
export declare function initFocusObserver(focusCb: FocusCallback): ListenerHandler;

@@ -0,5 +1,6 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { LifeCycle } from '@datadog/browser-rum-core';
import type { FrustrationRecord } from '../../../types';
import type { ListenerHandler } from './utils';
import type { RecordIds } from './recordIds';
export type FrustrationCallback = (record: FrustrationRecord) => void;
export declare function initFrustrationObserver(lifeCycle: LifeCycle, frustrationCb: FrustrationCallback): ListenerHandler;
export declare function initFrustrationObserver(lifeCycle: LifeCycle, frustrationCb: FrustrationCallback, recordIds: RecordIds): ListenerHandler;
import { RecordType } from '../../../types';
import { getRecordIdForEvent } from './utils';
export function initFrustrationObserver(lifeCycle, frustrationCb) {
export function initFrustrationObserver(lifeCycle, frustrationCb, recordIds) {
return lifeCycle.subscribe(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, function (data) {

@@ -16,3 +15,3 @@ var _a, _b, _c;

frustrationTypes: data.rawRumEvent.action.frustration.type,
recordIds: data.domainContext.events.map(function (e) { return getRecordIdForEvent(e); }),
recordIds: data.domainContext.events.map(function (e) { return recordIds.getIdForEvent(e); }),
},

@@ -19,0 +18,0 @@ });

export { initObservers } from './observers';
export { InputCallback, initInputObserver } from './inputObserver';
export { initMutationObserver, MutationCallBack, RumMutationRecord } from './mutationObserver';
export { DEFAULT_CONFIGURATION } from './observers.specHelper';
export { DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper';
export { initObservers } from './observers';
export { initInputObserver } from './inputObserver';
export { initMutationObserver } from './mutationObserver';
export { DEFAULT_CONFIGURATION } from './observers.specHelper';
export { DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper';
//# sourceMappingURL=index.js.map

@@ -1,5 +0,4 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import { DOM_EVENT } from '@datadog/browser-core';
import type { InputState } from '../../../types';
import type { ListenerHandler } from './utils';
type InputObserverOptions = {

@@ -6,0 +5,0 @@ domEvents?: Array<DOM_EVENT.INPUT | DOM_EVENT.CHANGE>;

@@ -1,6 +0,6 @@

import { instrumentSetter, assign, addEventListeners } from '@datadog/browser-core';
import { instrumentSetter, assign, addEventListeners, forEach } from '@datadog/browser-core';
import { NodePrivacyLevel } from '../../../constants';
import { getEventTarget } from '../eventsUtils';
import { getNodePrivacyLevel, shouldMaskNode } from '../privacy';
import { getElementInputValue, getSerializedNodeId, hasSerializedNode } from '../serialization';
import { getEventTarget, forEach } from './utils';
export function initInputObserver(cb, defaultPrivacyLevel, _a) {

@@ -7,0 +7,0 @@ var _b = _a === void 0 ? {} : _a, _c = _b.domEvents, domEvents = _c === void 0 ? ["input" /* DOM_EVENT.INPUT */, "change" /* DOM_EVENT.CHANGE */] : _c, _d = _b.target, target = _d === void 0 ? document : _d;

@@ -1,5 +0,4 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import type { MediaInteraction } from '../../../types';
import type { ListenerHandler } from './utils';
export type MediaInteractionCallback = (p: MediaInteraction) => void;
export declare function initMediaInteractionObserver(mediaInteractionCb: MediaInteractionCallback, defaultPrivacyLevel: DefaultPrivacyLevel): ListenerHandler;
import { addEventListeners } from '@datadog/browser-core';
import { NodePrivacyLevel } from '../../../constants';
import { MediaInteractionType } from '../../../types';
import { getEventTarget } from '../eventsUtils';
import { getNodePrivacyLevel } from '../privacy';
import { getSerializedNodeId, hasSerializedNode } from '../serialization';
import { getEventTarget } from './utils';
export function initMediaInteractionObserver(mediaInteractionCb, defaultPrivacyLevel) {

@@ -8,0 +8,0 @@ var handler = function (event) {

@@ -1,5 +0,5 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import type { BrowserIncrementalSnapshotRecord } from '../../../types';
import type { ListenerHandler } from './utils';
import type { RecordIds } from './recordIds';
export type MouseInteractionCallBack = (record: BrowserIncrementalSnapshotRecord) => void;
export declare function initMouseInteractionObserver(cb: MouseInteractionCallBack, defaultPrivacyLevel: DefaultPrivacyLevel): ListenerHandler;
export declare function initMouseInteractionObserver(cb: MouseInteractionCallBack, defaultPrivacyLevel: DefaultPrivacyLevel, recordIds: RecordIds): ListenerHandler;

@@ -5,7 +5,7 @@ var _a;

import { IncrementalSource, MouseInteractionType } from '../../../types';
import { assembleIncrementalSnapshot } from '../assembly';
import { getEventTarget } from '../eventsUtils';
import { getNodePrivacyLevel } from '../privacy';
import { getSerializedNodeId, hasSerializedNode } from '../serialization';
import { assembleIncrementalSnapshot } from '../utils';
import { tryToComputeCoordinates } from './moveObserver';
import { getRecordIdForEvent, getEventTarget } from './utils';
var eventTypeToMouseInteraction = (_a = {},

@@ -30,3 +30,3 @@ // Listen for pointerup DOM events instead of mouseup for MouseInteraction/MouseUp records. This

_a);
export function initMouseInteractionObserver(cb, defaultPrivacyLevel) {
export function initMouseInteractionObserver(cb, defaultPrivacyLevel, recordIds) {
var handler = function (event) {

@@ -50,3 +50,3 @@ var target = getEventTarget(event);

}
var record = assign({ id: getRecordIdForEvent(event) }, assembleIncrementalSnapshot(IncrementalSource.MouseInteraction, interaction));
var record = assign({ id: recordIds.getIdForEvent(event) }, assembleIncrementalSnapshot(IncrementalSource.MouseInteraction, interaction));
cb(record);

@@ -53,0 +53,0 @@ };

@@ -0,4 +1,4 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { MousePosition } from '../../../types';
import { IncrementalSource } from '../../../types';
import type { ListenerHandler } from './utils';
export type MousemoveCallBack = (p: MousePosition[], source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove) => void;

@@ -5,0 +5,0 @@ export declare function initMoveObserver(cb: MousemoveCallBack): ListenerHandler;

import { addEventListeners, addTelemetryDebug, throttle } from '@datadog/browser-core';
import { getSerializedNodeId, hasSerializedNode } from '../serialization';
import { isTouchEvent } from '../utils';
import { IncrementalSource } from '../../../types';
import { getEventTarget, isTouchEvent } from '../eventsUtils';
import { convertMouseEventToLayoutCoordinates } from '../viewports';
import { getEventTarget } from './utils';
var MOUSE_MOVE_OBSERVER_THRESHOLD = 50;

@@ -8,0 +7,0 @@ export function initMoveObserver(cb) {

@@ -0,1 +1,2 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { LifeCycle, RumConfiguration } from '@datadog/browser-rum-core';

@@ -14,3 +15,2 @@ import type { ElementsScrollPositions } from '../elementsScrollPositions';

import type { FocusCallback } from './focusObserver';
import type { ListenerHandler } from './utils';
interface ObserverParam {

@@ -17,0 +17,0 @@ lifeCycle: LifeCycle;

@@ -11,6 +11,8 @@ import { initMoveObserver } from './moveObserver';

import { initFocusObserver } from './focusObserver';
import { initRecordIds } from './recordIds';
export function initObservers(o) {
var recordIds = initRecordIds();
var mutationHandler = initMutationObserver(o.mutationCb, o.configuration, o.shadowRootsController, document);
var mousemoveHandler = initMoveObserver(o.mousemoveCb);
var mouseInteractionHandler = initMouseInteractionObserver(o.mouseInteractionCb, o.configuration.defaultPrivacyLevel);
var mouseInteractionHandler = initMouseInteractionObserver(o.mouseInteractionCb, o.configuration.defaultPrivacyLevel, recordIds);
var scrollHandler = initScrollObserver(o.scrollCb, o.configuration.defaultPrivacyLevel, o.elementsScrollPositions);

@@ -23,3 +25,3 @@ var viewportResizeHandler = initViewportResizeObserver(o.viewportResizeCb);

var visualViewportResizeHandler = initVisualViewportResizeObserver(o.visualViewportResizeCb);
var frustrationHandler = initFrustrationObserver(o.lifeCycle, o.frustrationCb);
var frustrationHandler = initFrustrationObserver(o.lifeCycle, o.frustrationCb, recordIds);
return {

@@ -26,0 +28,0 @@ flush: function () {

@@ -1,6 +0,5 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core';
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core';
import type { ElementsScrollPositions } from '../elementsScrollPositions';
import type { ScrollPosition } from '../../../types';
import type { ListenerHandler } from './utils';
export type ScrollCallback = (p: ScrollPosition) => void;
export declare function initScrollObserver(cb: ScrollCallback, defaultPrivacyLevel: DefaultPrivacyLevel, elementsScrollPositions: ElementsScrollPositions): ListenerHandler;
import { throttle, addEventListener } from '@datadog/browser-core';
import { getEventTarget } from '../eventsUtils';
import { getNodePrivacyLevel } from '../privacy';

@@ -6,3 +7,2 @@ import { getSerializedNodeId, hasSerializedNode } from '../serialization';

import { NodePrivacyLevel } from '../../../constants';
import { getEventTarget } from './utils';
var SCROLL_OBSERVER_THRESHOLD = 100;

@@ -9,0 +9,0 @@ export function initScrollObserver(cb, defaultPrivacyLevel, elementsScrollPositions) {

@@ -0,4 +1,5 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { StyleSheetRule } from '../../../types';
import type { ListenerHandler } from './utils';
export type StyleSheetCallback = (s: StyleSheetRule) => void;
export declare function initStyleSheetObserver(cb: StyleSheetCallback): ListenerHandler;
export declare function getPathToNestedCSSRule(rule: CSSRule): number[] | undefined;
import { instrumentMethodAndCallOriginal } from '@datadog/browser-core';
import { getSerializedNodeId, hasSerializedNode } from '../serialization';
import { getPathToNestedCSSRule } from '../utils';
export function initStyleSheetObserver(cb) {

@@ -56,2 +55,20 @@ function checkStyleSheetAndCallback(styleSheet, callback) {

}
export function getPathToNestedCSSRule(rule) {
var path = [];
var currentRule = rule;
while (currentRule.parentRule) {
var rules_1 = Array.from(currentRule.parentRule.cssRules);
var index_1 = rules_1.indexOf(currentRule);
path.unshift(index_1);
currentRule = currentRule.parentRule;
}
// A rule may not be attached to a stylesheet
if (!currentRule.parentStyleSheet) {
return;
}
var rules = Array.from(currentRule.parentStyleSheet.cssRules);
var index = rules.indexOf(currentRule);
path.unshift(index);
return path;
}
//# sourceMappingURL=styleSheetObserver.js.map

@@ -0,3 +1,3 @@

import type { ListenerHandler } from '@datadog/browser-core';
import type { ViewportResizeDimension, VisualViewportRecord } from '../../../types';
import type { ListenerHandler } from './utils';
export type ViewportResizeCallback = (d: ViewportResizeDimension) => void;

@@ -4,0 +4,0 @@ export type VisualViewportResizeCallback = (data: VisualViewportRecord['data']) => void;

import { timeStampNow } from '@datadog/browser-core';
import { getViewportDimension } from '@datadog/browser-rum-core';
import { RecordType, IncrementalSource } from '../../types';
import { assembleIncrementalSnapshot } from './assembly';
import { serializeDocument } from './serialization';
import { initObservers } from './observers';
import { getVisualViewport, getScrollX, getScrollY } from './viewports';
import { assembleIncrementalSnapshot } from './utils';
import { createElementsScrollPositions } from './elementsScrollPositions';

@@ -9,0 +9,0 @@ import { initShadowRootsController } from './shadowRootsController';

@@ -1,2 +0,2 @@

import { addTelemetryDebug, isExperimentalFeatureEnabled } from '@datadog/browser-core';
import { addTelemetryDebug, ExperimentalFeature, isExperimentalFeatureEnabled } from '@datadog/browser-core';
import { initInputObserver, initMutationObserver } from './observers';

@@ -29,3 +29,3 @@ export var initShadowRootsController = function (configuration, _a) {

controllerByShadowRootSize: controllerByShadowRoot.size,
html: shadowRoot && isExperimentalFeatureEnabled('shadow_dom_debug')
html: shadowRoot && isExperimentalFeatureEnabled(ExperimentalFeature.SHADOW_DOM_DEBUG)
? shadowRoot.innerHTML.substring(0, 2000)

@@ -32,0 +32,0 @@ : undefined,

{
"name": "@datadog/browser-rum",
"version": "4.37.0",
"version": "4.38.0",
"license": "Apache-2.0",

@@ -15,7 +15,7 @@ "main": "cjs/entries/main.js",

"dependencies": {
"@datadog/browser-core": "4.37.0",
"@datadog/browser-rum-core": "4.37.0"
"@datadog/browser-core": "4.38.0",
"@datadog/browser-rum-core": "4.38.0"
},
"peerDependencies": {
"@datadog/browser-logs": "4.37.0"
"@datadog/browser-logs": "4.38.0"
},

@@ -39,3 +39,3 @@ "peerDependenciesMeta": {

},
"gitHead": "058831610a12a72ff5e650e47a6ce8cfe9e20012"
"gitHead": "61ff7fdf8c51ea1bb789cb3d865ad094bfcdcf71"
}
# RUM Browser Monitoring
## Overview
Datadog Real User Monitoring (RUM) enables you to visualize and analyze the real-time performance and user journeys of your application's individual users.
Datadog Real User Monitoring (RUM) enables you to visualize and analyze the real-time performance and user journeys of your application's individual users. To collect events, add the RUM Browser SDK to your browser application and configure what data is collected using initialization parameters.
See the [dedicated datadog documentation][1] for more details.
## Setup
## Usage
The RUM Browser SDK supports all modern desktop and mobile browsers including IE11. For more information, see the [Browser Support][8] table.
To start collecting events, add [`@datadog/browser-rum`][2] to your `package.json` file, then initialize it with:
To set up RUM Browser Monitoring, create a RUM application:
1. In Datadog, navigate to the [**RUM Applications** page][1] and click the **New Application** button.
- Enter a name for your application and click **Generate Client Token**. This generates a `clientToken` and an `applicationId` for your application.
- Choose the installation type for the RUM Browser SDK: [npm](#npm), or a hosted version ([CDN async](#cdn-async) or [CDN sync](#cdn-sync)).
- Define the environment name and service name for your application to use unified service tagging for [RUM & Session Replay][19]. Set a version number for your deployed application in the initialization snippet. For more information, see [Tagging](#tagging).
- Set the sampling rate of total user sessions collected and use the slider to set the percentage of total [Browser RUM & Session Replay][11] sessions collected. Browser RUM & Session Replay sessions include resources, long tasks, and replay recordings. For more information about configuring the percentage of Browser RUM & Session Replay sessions collected from the total amount of user sessions, see [Configure Your Setup For Browser and Browser RUM & Session Replay Sampling][21].
- Click the **Session Replay Enabled** toggle to access replay recordings in [Session Replay][17].
- Select a [privacy setting][18] for Session Replay in the dropdown menu.
2. Deploy the changes to your application. Once your deployment is live, Datadog collects events from your users' browsers.
3. Visualize the [data collected][2] in [dashboards][3] or create a search query in the [RUM Explorer][16].
Until Datadog starts receiving data, your application appears as `pending` on the **RUM Applications** page.
### Choose the right installation method
npm (node package manager)
: This method is recommended for modern web applications. The RUM Browser SDK is packaged with the rest of your front-end JavaScript code. It has no impact on page load performance. However, the SDK may miss errors, resources, and user actions triggered before the SDK is initialized. Datadog recommends using a matching version with the Browser Logs SDK.
CDN async
: This method is recommended for web applications with performance targets. The RUM Browser SDK loads from our CDN asynchronously, ensuring the SDK download does not impact page load performance. However, the SDK may miss errors, resources, and user actions triggered before the SDK is initialized.
CDN sync
: This method is recommended for collecting all RUM events. The RUM Browser SDK loads from our CDN synchronously, ensuring the SDK loads first and collects all errors, resources, and user actions. This method may impact page load performance.
### npm
Add [`@datadog/browser-rum`][4] to your `package.json` file, then initialize it with:
<details open>
<summary>Latest version</summary>
```javascript

@@ -61,597 +29,7 @@ import { datadogRum } from '@datadog/browser-rum'

</details>
**Note**: The `trackUserInteractions` parameter enables the automatic collection of user clicks in your application. **Sensitive and private data** contained in your pages may be included to identify the elements interacted with.
<details>
<summary>before <code>v4.30.0</code></summary>
```javascript
import { datadogRum } from '@datadog/browser-rum'
datadogRum.init({
applicationId: '<DATADOG_APPLICATION_ID>',
clientToken: '<DATADOG_CLIENT_TOKEN>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
sessionReplaySampleRate: 100, // if not included, the default is 100
trackResources: true,
trackLongTasks: true,
trackInteractions: true,
})
```
</details>
<details>
<summary>before <code>v4.20.0</code></summary>
```javascript
import { datadogRum } from '@datadog/browser-rum'
datadogRum.init({
applicationId: '<DATADOG_APPLICATION_ID>',
clientToken: '<DATADOG_CLIENT_TOKEN>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
premiumSampleRate: 100, // if not included, the default is 100
trackInteractions: true,
})
```
</details>
<details>
<summary>before <code>v4.10.2</code></summary>
```javascript
import { datadogRum } from '@datadog/browser-rum'
datadogRum.init({
applicationId: '<DATADOG_APPLICATION_ID>',
clientToken: '<DATADOG_CLIENT_TOKEN>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
replaySampleRate: 100, // if not included, the default is 100
trackInteractions: true,
})
```
</details>
The `trackUserInteractions` and `trackFrustrations` parameters enable the automatic collection of user clicks in your application. **Sensitive and private data** contained in your pages may be included to identify the elements interacted with.
### CDN async
Add the generated code snippet to the head tag of every HTML page you want to monitor in your application.
<details open>
<summary>Latest version</summary>
<!-- prettier-ignore -->
```html
<script>
(function(h,o,u,n,d) {
h=h[d]=h[d]||{q:[],onReady:function(c){h.q.push(c)}}
d=o.createElement(u);d.async=1;d.src=n
n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n)
})(window,document,'script','https://www.datadoghq-browser-agent.com/datadog-rum-v4.js','DD_RUM')
DD_RUM.onReady(function() {
DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sessionSampleRate: 100,
sessionReplaySampleRate: 100, // if not included, the default is 100
trackResources: true,
trackLongTasks: true,
trackUserInteractions: true,
})
})
</script>
```
</details>
<details>
<summary>before<code>v4.30.0</code></summary>
<!-- prettier-ignore -->
```html
<script>
(function(h,o,u,n,d) {
h=h[d]=h[d]||{q:[],onReady:function(c){h.q.push(c)}}
d=o.createElement(u);d.async=1;d.src=n
n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n)
})(window,document,'script','https://www.datadoghq-browser-agent.com/datadog-rum-v4.js','DD_RUM')
DD_RUM.onReady(function() {
DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
sessionReplaySampleRate: 100, // if not included, the default is 100
trackResources: true,
trackLongTasks: true,
trackInteractions: true,
})
})
</script>
```
</details>
<details>
<summary>before<code>v4.20.0</code></summary>
<!-- prettier-ignore -->
```html
<script>
(function(h,o,u,n,d) {
h=h[d]=h[d]||{q:[],onReady:function(c){h.q.push(c)}}
d=o.createElement(u);d.async=1;d.src=n
n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n)
})(window,document,'script','https://www.datadoghq-browser-agent.com/datadog-rum-v4.js','DD_RUM')
DD_RUM.onReady(function() {
DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
premiumSampleRate: 100, // if not included, the default is 100
trackInteractions: true,
})
})
</script>
```
</details>
<details>
<summary>before<code>v4.10.2</code></summary>
<!-- prettier-ignore -->
```html
<script>
(function(h,o,u,n,d) {
h=h[d]=h[d]||{q:[],onReady:function(c){h.q.push(c)}}
d=o.createElement(u);d.async=1;d.src=n
n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n)
})(window,document,'script','https://www.datadoghq-browser-agent.com/datadog-rum-v4.js','DD_RUM')
DD_RUM.onReady(function() {
DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
replaySampleRate: 100, // if not included, the default is 100
trackInteractions: true,
})
})
</script>
```
</details>
The `trackUserInteractions` and `trackFrustrations` parameters enable the automatic collection of user clicks in your application. **Sensitive and private data** contained in your pages may be included to identify the elements interacted with.
Early RUM API calls must be wrapped in the `DD_RUM.onReady()` callback. This ensures the code only gets executed once the SDK is properly loaded.
### CDN sync
Add the generated code snippet to the head tag (in front of any other script tags) of every HTML page you want to monitor in your application. Including the script tag higher and synchronized ensures Datadog RUM can collect all performance data and errors.
<details open>
<summary>Latest version</summary>
```html
<script src="https://www.datadoghq-browser-agent.com/datadog-rum-v4.js" type="text/javascript"></script>
<script>
window.DD_RUM &&
window.DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sessionSampleRate: 100,
sessionReplaySampleRate: 100, // if not included, the default is 100
trackResources: true,
trackLongTasks: true,
trackUserInteractions: true,
})
</script>
```
</details>
<details>
<summary>before<code>v4.30.0</code></summary>
```html
<script src="https://www.datadoghq-browser-agent.com/datadog-rum-v4.js" type="text/javascript"></script>
<script>
window.DD_RUM &&
window.DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
sessionReplaySampleRate: 100, // if not included, the default is 100
trackResources: true,
trackLongTasks: true,
trackInteractions: true,
})
</script>
```
</details>
<details>
<summary>before<code>v4.20.0</code></summary>
```html
<script src="https://www.datadoghq-browser-agent.com/datadog-rum-v4.js" type="text/javascript"></script>
<script>
window.DD_RUM &&
window.DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
premiumSampleRate: 100, // if not included, the default is 100
trackInteractions: true,
})
</script>
```
</details>
<details>
<summary>before<code>v4.10.2</code></summary>
```html
<script src="https://www.datadoghq-browser-agent.com/datadog-rum-v4.js" type="text/javascript"></script>
<script>
window.DD_RUM &&
window.DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
// service: 'my-web-application',
// env: 'production',
// version: '1.0.0',
sampleRate: 100,
replaySampleRate: 100, // if not included, the default is 100
trackInteractions: true,
})
</script>
```
</details>
The `trackUserInteractions` and `trackFrustrations` parameters enable the automatic collection of user clicks in your application. **Sensitive and private data** contained in your pages may be included to identify the elements interacted with.
The `window.DD_RUM` check is used to prevent issues if a loading failure occurs with the RUM Browser SDK.
### TypeScript
Types are compatible with TypeScript >= 3.8.2. For earlier versions, import JavaScript sources and use global variables to avoid any compilation issues:
```javascript
import '@datadog/browser-rum/bundle/datadog-rum'
window.DD_RUM.init({
applicationId: 'XXX',
clientToken: 'XXX',
site: 'datadoghq.com',
sessionSampleRate: 100,
sessionReplaySampleRate: 100, // if not included, the default is 100
trackResources: true,
trackLongTasks: true,
})
```
## Configuration
### Initialization parameters
Call the initialization command to start tracking. The following parameters are available:
`applicationId`
: Required<br/>
**Type**: String<br/>
The RUM application ID.
`clientToken`
: Required<br/>
**Type**: String<br/>
A [Datadog client token][5].
`site`
: Required<br/>
**Type**: String<br/>
**Default**: `datadoghq.com`<br/>
[The Datadog site parameter of your organization][14].
`service`
: Optional<br/>
**Type**: String<br/>
The service name for your application. Follows the [tag syntax requirements][15].
`env`
: Optional<br/>
**Type**: String<br/>
The application’s environment, for example: prod, pre-prod, and staging. Follows the [tag syntax requirements][15].
`version`
: Optional<br/>
**Type**: String<br/>
The application’s version, for example: 1.2.3, 6c44da20, and 2020.02.13. Follows the [tag syntax requirements][15].
`trackViewsManually`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false` <br/>
Allows you to control RUM views creation. See [override default RUM view names][10].
`trackInteractions`
: Optional - **Deprecated**<br/>
**Type**: Boolean<br/>
**Default**: `false` <br/>
See `trackUserInteractions`.
`trackUserInteractions`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false` <br/>
Enables [automatic collection of users actions][6].
`trackFrustrations`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false` <br/>
Enables [automatic collection of user frustrations][20]. Implies `trackUserInteractions: true`.
`trackResources`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false` <br/>
Enables collection of resource events.
`trackLongTasks`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false` <br/>
Enables collection of long task events.
`defaultPrivacyLevel`
: Optional<br/>
**Type**: String<br/>
**Default**: `mask-user-input` <br/>
See [Session Replay Privacy Options][13].
`actionNameAttribute`
: Optional<br/>
**Type**: String<br/>
Specify your own attribute to be used to [name actions][9].
`sampleRate`
: Optional - **Deprecated**<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
See ``sessionSampleRate`.
`sessionSampleRate`
: Optional<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
The percentage of sessions to track: `100` for all, `0` for none. Only tracked sessions send RUM events. For more details about `sessionSampleRate`, see the [sampling configuration][21].
`replaySampleRate`
: Optional - **Deprecated**<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
See `sessionReplaySampleRate`.
`premiumSampleRate`
: Optional - **Deprecated**<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
See `sessionReplaySampleRate`.
`sessionReplaySampleRate`
: Optional<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
The percentage of tracked sessions with [Browser RUM & Session Replay pricing][11] features: `100` for all, `0` for none. For more details about `sessionReplaySampleRate`, see the [sampling configuration][21].
`silentMultipleInit`
: Optional<br/>
**Type**: Boolean <br/>
**Default**: `false`<br/>
Initialization fails silently if the RUM Browser SDK is already initialized on the page.
`proxyUrl`
: Optional<br/>
**Type**: String<br/>
Optional proxy URL, for example: https://www.proxy.com/path. For more information, see the full [proxy setup guide][7].
`allowedTracingOrigins`
: Optional - **Deprecated**<br/>
**Type**: List<br/>
A list of request origins used to inject tracing headers. For more information, see [Connect RUM and Traces][12].
`allowedTracingUrls`
: Optional<br/>
**Type**: List<br/>
A list of request URLs used to inject tracing headers. For more information, see [Connect RUM and Traces][12].
`tracingSampleRate`
: Optional - **Deprecated**<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
See `traceSampleRate`.
`traceSampleRate`
: Optional<br/>
**Type**: Number<br/>
**Default**: `100`<br/>
The percentage of requests to trace: `100` for all, `0` for none. For more information, see [Connect RUM and Traces][12].
`telemetrySampleRate`
: Optional<br/>
**Type**: Number<br/>
**Default**: `20`<br/>
Telemetry data (such as errors and debug logs) about SDK execution is sent to Datadog in order to detect and solve potential issues. Set this option to `0` to opt out from telemetry collection.
`excludedActivityUrls`
: Optional<br/>
**Type:** List<br/>
A list of request origins ignored when computing the page activity. See [How page activity is calculated][16].
Options that must have matching configuration when you are using the Logs Browser SDK:
`trackSessionAcrossSubdomains`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false`<br/>
Preserve the session across subdomains for the same site.
`useSecureSessionCookie`
: Optional<br/>
**Type**: Boolean<br/>
**Default**: `false`<br/>
Use a secure session cookie. This disables RUM events sent on insecure (non-HTTPS) connections.
`useCrossSiteSessionCookie`
: Optional<br/>
**Type**: Boolean<br/>
**Default**:`false`<br/>
Use a secure cross-site session cookie. This allows the RUM Browser SDK to run when the site is loaded from another one (iframe). Implies `useSecureSessionCookie`.
### Tagging
A service is an independent, deployable code repository that maps to a set of pages.
- If your browser application was constructed as a monolith, your RUM application has one service name for the application.
- If your browser application was constructed as separate repositories for multiple pages, edit the default service names throughout the lifecycle of your application.
### Access internal context
After the Datadog browser RUM SDK is initialized, you can access the internal context of the SDK.
You can explore the following attributes:
| Attribute | Description |
| -------------- | ----------------------------------------------------------------- |
| application_id | ID of the application. |
| session_id | ID of the session. |
| user_action | Object containing action ID (or undefined if no action is found). |
| view | Object containing details about the current view event. |
For more information, see [RUM Browser Data Collected][2].
#### Example
```
{
application_id : "xxx",
session_id : "xxx",
user_action: { id: "xxx" },
view : {
id : "xxx",
referrer : "",
url: "http://localhost:8080/",
name: "homepage"
}
}
```
You can optionally use `startTime` parameter to get the context of a specific time. If the parameter is omitted, the current context is returned.
```
getInternalContext (startTime?: 'number' | undefined)
```
#### NPM
For NPM, use:
```javascript
import { datadogRum } from '@datadog/browser-rum'
datadogRum.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
```
#### CDN async
For CDN async, use:
```javascript
DD_RUM.onReady(function () {
DD_RUM.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
})
```
#### CDN sync
For CDN sync, use:
```javascript
window.DD_RUM && window.DD_RUM.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
```
## Further reading
{{< partial name="whats-next/whats-next.html" >}}
<!-- Note: all URLs should be absolute -->
[1]: https://app.datadoghq.com/rum/list
[2]: https://docs.datadoghq.com/real_user_monitoring/data_collected/
[3]: https://docs.datadoghq.com/real_user_monitoring/dashboards/
[4]: https://www.npmjs.com/package/@datadog/browser-rum
[5]: https://docs.datadoghq.com/account_management/api-app-keys/#client-tokens
[6]: https://docs.datadoghq.com/real_user_monitoring/browser/tracking_user_actions
[7]: https://docs.datadoghq.com/real_user_monitoring/guide/proxy-rum-data/
[8]: https://github.com/DataDog/browser-sdk/blob/main/packages/rum/BROWSER_SUPPORT.md
[9]: https://docs.datadoghq.com/real_user_monitoring/browser/tracking_user_actions/#declare-a-name-for-click-actions
[10]: https://docs.datadoghq.com/real_user_monitoring/browser/modifying_data_and_context/?tab=npm#override-default-rum-view-names
[11]: https://www.datadoghq.com/pricing/?product=real-user-monitoring--session-replay#real-user-monitoring--session-replay
[12]: https://docs.datadoghq.com/real_user_monitoring/connect_rum_and_traces?tab=browserrum
[13]: https://docs.datadoghq.com/real_user_monitoring/session_replay/privacy_options?tab=maskuserinput
[14]: https://docs.datadoghq.com/getting_started/site/
[15]: https://docs.datadoghq.com/getting_started/tagging/#defining-tags
[16]: https://docs.datadoghq.com/real_user_monitoring/browser/monitoring_page_performance/#how-page-activity-is-calculated
[17]: https://docs.datadoghq.com/real_user_monitoring/session_replay/
[18]: https://docs.datadoghq.com/real_user_monitoring/session_replay/privacy_options
[19]: https://docs.datadoghq.com/getting_started/tagging/using_tags
[20]: https://docs.datadoghq.com/real_user_monitoring/frustration_signals/
[21]: https://docs.datadoghq.com/real_user_monitoring/guide/sampling-browser-plans/
[1]: https://docs.datadoghq.com/real_user_monitoring/browser
[2]: https://www.npmjs.com/package/@datadog/browser-rum
import { isIE, noop } from '@datadog/browser-core'
import type { RecorderApi, ViewContexts, LifeCycle, RumConfiguration } from '@datadog/browser-rum-core'
import { LifeCycleEventType } from '@datadog/browser-rum-core'
import { createNewEvent, deleteEventBridgeStub, initEventBridgeStub } from '../../../core/test/specHelper'
import type { RumSessionManagerMock } from '../../../rum-core/test/mockRumSessionManager'
import { createRumSessionManagerMock } from '../../../rum-core/test/mockRumSessionManager'
import type { TestSetupBuilder } from '../../../rum-core/test/testSetupBuilder'
import { setup } from '../../../rum-core/test/testSetupBuilder'
import { deleteEventBridgeStub, initEventBridgeStub, createNewEvent } from '@datadog/browser-core/test'
import type { RumSessionManagerMock, TestSetupBuilder } from '../../../rum-core/test'
import { createRumSessionManagerMock, setup } from '../../../rum-core/test'
import type { DeflateWorker, startDeflateWorker } from '../domain/segmentCollection'

@@ -10,0 +8,0 @@ import type { StartRecording } from './recorderApi'

@@ -6,9 +6,7 @@ import type { TimeStamp, HttpRequest } from '@datadog/browser-core'

import { inflate } from 'pako'
import type { RumSessionManagerMock } from '../../../rum-core/test/mockRumSessionManager'
import { createRumSessionManagerMock } from '../../../rum-core/test/mockRumSessionManager'
import { createNewEvent, mockClock } from '../../../core/test/specHelper'
import { collectAsyncCalls, createNewEvent, mockClock } from '@datadog/browser-core/test'
import type { RumSessionManagerMock, TestSetupBuilder } from '../../../rum-core/test'
import { createRumSessionManagerMock, setup } from '../../../rum-core/test'
import type { TestSetupBuilder } from '../../../rum-core/test/testSetupBuilder'
import { setup } from '../../../rum-core/test/testSetupBuilder'
import { recordsPerFullSnapshot } from '../../test/utils'
import { recordsPerFullSnapshot } from '../../test'
import { setSegmentBytesLimit, startDeflateWorker } from '../domain/segmentCollection'

@@ -19,3 +17,2 @@

import { resetReplayStats } from '../domain/replayStats'
import { collectAsyncCalls } from '../../../core/test/collectAsyncCalls'
import { startRecording } from './startRecording'

@@ -29,9 +26,5 @@

let viewId: string
let waitRequestSendCalls: (
expectedCallsCount: number,
callback: (calls: jasmine.Calls<HttpRequest['sendOnExit']>) => void
) => void
let sandbox: HTMLElement
let textField: HTMLInputElement
let expectNoExtraRequestSendCalls: (done: () => void) => void
let requestSendSpy: jasmine.Spy<HttpRequest['sendOnExit']>
let stopRecording: () => void

@@ -64,4 +57,4 @@

.beforeBuild(({ lifeCycle, configuration, viewContexts, sessionManager }) => {
const requestSendSpy = jasmine.createSpy()
const httpRequest: HttpRequest = {
requestSendSpy = jasmine.createSpy()
const httpRequest = {
send: requestSendSpy,

@@ -71,5 +64,2 @@ sendOnExit: requestSendSpy,

;({ waitAsyncCalls: waitRequestSendCalls, expectNoExtraAsyncCall: expectNoExtraRequestSendCalls } =
collectAsyncCalls(requestSendSpy))
const recording = startRecording(lifeCycle, configuration, sessionManager, viewContexts, worker!, httpRequest)

@@ -93,3 +83,3 @@ stopRecording = recording ? recording.stop : noop

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
expect(calls.first().args[0]).toEqual({ data: jasmine.any(FormData), bytesCount: jasmine.any(Number) })

@@ -110,3 +100,3 @@ expect(getRequestData(calls.first())).toEqual({

})
expectNoExtraRequestSendCalls(done)
done()
})

@@ -126,5 +116,5 @@ })

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
expect(getRequestData(calls.first()).records_count).toBe(String(inputCount + recordsPerFullSnapshot()))
expectNoExtraRequestSendCalls(done)
done()
})

@@ -144,5 +134,5 @@ })

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
expect(getRequestData(calls.first()).records_count).toBe(String(1 + recordsPerFullSnapshot()))
expectNoExtraRequestSendCalls(done)
done()
})

@@ -163,7 +153,7 @@ })

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
const data = getRequestData(calls.first())
expect(data.records_count).toBe('1')
expect(data['session.id']).toBe('new-session-id')
expectNoExtraRequestSendCalls(done)
done()
})

@@ -178,5 +168,5 @@ })

waitRequestSendCalls(2, (calls) => {
collectAsyncCalls(requestSendSpy, 2, (calls) => {
expect(getRequestData(calls.mostRecent()).has_full_snapshot).toBe('true')
expectNoExtraRequestSendCalls(done)
done()
})

@@ -192,3 +182,3 @@ })

waitRequestSendCalls(2, (calls) => {
collectAsyncCalls(requestSendSpy, 2, (calls) => {
readRequestSegment(calls.first(), (segment) => {

@@ -207,3 +197,3 @@ expect(segment.records[0].timestamp).toEqual(timeStampNow())

expectNoExtraRequestSendCalls(done)
done()
})

@@ -220,7 +210,7 @@ })

waitRequestSendCalls(2, (calls) => {
collectAsyncCalls(requestSendSpy, 2, (calls) => {
expect(getRequestData(calls.first())['view.id']).toBe('view-id')
readRequestSegment(calls.first(), (segment) => {
expect(segment.records[segment.records.length - 1].type).toBe(RecordType.ViewEnd)
expectNoExtraRequestSendCalls(done)
done()
})

@@ -237,3 +227,3 @@ })

waitRequestSendCalls(2, (calls) => {
collectAsyncCalls(requestSendSpy, 2, (calls) => {
readRequestSegment(calls.first(), (segment) => {

@@ -245,3 +235,3 @@ expect(segment.records[segment.records.length - 2].type).toBe(RecordType.IncrementalSnapshot)

expect(segment.records[0].type).toBe(RecordType.Meta)
expectNoExtraRequestSendCalls(done)
done()
})

@@ -256,3 +246,3 @@ })

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
readRequestSegment(calls.first(), (segment) => {

@@ -262,3 +252,3 @@ expect(segment.records[0].type).toBe(RecordType.Meta)

expect(segment.records[2].type).toBe(RecordType.FullSnapshot)
expectNoExtraRequestSendCalls(done)
done()
})

@@ -277,5 +267,5 @@ })

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
expect(getRequestData(calls.first()).records_count).toBe(String(1 + recordsPerFullSnapshot()))
expectNoExtraRequestSendCalls(done)
done()
})

@@ -291,5 +281,5 @@ })

waitRequestSendCalls(1, (calls) => {
collectAsyncCalls(requestSendSpy, 1, (calls) => {
expect(getRequestData(calls.first()).records_count).toBe(String(recordsPerFullSnapshot()))
expectNoExtraRequestSendCalls(done)
done()
})

@@ -296,0 +286,0 @@ })

@@ -1,2 +0,2 @@

import { collectAsyncCalls } from '../../../../core/test/collectAsyncCalls'
import { collectAsyncCalls } from '@datadog/browser-core/test'
import { createMutationBatch } from './mutationBatch'

@@ -22,10 +22,5 @@ import type { RumMutationRecord } from './observers'

const {
waitAsyncCalls: waitProcessMutationBatchCalls,
expectNoExtraAsyncCall: expectNoExtraProcessMutationBatchCall,
} = collectAsyncCalls(processMutationBatchSpy)
waitProcessMutationBatchCalls(1, (calls) => {
collectAsyncCalls(processMutationBatchSpy, 1, (calls) => {
expect(calls.mostRecent().args[0]).toEqual([mutation])
expectNoExtraProcessMutationBatchCall(done)
done()
})

@@ -32,0 +27,0 @@ })

@@ -0,4 +1,4 @@

import type { ListenerHandler } from '@datadog/browser-core'
import { DOM_EVENT, addEventListeners } from '@datadog/browser-core'
import type { FocusRecord } from '../../../types'
import type { ListenerHandler } from './utils'

@@ -5,0 +5,0 @@ export type FocusCallback = (data: FocusRecord['data']) => void

@@ -8,3 +8,4 @@ import { isIE, relativeNow, timeStampNow } from '@datadog/browser-core'

import { initFrustrationObserver } from './frustrationObserver'
import { getRecordIdForEvent } from './utils'
import type { RecordIds } from './recordIds'
import { initRecordIds } from './recordIds'

@@ -17,2 +18,3 @@ describe('initFrustrationObserver', () => {

let rumData: RawRumEventCollectedData<RawRumActionEvent>
let recordIds: RecordIds

@@ -25,2 +27,3 @@ beforeEach(() => {

frustrationsCallbackSpy = jasmine.createSpy()
recordIds = initRecordIds()

@@ -52,3 +55,3 @@ rumData = {

it('calls callback if the raw data inserted is a click action', () => {
stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy)
stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy, recordIds)
lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, rumData)

@@ -60,3 +63,3 @@

expect(frustrationRecord.data.frustrationTypes).toEqual(rumData.rawRumEvent.action.frustration!.type)
expect(frustrationRecord.data.recordIds).toEqual([getRecordIdForEvent(mouseEvent)])
expect(frustrationRecord.data.recordIds).toEqual([recordIds.getIdForEvent(mouseEvent)])
})

@@ -66,3 +69,3 @@

rumData.rawRumEvent.action.type = ActionType.CUSTOM
stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy)
stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy, recordIds)
lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, rumData)

@@ -76,3 +79,3 @@

stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy)
stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy, recordIds)
lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, rumData)

@@ -86,3 +89,3 @@

stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy)
stopFrustrationObserver = initFrustrationObserver(lifeCycle, frustrationsCallbackSpy, recordIds)
lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, rumData)

@@ -89,0 +92,0 @@

@@ -0,1 +1,2 @@

import type { ListenerHandler } from '@datadog/browser-core'
import type { LifeCycle } from '@datadog/browser-rum-core'

@@ -5,8 +6,11 @@ import { ActionType, RumEventType, LifeCycleEventType } from '@datadog/browser-rum-core'

import { RecordType } from '../../../types'
import type { ListenerHandler } from './utils'
import { getRecordIdForEvent } from './utils'
import type { RecordIds } from './recordIds'
export type FrustrationCallback = (record: FrustrationRecord) => void
export function initFrustrationObserver(lifeCycle: LifeCycle, frustrationCb: FrustrationCallback): ListenerHandler {
export function initFrustrationObserver(
lifeCycle: LifeCycle,
frustrationCb: FrustrationCallback,
recordIds: RecordIds
): ListenerHandler {
return lifeCycle.subscribe(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, (data) => {

@@ -25,3 +29,3 @@ if (

frustrationTypes: data.rawRumEvent.action.frustration.type,
recordIds: data.domainContext.events.map((e) => getRecordIdForEvent(e)),
recordIds: data.domainContext.events.map((e) => recordIds.getIdForEvent(e)),
},

@@ -28,0 +32,0 @@ })

export { initObservers } from './observers'
export { InputCallback, initInputObserver } from './inputObserver'
export { initMutationObserver, MutationCallBack, RumMutationRecord } from './mutationObserver'
export { DEFAULT_CONFIGURATION } from './observers.specHelper'
export { DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper'
import { DefaultPrivacyLevel, isIE } from '@datadog/browser-core'
import { createNewEvent } from '@datadog/browser-core/test/specHelper'
import { createNewEvent } from '@datadog/browser-core/test'
import { PRIVACY_ATTR_NAME, PRIVACY_ATTR_VALUE_MASK_USER_INPUT } from '../../../constants'
import { serializeDocument, SerializationContextStatus } from '../serialization'
import { createElementsScrollPositions } from '../elementsScrollPositions'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from '../../../../test/utils'
import type { InputCallback } from './inputObserver'
import { initInputObserver } from './inputObserver'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper'

@@ -10,0 +10,0 @@ describe('initInputObserver', () => {

@@ -1,9 +0,8 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core'
import { instrumentSetter, assign, DOM_EVENT, addEventListeners } from '@datadog/browser-core'
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core'
import { instrumentSetter, assign, DOM_EVENT, addEventListeners, forEach } from '@datadog/browser-core'
import { NodePrivacyLevel } from '../../../constants'
import type { InputState } from '../../../types'
import { getEventTarget } from '../eventsUtils'
import { getNodePrivacyLevel, shouldMaskNode } from '../privacy'
import { getElementInputValue, getSerializedNodeId, hasSerializedNode } from '../serialization'
import type { ListenerHandler } from './utils'
import { getEventTarget, forEach } from './utils'

@@ -10,0 +9,0 @@ type InputObserverOptions = {

@@ -1,2 +0,2 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core'
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core'
import { DOM_EVENT, addEventListeners } from '@datadog/browser-core'

@@ -6,6 +6,5 @@ import { NodePrivacyLevel } from '../../../constants'

import { MediaInteractionType } from '../../../types'
import { getEventTarget } from '../eventsUtils'
import { getNodePrivacyLevel } from '../privacy'
import { getSerializedNodeId, hasSerializedNode } from '../serialization'
import type { ListenerHandler } from './utils'
import { getEventTarget } from './utils'

@@ -12,0 +11,0 @@ export type MediaInteractionCallback = (p: MediaInteraction) => void

import { DefaultPrivacyLevel, isIE } from '@datadog/browser-core'
import { createNewEvent } from '@datadog/browser-core/test/specHelper'
import { createNewEvent } from '@datadog/browser-core/test'
import { IncrementalSource, MouseInteractionType, RecordType } from '../../../types'
import { serializeDocument, SerializationContextStatus } from '../serialization'
import { createElementsScrollPositions } from '../elementsScrollPositions'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from '../../../../test/utils'
import type { MouseInteractionCallBack } from './mouseInteractionObserver'
import { initMouseInteractionObserver } from './mouseInteractionObserver'
import { getRecordIdForEvent } from './utils'
import type { RecordIds } from './recordIds'
import { initRecordIds } from './recordIds'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper'

@@ -14,2 +15,3 @@ describe('initMouseInteractionObserver', () => {

let stopObserver: () => void
let recordIds: RecordIds
let sandbox: HTMLDivElement

@@ -37,3 +39,4 @@ let a: HTMLAnchorElement

mouseInteractionCallbackSpy = jasmine.createSpy()
stopObserver = initMouseInteractionObserver(mouseInteractionCallbackSpy, DefaultPrivacyLevel.ALLOW)
recordIds = initRecordIds()
stopObserver = initMouseInteractionObserver(mouseInteractionCallbackSpy, DefaultPrivacyLevel.ALLOW, recordIds)
})

@@ -68,3 +71,3 @@

expect(mouseInteractionCallbackSpy).toHaveBeenCalledWith({
id: getRecordIdForEvent(pointerupEvent),
id: recordIds.getIdForEvent(pointerupEvent),
type: RecordType.IncrementalSnapshot,

@@ -71,0 +74,0 @@ timestamp: jasmine.any(Number),

@@ -1,2 +0,2 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core'
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core'
import { assign, addEventListeners, DOM_EVENT } from '@datadog/browser-core'

@@ -6,8 +6,8 @@ import { NodePrivacyLevel } from '../../../constants'

import { IncrementalSource, MouseInteractionType } from '../../../types'
import { assembleIncrementalSnapshot } from '../assembly'
import { getEventTarget } from '../eventsUtils'
import { getNodePrivacyLevel } from '../privacy'
import { getSerializedNodeId, hasSerializedNode } from '../serialization'
import { assembleIncrementalSnapshot } from '../utils'
import { tryToComputeCoordinates } from './moveObserver'
import type { ListenerHandler } from './utils'
import { getRecordIdForEvent, getEventTarget } from './utils'
import type { RecordIds } from './recordIds'

@@ -39,3 +39,4 @@ const eventTypeToMouseInteraction = {

cb: MouseInteractionCallBack,
defaultPrivacyLevel: DefaultPrivacyLevel
defaultPrivacyLevel: DefaultPrivacyLevel,
recordIds: RecordIds
): ListenerHandler {

@@ -62,3 +63,3 @@ const handler = (event: MouseEvent | TouchEvent) => {

const record = assign(
{ id: getRecordIdForEvent(event) },
{ id: recordIds.getIdForEvent(event) },
assembleIncrementalSnapshot<MouseInteractionData>(IncrementalSource.MouseInteraction, interaction)

@@ -65,0 +66,0 @@ )

import { isIE } from '@datadog/browser-core'
import { createNewEvent } from '@datadog/browser-core/test/specHelper'
import { createNewEvent } from '@datadog/browser-core/test'
import { SerializationContextStatus, serializeDocument } from '../serialization'
import { createElementsScrollPositions } from '../elementsScrollPositions'
import { IncrementalSource } from '../../../types'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from '../../../../test/utils'
import type { MousemoveCallBack } from './moveObserver'
import { initMoveObserver } from './moveObserver'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper'

@@ -10,0 +10,0 @@ describe('initMoveObserver', () => {

@@ -0,9 +1,8 @@

import type { ListenerHandler } from '@datadog/browser-core'
import { addEventListeners, addTelemetryDebug, DOM_EVENT, throttle } from '@datadog/browser-core'
import { getSerializedNodeId, hasSerializedNode } from '../serialization'
import { isTouchEvent } from '../utils'
import type { MousePosition } from '../../../types'
import { IncrementalSource } from '../../../types'
import { getEventTarget, isTouchEvent } from '../eventsUtils'
import { convertMouseEventToLayoutCoordinates } from '../viewports'
import type { ListenerHandler } from './utils'
import { getEventTarget } from './utils'

@@ -10,0 +9,0 @@ const MOUSE_MOVE_OBSERVER_THRESHOLD = 50

import { DefaultPrivacyLevel, isIE } from '@datadog/browser-core'
import type { RumConfiguration } from '@datadog/browser-rum-core'
import { collectAsyncCalls } from '@datadog/browser-core/test/collectAsyncCalls'
import { createMutationPayloadValidator, DEFAULT_SHADOW_ROOT_CONTROLLER } from '../../../../test/utils'
import { collectAsyncCalls } from '@datadog/browser-core/test'
import { createMutationPayloadValidator } from '../../../../test'
import {

@@ -19,2 +19,3 @@ NodePrivacyLevel,

import type { MutationCallBack } from './mutationObserver'
import { DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper'

@@ -105,4 +106,2 @@ describe('startMutationCollection', () => {

const { mutationCallbackSpy } = startMutationCollection()
const { waitAsyncCalls: waitMutationCallbackCalls, expectNoExtraAsyncCall: expectNoExtraMutationCallbackCalls } =
collectAsyncCalls(mutationCallbackSpy)

@@ -113,5 +112,3 @@ sandbox.appendChild(document.createElement('div'))

waitMutationCallbackCalls(1, () => {
expectNoExtraMutationCallbackCalls(done)
})
collectAsyncCalls(mutationCallbackSpy, 1, () => done())
})

@@ -118,0 +115,0 @@

@@ -0,1 +1,2 @@

import type { ListenerHandler } from '@datadog/browser-core'
import type { LifeCycle, RumConfiguration } from '@datadog/browser-rum-core'

@@ -24,3 +25,3 @@ import type { ElementsScrollPositions } from '../elementsScrollPositions'

import { initFocusObserver } from './focusObserver'
import type { ListenerHandler } from './utils'
import { initRecordIds } from './recordIds'

@@ -46,2 +47,3 @@ interface ObserverParam {

export function initObservers(o: ObserverParam): { stop: ListenerHandler; flush: ListenerHandler } {
const recordIds = initRecordIds()
const mutationHandler = initMutationObserver(o.mutationCb, o.configuration, o.shadowRootsController, document)

@@ -51,3 +53,4 @@ const mousemoveHandler = initMoveObserver(o.mousemoveCb)

o.mouseInteractionCb,
o.configuration.defaultPrivacyLevel
o.configuration.defaultPrivacyLevel,
recordIds
)

@@ -64,3 +67,3 @@ const scrollHandler = initScrollObserver(o.scrollCb, o.configuration.defaultPrivacyLevel, o.elementsScrollPositions)

const visualViewportResizeHandler = initVisualViewportResizeObserver(o.visualViewportResizeCb)
const frustrationHandler = initFrustrationObserver(o.lifeCycle, o.frustrationCb)
const frustrationHandler = initFrustrationObserver(o.lifeCycle, o.frustrationCb, recordIds)

@@ -67,0 +70,0 @@ return {

@@ -1,12 +0,10 @@

import type { DefaultPrivacyLevel } from '@datadog/browser-core'
import type { DefaultPrivacyLevel, ListenerHandler } from '@datadog/browser-core'
import { DOM_EVENT, throttle, addEventListener } from '@datadog/browser-core'
import type { ElementsScrollPositions } from '../elementsScrollPositions'
import { getEventTarget } from '../eventsUtils'
import { getNodePrivacyLevel } from '../privacy'
import { getSerializedNodeId, hasSerializedNode } from '../serialization'
import { getScrollX, getScrollY } from '../viewports'
import type { ScrollPosition } from '../../../types'
import { NodePrivacyLevel } from '../../../constants'
import type { ListenerHandler } from './utils'
import { getEventTarget } from './utils'

@@ -13,0 +11,0 @@ const SCROLL_OBSERVER_THRESHOLD = 100

import { isIE } from '@datadog/browser-core'
import { isFirefox } from '@datadog/browser-core/test/specHelper'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from '../../../../test/utils'
import { isFirefox } from '@datadog/browser-core/test'
import { serializeDocument, SerializationContextStatus } from '../serialization'
import { createElementsScrollPositions } from '../elementsScrollPositions'
import type { StyleSheetCallback } from './styleSheetObserver'
import { initStyleSheetObserver } from './styleSheetObserver'
import { initStyleSheetObserver, getPathToNestedCSSRule } from './styleSheetObserver'
import { DEFAULT_CONFIGURATION, DEFAULT_SHADOW_ROOT_CONTROLLER } from './observers.specHelper'

@@ -151,1 +151,70 @@ describe('initStyleSheetObserver', () => {

})
const firstStyleRule = '.selector-1 { color: #aaa }'
const secondStyleRule = '.selector-2 { color: #bbb }'
const firstMediaRule = `
@media cond-1 {
.selector-3-1 { color: #ccc }
.selector-3-2 { color: #ddd }
.selector-3-3 { color: #eee }
}`
const secondMediaRule = `
@media cond-2 {
@media cond-2-1 {.selector-2-1-1 { display: none }}
@media cond-2-2 {.selector-2-2-1 { display: clock }}
}`
describe('StyleSheetObserver > getPathToNestedCSSRule', () => {
let styleSheet: CSSStyleSheet
let styleElement: HTMLStyleElement
beforeEach(() => {
if (isIE()) {
pending('IE not supported')
}
styleElement = document.createElement('style')
document.head.appendChild(styleElement)
styleSheet = styleElement.sheet!
styleSheet.insertRule(secondMediaRule)
styleSheet.insertRule(firstMediaRule)
styleSheet.insertRule(secondStyleRule)
styleSheet.insertRule(firstStyleRule)
})
afterEach(() => {
styleElement.remove()
})
it('should return undefined if the rule is not attached to a parent StyleSheet', () => {
const groupingRule = styleSheet.cssRules[3]
expect(groupingRule.parentStyleSheet).toBeDefined()
// Removing rule from CSSStyleSheet
styleSheet.deleteRule(3)
expect(groupingRule.parentStyleSheet).toEqual(null)
expect(getPathToNestedCSSRule(groupingRule)).toBeUndefined()
})
it('should return path to high level CSSStyleRule', () => {
expect(getPathToNestedCSSRule(styleSheet.cssRules[1])).toEqual([1])
})
it('should return path to high level CSSGroupingRule', () => {
expect(getPathToNestedCSSRule(styleSheet.cssRules[3])).toEqual([3])
})
it('should return path to nested CSSStyleRule', () => {
const rule = (styleSheet.cssRules[2] as CSSGroupingRule).cssRules[1]
expect(getPathToNestedCSSRule(rule)).toEqual([2, 1])
})
it('should return path to nested CSSGroupingRule', () => {
const rule = (styleSheet.cssRules[3] as CSSGroupingRule).cssRules[0]
expect(getPathToNestedCSSRule(rule)).toEqual([3, 0])
})
it('should return path to leaf CSSRule', () => {
const rule = ((styleSheet.cssRules[3] as CSSGroupingRule).cssRules[1] as CSSGroupingRule).cssRules[0]
expect(getPathToNestedCSSRule(rule)).toEqual([3, 1, 0])
})
})

@@ -0,6 +1,5 @@

import type { ListenerHandler } from '@datadog/browser-core'
import { instrumentMethodAndCallOriginal } from '@datadog/browser-core'
import type { StyleSheetRule } from '../../../types'
import { getSerializedNodeId, hasSerializedNode } from '../serialization'
import { getPathToNestedCSSRule } from '../utils'
import type { ListenerHandler } from './utils'

@@ -67,1 +66,22 @@ type GroupingCSSRuleTypes = typeof CSSGroupingRule | typeof CSSMediaRule | typeof CSSSupportsRule

}
export function getPathToNestedCSSRule(rule: CSSRule): number[] | undefined {
const path: number[] = []
let currentRule = rule
while (currentRule.parentRule) {
const rules = Array.from((currentRule.parentRule as CSSGroupingRule).cssRules)
const index = rules.indexOf(currentRule)
path.unshift(index)
currentRule = currentRule.parentRule
}
// A rule may not be attached to a stylesheet
if (!currentRule.parentStyleSheet) {
return
}
const rules = Array.from(currentRule.parentStyleSheet.cssRules)
const index = rules.indexOf(currentRule)
path.unshift(index)
return path
}

@@ -0,1 +1,2 @@

import type { ListenerHandler } from '@datadog/browser-core'
import { throttle, DOM_EVENT, addEventListeners, noop } from '@datadog/browser-core'

@@ -5,3 +6,2 @@ import { initViewportObservable } from '@datadog/browser-rum-core'

import { getVisualViewport } from '../viewports'
import type { ListenerHandler } from './utils'

@@ -8,0 +8,0 @@ const VISUAL_VIEWPORT_OBSERVER_THRESHOLD = 200

import { DefaultPrivacyLevel, findLast, isIE } from '@datadog/browser-core'
import type { RumConfiguration } from '@datadog/browser-rum-core'
import { LifeCycle } from '@datadog/browser-rum-core'
import { collectAsyncCalls } from '../../../../core/test/collectAsyncCalls'
import type { Clock } from '../../../../core/test/specHelper'
import { createNewEvent } from '../../../../core/test/specHelper'
import { findFullSnapshot, findNode, recordsPerFullSnapshot } from '../../../test/utils'
import type { Clock } from '@datadog/browser-core/test'
import { createNewEvent, collectAsyncCalls } from '@datadog/browser-core/test'
import { findFullSnapshot, findNode, recordsPerFullSnapshot } from '../../../test'
import type {

@@ -24,4 +23,2 @@ BrowserIncrementalSnapshotRecord,

let emitSpy: jasmine.Spy<(record: BrowserRecord) => void>
let waitEmitCalls: (expectedCallsCount: number, callback: () => void) => void
let expectNoExtraEmitCalls: (done: () => void) => void
let clock: Clock | undefined

@@ -35,3 +32,2 @@

emitSpy = jasmine.createSpy()
;({ waitAsyncCalls: waitEmitCalls, expectNoExtraAsyncCall: expectNoExtraEmitCalls } = collectAsyncCalls(emitSpy))
sandbox = createDOMSandbox()

@@ -66,3 +62,3 @@ })

waitEmitCalls(recordsPerFullSnapshot() + 6, () => {
collectAsyncCalls(emitSpy, recordsPerFullSnapshot() + 6, () => {
const records = getEmittedRecords()

@@ -122,3 +118,3 @@ let i = 0

expectNoExtraEmitCalls(done)
done()
})

@@ -134,3 +130,3 @@ })

waitEmitCalls(1 + 2 * recordsPerFullSnapshot(), () => {
collectAsyncCalls(emitSpy, 1 + 2 * recordsPerFullSnapshot(), () => {
const records = getEmittedRecords()

@@ -152,3 +148,3 @@ let i = 0

expectNoExtraEmitCalls(done)
done()
})

@@ -155,0 +151,0 @@ })

@@ -17,6 +17,6 @@ import type { TimeStamp } from '@datadog/browser-core'

import { RecordType, IncrementalSource } from '../../types'
import { assembleIncrementalSnapshot } from './assembly'
import { SerializationContextStatus, serializeDocument } from './serialization'
import { initObservers } from './observers'
import { getVisualViewport, getScrollX, getScrollY } from './viewports'
import { assembleIncrementalSnapshot } from './utils'
import { createElementsScrollPositions } from './elementsScrollPositions'

@@ -23,0 +23,0 @@ import type { ShadowRootsController } from './shadowRootsController'

import { isIE, noop } from '@datadog/browser-core'
import type { RumConfiguration } from '@datadog/browser-rum-core'
import { isAdoptedStyleSheetsSupported } from '@datadog/browser-core/test'
import {

@@ -14,8 +15,7 @@ NodePrivacyLevel,

import { NodeType } from '../../../types'
import type { IsolatedDom } from '../../../../../rum-core/test/createIsolatedDom'
import { createIsolatedDom } from '../../../../../rum-core/test/createIsolatedDom'
import type { IsolatedDom } from '../../../../../rum-core/test'
import { createIsolatedDom } from '../../../../../rum-core/test'
import type { ElementsScrollPositions } from '../elementsScrollPositions'
import { createElementsScrollPositions } from '../elementsScrollPositions'
import type { ShadowRootCallBack, ShadowRootsController } from '../shadowRootsController'
import { isAdoptedStyleSheetsSupported } from '../../../../../core/test/specHelper'
import {

@@ -22,0 +22,0 @@ HTML,

@@ -1,2 +0,2 @@

import { isAdoptedStyleSheetsSupported } from '@datadog/browser-core/test/specHelper'
import { isAdoptedStyleSheetsSupported } from '@datadog/browser-core/test'
import { serializeStyleSheets } from './serializeStyleSheets'

@@ -3,0 +3,0 @@

@@ -1,2 +0,2 @@

import { addTelemetryDebug, DOM_EVENT, isExperimentalFeatureEnabled } from '@datadog/browser-core'
import { addTelemetryDebug, DOM_EVENT, ExperimentalFeature, isExperimentalFeatureEnabled } from '@datadog/browser-core'
import type { RumConfiguration } from '@datadog/browser-rum-core'

@@ -61,3 +61,3 @@ import type { InputCallback, MutationCallBack } from './observers'

html:
shadowRoot && isExperimentalFeatureEnabled('shadow_dom_debug')
shadowRoot && isExperimentalFeatureEnabled(ExperimentalFeature.SHADOW_DOM_DEBUG)
? shadowRoot.innerHTML.substring(0, 2000)

@@ -64,0 +64,0 @@ : undefined,

import type { TimeStamp } from '@datadog/browser-core'
import { noop, setDebugMode, display, isIE } from '@datadog/browser-core'
import { MockWorker, parseSegment } from '../../../test/utils'
import type { CreationReason, BrowserRecord, SegmentContext } from '../../types'
import { MockWorker } from '../../../test'
import type { CreationReason, BrowserRecord, SegmentContext, BrowserSegment } from '../../types'
import { RecordType } from '../../types'

@@ -243,1 +243,5 @@ import { getReplayStats, resetReplayStats } from '../replayStats'

})
function parseSegment(bytes: Uint8Array) {
return JSON.parse(new TextDecoder().decode(bytes)) as BrowserSegment
}

@@ -5,8 +5,8 @@ import type { HttpRequest, TimeStamp } from '@datadog/browser-core'

import { LifeCycle, LifeCycleEventType } from '@datadog/browser-rum-core'
import type { Clock } from '@datadog/browser-core/test/specHelper'
import { mockClock, restorePageVisibility } from '@datadog/browser-core/test/specHelper'
import { createRumSessionManagerMock } from '../../../../rum-core/test/mockRumSessionManager'
import type { Clock } from '@datadog/browser-core/test'
import { mockClock, restorePageVisibility } from '@datadog/browser-core/test'
import { createRumSessionManagerMock } from '../../../../rum-core/test'
import type { BrowserRecord, SegmentContext } from '../../types'
import { RecordType } from '../../types'
import { MockWorker } from '../../../test/utils'
import { MockWorker } from '../../../test'
import {

@@ -13,0 +13,0 @@ computeSegmentContext,

import type { RawTelemetryEvent } from '@datadog/browser-core'
import { display, isIE, noop, resetTelemetry, startFakeTelemetry } from '@datadog/browser-core'
import { MockWorker } from '../../../test/utils'
import { MockWorker } from '../../../test'
import type { createDeflateWorker } from './deflateWorker'

@@ -5,0 +5,0 @@ import { startDeflateWorker, resetDeflateWorkerState } from './startDeflateWorker'

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc