Socket
Socket
Sign inDemoInstall

@datadog/browser-rum-core

Package Overview
Dependencies
Maintainers
1
Versions
177
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@datadog/browser-rum-core - npm Package Compare versions

Comparing version 4.42.2 to 4.43.0

24

cjs/boot/rumPublicApi.js

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

}
if ((0, browser_core_1.canUseEventBridge)()) {
var eventBridgeAvailable = (0, browser_core_1.canUseEventBridge)();
if (eventBridgeAvailable) {
initConfiguration = overrideInitConfigurationForBridge(initConfiguration);
}
else if (!canHandleSession(initConfiguration)) {
return;
}
if (!canInitRum(initConfiguration)) {

@@ -60,2 +58,6 @@ return;

}
if (!eventBridgeAvailable && !configuration.sessionStoreStrategyType) {
browser_core_1.display.warn('No storage available for session. We will not send any data.');
return;
}
if (!configuration.trackViewsManually) {

@@ -159,13 +161,2 @@ doStartRum(initConfiguration, configuration);

return rumPublicApi;
function canHandleSession(initConfiguration) {
if (!(0, browser_core_1.areCookiesAuthorized)((0, browser_core_1.buildCookieOptions)(initConfiguration))) {
browser_core_1.display.warn('Cookies are not authorized, we will not send any data.');
return false;
}
if (isLocalFile()) {
browser_core_1.display.error('Execution is not allowed in the current context.');
return false;
}
return true;
}
function canInitRum(initConfiguration) {

@@ -187,7 +178,4 @@ if (isAlreadyInitialized) {

}
function isLocalFile() {
return window.location.protocol === 'file:';
}
}
exports.makeRumPublicApi = makeRumPublicApi;
//# sourceMappingURL=rumPublicApi.js.map

@@ -24,2 +24,3 @@ import type { Observable, RawError, ContextManager } from '@datadog/browser-core';

foregroundContexts: import("../domain/contexts/foregroundContexts").ForegroundContexts;
pageStateHistory: import("../domain/contexts/pageStateHistory").PageStateHistory;
urlContexts: {

@@ -26,0 +27,0 @@ findUrl: (startTime?: import("@datadog/browser-core").RelativeTime | undefined) => import("../domain/contexts/urlContexts").UrlContext | undefined;

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

var locationChangeObservable = (0, locationChangeObservable_1.createLocationChangeObservable)(location);
var _a = startRumEventCollection(lifeCycle, configuration, location, session, locationChangeObservable, domMutationObservable, function () { return (0, commonContext_1.buildCommonContext)(globalContextManager, userContextManager, recorderApi); }, reportError), viewContexts = _a.viewContexts, foregroundContexts = _a.foregroundContexts, urlContexts = _a.urlContexts, actionContexts = _a.actionContexts, addAction = _a.addAction;
var _a = startRumEventCollection(lifeCycle, configuration, location, session, locationChangeObservable, domMutationObservable, function () { return (0, commonContext_1.buildCommonContext)(globalContextManager, userContextManager, recorderApi); }, reportError), viewContexts = _a.viewContexts, foregroundContexts = _a.foregroundContexts, pageStateHistory = _a.pageStateHistory, urlContexts = _a.urlContexts, actionContexts = _a.actionContexts, addAction = _a.addAction;
(0, browser_core_1.addTelemetryConfiguration)((0, configuration_1.serializeRumConfiguration)(initConfiguration));
(0, longTaskCollection_1.startLongTaskCollection)(lifeCycle, session);
var pageStateHistory = (0, pageStateHistory_1.startPageStateHistory)();
(0, resourceCollection_1.startResourceCollection)(lifeCycle, configuration, session, pageStateHistory);
var _b = (0, viewCollection_1.startViewCollection)(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, recorderApi, initialViewOptions), addTiming = _b.addTiming, startView = _b.startView;
var _b = (0, viewCollection_1.startViewCollection)(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, pageStateHistory, recorderApi, initialViewOptions), addTiming = _b.addTiming, startView = _b.startView;
var addError = (0, errorCollection_1.startErrorCollection)(lifeCycle, foregroundContexts, featureFlagContexts).addError;

@@ -104,2 +103,3 @@ (0, requestCollection_1.startRequestCollection)(lifeCycle, configuration, session);

var foregroundContexts = (0, foregroundContexts_1.startForegroundContexts)();
var pageStateHistory = (0, pageStateHistory_1.startPageStateHistory)();
var _a = (0, actionCollection_1.startActionCollection)(lifeCycle, domMutationObservable, configuration, foregroundContexts), addAction = _a.addAction, actionContexts = _a.actionContexts;

@@ -110,2 +110,3 @@ (0, assembly_1.startRumAssembly)(configuration, lifeCycle, sessionManager, viewContexts, urlContexts, actionContexts, buildCommonContext, reportError);

foregroundContexts: foregroundContexts,
pageStateHistory: pageStateHistory,
urlContexts: urlContexts,

@@ -112,0 +113,0 @@ addAction: addAction,

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

},
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "4.42.2" : undefined,
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "4.43.0" : undefined,
},

@@ -59,0 +59,0 @@ application: {

import type { Duration, RelativeTime } from '@datadog/browser-core';
export declare const MAX_PAGE_STATE_ENTRIES = 500;
import type { PageStateServerEntry } from '../../rawRumEvent.types';
export declare const MAX_PAGE_STATE_ENTRIES = 4000;
export declare const MAX_PAGE_STATE_ENTRIES_SELECTABLE = 500;
export declare const PAGE_STATE_CONTEXT_TIME_OUT_DELAY: number;
export declare const enum PageState {

@@ -15,7 +18,6 @@ ACTIVE = "active",

export interface PageStateHistory {
findAll: (startTime: RelativeTime, duration: Duration) => PageStateEntry[] | undefined;
findAll: (startTime: RelativeTime, duration: Duration) => PageStateServerEntry[] | undefined;
addPageState(nextPageState: PageState, startTime?: RelativeTime): void;
stop: () => void;
}
export declare function startPageStateHistory(): PageStateHistory;
export declare function addPageState(nextPageState: PageState, maxPageStateEntries?: number): void;
export declare function resetPageStates(): void;
export declare function startPageStateHistory(maxPageStateEntriesSelectable?: number): PageStateHistory;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resetPageStates = exports.addPageState = exports.startPageStateHistory = exports.MAX_PAGE_STATE_ENTRIES = void 0;
exports.startPageStateHistory = exports.PAGE_STATE_CONTEXT_TIME_OUT_DELAY = exports.MAX_PAGE_STATE_ENTRIES_SELECTABLE = exports.MAX_PAGE_STATE_ENTRIES = void 0;
var browser_core_1 = require("@datadog/browser-core");
exports.MAX_PAGE_STATE_ENTRIES = 500;
var pageStateEntries = [];
var currentPageState;
function startPageStateHistory() {
addPageState(getPageState());
var stop = (0, browser_core_1.addEventListeners)(window, [
// Arbitrary value to cap number of element for memory consumption in the browser
exports.MAX_PAGE_STATE_ENTRIES = 4000;
// Arbitrary value to cap number of element for backend & to save bandwidth
exports.MAX_PAGE_STATE_ENTRIES_SELECTABLE = 500;
exports.PAGE_STATE_CONTEXT_TIME_OUT_DELAY = browser_core_1.SESSION_TIME_OUT_DELAY;
function startPageStateHistory(maxPageStateEntriesSelectable) {
if (maxPageStateEntriesSelectable === void 0) { maxPageStateEntriesSelectable = exports.MAX_PAGE_STATE_ENTRIES_SELECTABLE; }
var pageStateHistory = new browser_core_1.ValueHistory(exports.PAGE_STATE_CONTEXT_TIME_OUT_DELAY, exports.MAX_PAGE_STATE_ENTRIES);
var currentPageState;
addPageState(getPageState(), (0, browser_core_1.relativeNow)());
var stopEventListeners = (0, browser_core_1.addEventListeners)(window, [
"pageshow" /* DOM_EVENT.PAGE_SHOW */,

@@ -21,35 +26,53 @@ "focus" /* DOM_EVENT.FOCUS */,

// cf: developer extension auto flush: https://github.com/DataDog/browser-sdk/blob/2f72bf05a672794c9e33965351964382a94c72ba/developer-extension/src/panel/flushEvents.ts#L11-L12
if (!event.isTrusted) {
if (event.isTrusted) {
addPageState(computePageState(event), event.timeStamp);
}
}, { capture: true }).stop;
function addPageState(nextPageState, startTime) {
if (startTime === void 0) { startTime = (0, browser_core_1.relativeNow)(); }
if (nextPageState === currentPageState) {
return;
}
if (event.type === "freeze" /* DOM_EVENT.FREEZE */) {
addPageState("frozen" /* PageState.FROZEN */);
}
else if (event.type === "pagehide" /* DOM_EVENT.PAGE_HIDE */) {
addPageState(event.persisted ? "frozen" /* PageState.FROZEN */ : "terminated" /* PageState.TERMINATED */);
}
else {
addPageState(getPageState());
}
}, { capture: true }).stop;
currentPageState = nextPageState;
pageStateHistory.closeActive(startTime);
pageStateHistory.add({ state: currentPageState, startTime: startTime }, startTime);
}
return {
findAll: function (startTime, duration) {
var entries = [];
var endTime = (0, browser_core_1.addDuration)(startTime, duration);
for (var i = pageStateEntries.length - 1; i >= 0; i--) {
var stateStartTime = pageStateEntries[i].startTime;
if (stateStartTime >= endTime) {
continue;
}
entries.unshift(pageStateEntries[i]);
if (stateStartTime < startTime) {
break;
}
findAll: function (eventStartTime, duration) {
var pageStateEntries = pageStateHistory.findAll(eventStartTime, duration);
if (pageStateEntries.length === 0) {
return;
}
return entries.length ? entries : undefined;
var pageStateServerEntries = [];
// limit the number of entries to return
var limit = Math.max(0, pageStateEntries.length - maxPageStateEntriesSelectable);
// loop page state entries backward to return the selected ones in desc order
for (var index = pageStateEntries.length - 1; index >= limit; index--) {
var pageState = pageStateEntries[index];
// compute the start time relative to the event start time (ex: to be relative to the view start time)
var relativeStartTime = (0, browser_core_1.elapsed)(eventStartTime, pageState.startTime);
pageStateServerEntries.push({
state: pageState.state,
start: (0, browser_core_1.toServerDuration)(relativeStartTime),
});
}
return pageStateServerEntries;
},
stop: stop,
addPageState: addPageState,
stop: function () {
stopEventListeners();
pageStateHistory.stop();
},
};
}
exports.startPageStateHistory = startPageStateHistory;
function computePageState(event) {
if (event.type === "freeze" /* DOM_EVENT.FREEZE */) {
return "frozen" /* PageState.FROZEN */;
}
else if (event.type === "pagehide" /* DOM_EVENT.PAGE_HIDE */) {
return event.persisted ? "frozen" /* PageState.FROZEN */ : "terminated" /* PageState.TERMINATED */;
}
return getPageState();
}
function getPageState() {

@@ -64,19 +87,2 @@ if (document.visibilityState === 'hidden') {

}
function addPageState(nextPageState, maxPageStateEntries) {
if (maxPageStateEntries === void 0) { maxPageStateEntries = exports.MAX_PAGE_STATE_ENTRIES; }
if (nextPageState === currentPageState) {
return;
}
currentPageState = nextPageState;
if (pageStateEntries.length === maxPageStateEntries) {
pageStateEntries.shift();
}
pageStateEntries.push({ state: currentPageState, startTime: (0, browser_core_1.relativeNow)() });
}
exports.addPageState = addPageState;
function resetPageStates() {
pageStateEntries = [];
currentPageState = undefined;
}
exports.resetPageStates = resetPageStates;
//# sourceMappingURL=pageStateHistory.js.map

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

var indexingInfo = computeIndexingInfo(sessionManager, startClocks);
var duration = (0, browser_core_1.toServerDuration)(request.duration);
var duration = computeRequestDuration(pageStateHistory, startClocks, request.duration);
var pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, (_a = matchingTiming === null || matchingTiming === void 0 ? void 0 : matchingTiming.duration) !== null && _a !== void 0 ? _a : request.duration);

@@ -143,2 +143,12 @@ var resourceEvent = (0, browser_core_1.combine)({

}
function computeRequestDuration(pageStateHistory, startClocks, duration) {
var _a;
// TODO remove FF in next major
if (!(0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.NO_RESOURCE_DURATION_FROZEN_STATE)) {
return (0, browser_core_1.toServerDuration)(duration);
}
var requestCrossedFrozenState = (_a = pageStateHistory
.findAll(startClocks.relative, duration)) === null || _a === void 0 ? void 0 : _a.some(function (pageState) { return pageState.state === "frozen" /* PageState.FROZEN */; });
return !requestCrossedFrozenState ? (0, browser_core_1.toServerDuration)(duration) : undefined;
}
//# sourceMappingURL=resourceCollection.js.map

@@ -8,4 +8,5 @@ import type { Observable } from '@datadog/browser-core';

import type { FeatureFlagContexts } from '../../contexts/featureFlagContext';
import type { PageStateHistory } from '../../contexts/pageStateHistory';
import type { ViewOptions } from './trackViews';
export declare function startViewCollection(lifeCycle: LifeCycle, configuration: RumConfiguration, location: Location, domMutationObservable: Observable<void>, locationChangeObservable: Observable<LocationChange>, foregroundContexts: ForegroundContexts, featureFlagContexts: FeatureFlagContexts, recorderApi: RecorderApi, initialViewOptions?: ViewOptions): {
export declare function startViewCollection(lifeCycle: LifeCycle, configuration: RumConfiguration, location: Location, domMutationObservable: Observable<void>, locationChangeObservable: Observable<LocationChange>, foregroundContexts: ForegroundContexts, featureFlagContexts: FeatureFlagContexts, pageStateHistory: PageStateHistory, recorderApi: RecorderApi, initialViewOptions?: ViewOptions): {
addTiming: (name: string, time?: import("@datadog/browser-core").TimeStamp | import("@datadog/browser-core").RelativeTime) => void;

@@ -12,0 +13,0 @@ startView: (options?: ViewOptions | undefined, startClocks?: import("@datadog/browser-core").ClocksState | undefined) => void;

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

var trackViews_1 = require("./trackViews");
function startViewCollection(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, recorderApi, initialViewOptions) {
function startViewCollection(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, pageStateHistory, recorderApi, initialViewOptions) {
lifeCycle.subscribe(3 /* LifeCycleEventType.VIEW_UPDATED */, function (view) {
return lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi));
return lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi, pageStateHistory));
});
return (0, trackViews_1.trackViews)(location, lifeCycle, domMutationObservable, configuration, locationChangeObservable, !configuration.trackViewsManually, initialViewOptions);
var trackViewResult = (0, trackViews_1.trackViews)(location, lifeCycle, domMutationObservable, configuration, locationChangeObservable, !configuration.trackViewsManually, initialViewOptions);
return trackViewResult;
}
exports.startViewCollection = startViewCollection;
function processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi) {
function processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi, pageStateHistory) {
var replayStats = recorderApi.getReplayStats(view.id);
var featureFlagContext = featureFlagContexts.findFeatureFlagEvaluations(view.startClocks.relative);
var pageStatesEnabled = (0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.PAGE_STATES);
var viewEvent = {

@@ -21,2 +23,3 @@ _dd: {

replay_stats: replayStats,
page_states: pageStatesEnabled ? pageStateHistory.findAll(view.startClocks.relative, view.duration) : undefined,
},

@@ -56,3 +59,5 @@ date: view.startClocks.timeStamp,

time_spent: (0, browser_core_1.toServerDuration)(view.duration),
in_foreground_periods: foregroundContexts.selectInForegroundPeriodsFor(view.startClocks.relative, view.duration),
in_foreground_periods: !pageStatesEnabled
? foregroundContexts.selectInForegroundPeriodsFor(view.startClocks.relative, view.duration)
: undefined,
},

@@ -59,0 +64,0 @@ feature_flags: featureFlagContext && !(0, browser_core_1.isEmptyObject)(featureFlagContext) ? featureFlagContext : undefined,

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

function startRumSessionManager(configuration, lifeCycle) {
var sessionManager = (0, browser_core_1.startSessionManager)(configuration.cookieOptions, exports.RUM_SESSION_KEY, function (rawTrackingType) {
return computeSessionState(configuration, rawTrackingType);
});
var sessionManager = (0, browser_core_1.startSessionManager)(
// TODO - Improve configuration type and remove assertion
configuration.sessionStoreStrategyType, exports.RUM_SESSION_KEY, function (rawTrackingType) { return computeSessionState(configuration, rawTrackingType); });
sessionManager.expireObservable.subscribe(function () {

@@ -12,0 +12,0 @@ lifeCycle.notify(7 /* LifeCycleEventType.SESSION_EXPIRED */);

import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause } from '@datadog/browser-core';
import type { PageStateEntry } from './domain/contexts/pageStateHistory';
import type { PageState } from './domain/contexts/pageStateHistory';
import type { RumSessionPlan } from './domain/rumSessionManager';

@@ -17,3 +17,3 @@ export declare const enum RumEventType {

id: string;
duration: ServerDuration;
duration?: ServerDuration;
url: string;

@@ -35,3 +35,3 @@ method?: string;

discarded: boolean;
page_states?: PageStateEntry[];
page_states?: PageStateServerEntry[];
};

@@ -100,2 +100,3 @@ }

replay_stats?: ReplayStats;
page_states?: PageStateServerEntry[];
};

@@ -107,2 +108,6 @@ }

}
export type PageStateServerEntry = {
state: PageState;
start: ServerDuration;
};
export declare const enum ViewLoadingType {

@@ -109,0 +114,0 @@ INITIAL_LOAD = "initial_load",

@@ -353,3 +353,3 @@ /**

*/
readonly duration: number;
readonly duration?: number;
/**

@@ -699,2 +699,6 @@ * Size in octet of the resource response body

readonly is_active?: boolean;
/**
* Whether this session has been sampled for replay
*/
readonly sampled_for_replay?: boolean;
[k: string]: unknown;

@@ -716,2 +720,16 @@ };

readonly document_version: number;
/**
* List of the page states during the view
*/
readonly page_states?: {
/**
* Page state name
*/
readonly state: 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated';
/**
* Duration in ns between start of the view and start of the page state
*/
readonly start: number;
[k: string]: unknown;
}[];
[k: string]: unknown;

@@ -942,5 +960,5 @@ };

/**
* Session plan: 1 is the plan without replay, 2 is the plan with replay
* Session plan: 1 is the plan without replay, 2 is the plan with replay (deprecated)
*/
plan: 1 | 2;
plan?: 1 | 2;
[k: string]: unknown;

@@ -947,0 +965,0 @@ };

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

import { noop, willSyntheticsInjectRum, assign, BoundedBuffer, buildCookieOptions, createContextManager, deepClone, makePublicApi, monitor, clocksNow, timeStampNow, display, callMonitored, createHandlingStack, canUseEventBridge, areCookiesAuthorized, checkUser, sanitizeUser, sanitize, } from '@datadog/browser-core';
import { noop, willSyntheticsInjectRum, assign, BoundedBuffer, createContextManager, deepClone, makePublicApi, monitor, clocksNow, timeStampNow, display, callMonitored, createHandlingStack, canUseEventBridge, checkUser, sanitizeUser, sanitize, } from '@datadog/browser-core';
import { validateAndBuildRumConfiguration } from '../domain/configuration';

@@ -43,8 +43,6 @@ import { buildCommonContext } from '../domain/contexts/commonContext';

}
if (canUseEventBridge()) {
var eventBridgeAvailable = canUseEventBridge();
if (eventBridgeAvailable) {
initConfiguration = overrideInitConfigurationForBridge(initConfiguration);
}
else if (!canHandleSession(initConfiguration)) {
return;
}
if (!canInitRum(initConfiguration)) {

@@ -57,2 +55,6 @@ return;

}
if (!eventBridgeAvailable && !configuration.sessionStoreStrategyType) {
display.warn('No storage available for session. We will not send any data.');
return;
}
if (!configuration.trackViewsManually) {

@@ -156,13 +158,2 @@ doStartRum(initConfiguration, configuration);

return rumPublicApi;
function canHandleSession(initConfiguration) {
if (!areCookiesAuthorized(buildCookieOptions(initConfiguration))) {
display.warn('Cookies are not authorized, we will not send any data.');
return false;
}
if (isLocalFile()) {
display.error('Execution is not allowed in the current context.');
return false;
}
return true;
}
function canInitRum(initConfiguration) {

@@ -184,6 +175,3 @@ if (isAlreadyInitialized) {

}
function isLocalFile() {
return window.location.protocol === 'file:';
}
}
//# sourceMappingURL=rumPublicApi.js.map

@@ -24,2 +24,3 @@ import type { Observable, RawError, ContextManager } from '@datadog/browser-core';

foregroundContexts: import("../domain/contexts/foregroundContexts").ForegroundContexts;
pageStateHistory: import("../domain/contexts/pageStateHistory").PageStateHistory;
urlContexts: {

@@ -26,0 +27,0 @@ findUrl: (startTime?: import("@datadog/browser-core").RelativeTime | undefined) => import("../domain/contexts/urlContexts").UrlContext | undefined;

@@ -64,8 +64,7 @@ import { sendToExtension, createPageExitObservable, addTelemetryConfiguration, startTelemetry, canUseEventBridge, getEventBridge, } from '@datadog/browser-core';

var locationChangeObservable = createLocationChangeObservable(location);
var _a = startRumEventCollection(lifeCycle, configuration, location, session, locationChangeObservable, domMutationObservable, function () { return buildCommonContext(globalContextManager, userContextManager, recorderApi); }, reportError), viewContexts = _a.viewContexts, foregroundContexts = _a.foregroundContexts, urlContexts = _a.urlContexts, actionContexts = _a.actionContexts, addAction = _a.addAction;
var _a = startRumEventCollection(lifeCycle, configuration, location, session, locationChangeObservable, domMutationObservable, function () { return buildCommonContext(globalContextManager, userContextManager, recorderApi); }, reportError), viewContexts = _a.viewContexts, foregroundContexts = _a.foregroundContexts, pageStateHistory = _a.pageStateHistory, urlContexts = _a.urlContexts, actionContexts = _a.actionContexts, addAction = _a.addAction;
addTelemetryConfiguration(serializeRumConfiguration(initConfiguration));
startLongTaskCollection(lifeCycle, session);
var pageStateHistory = startPageStateHistory();
startResourceCollection(lifeCycle, configuration, session, pageStateHistory);
var _b = startViewCollection(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, recorderApi, initialViewOptions), addTiming = _b.addTiming, startView = _b.startView;
var _b = startViewCollection(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, pageStateHistory, recorderApi, initialViewOptions), addTiming = _b.addTiming, startView = _b.startView;
var addError = startErrorCollection(lifeCycle, foregroundContexts, featureFlagContexts).addError;

@@ -100,2 +99,3 @@ startRequestCollection(lifeCycle, configuration, session);

var foregroundContexts = startForegroundContexts();
var pageStateHistory = startPageStateHistory();
var _a = startActionCollection(lifeCycle, domMutationObservable, configuration, foregroundContexts), addAction = _a.addAction, actionContexts = _a.actionContexts;

@@ -106,2 +106,3 @@ startRumAssembly(configuration, lifeCycle, sessionManager, viewContexts, urlContexts, actionContexts, buildCommonContext, reportError);

foregroundContexts: foregroundContexts,
pageStateHistory: pageStateHistory,
urlContexts: urlContexts,

@@ -108,0 +109,0 @@ addAction: addAction,

@@ -53,3 +53,3 @@ import { combine, isEmptyObject, timeStampNow, currentDrift, display, createEventRateLimiter, canUseEventBridge, assign, } from '@datadog/browser-core';

},
browser_sdk_version: canUseEventBridge() ? "4.42.2" : undefined,
browser_sdk_version: canUseEventBridge() ? "4.43.0" : undefined,
},

@@ -56,0 +56,0 @@ application: {

import type { Duration, RelativeTime } from '@datadog/browser-core';
export declare const MAX_PAGE_STATE_ENTRIES = 500;
import type { PageStateServerEntry } from '../../rawRumEvent.types';
export declare const MAX_PAGE_STATE_ENTRIES = 4000;
export declare const MAX_PAGE_STATE_ENTRIES_SELECTABLE = 500;
export declare const PAGE_STATE_CONTEXT_TIME_OUT_DELAY: number;
export declare const enum PageState {

@@ -15,7 +18,6 @@ ACTIVE = "active",

export interface PageStateHistory {
findAll: (startTime: RelativeTime, duration: Duration) => PageStateEntry[] | undefined;
findAll: (startTime: RelativeTime, duration: Duration) => PageStateServerEntry[] | undefined;
addPageState(nextPageState: PageState, startTime?: RelativeTime): void;
stop: () => void;
}
export declare function startPageStateHistory(): PageStateHistory;
export declare function addPageState(nextPageState: PageState, maxPageStateEntries?: number): void;
export declare function resetPageStates(): void;
export declare function startPageStateHistory(maxPageStateEntriesSelectable?: number): PageStateHistory;

@@ -1,8 +0,13 @@

import { addDuration, addEventListeners, relativeNow } from '@datadog/browser-core';
export var MAX_PAGE_STATE_ENTRIES = 500;
var pageStateEntries = [];
var currentPageState;
export function startPageStateHistory() {
addPageState(getPageState());
var stop = addEventListeners(window, [
import { elapsed, ValueHistory, SESSION_TIME_OUT_DELAY, toServerDuration, addEventListeners, relativeNow, } from '@datadog/browser-core';
// Arbitrary value to cap number of element for memory consumption in the browser
export var MAX_PAGE_STATE_ENTRIES = 4000;
// Arbitrary value to cap number of element for backend & to save bandwidth
export var MAX_PAGE_STATE_ENTRIES_SELECTABLE = 500;
export var PAGE_STATE_CONTEXT_TIME_OUT_DELAY = SESSION_TIME_OUT_DELAY;
export function startPageStateHistory(maxPageStateEntriesSelectable) {
if (maxPageStateEntriesSelectable === void 0) { maxPageStateEntriesSelectable = MAX_PAGE_STATE_ENTRIES_SELECTABLE; }
var pageStateHistory = new ValueHistory(PAGE_STATE_CONTEXT_TIME_OUT_DELAY, MAX_PAGE_STATE_ENTRIES);
var currentPageState;
addPageState(getPageState(), relativeNow());
var stopEventListeners = addEventListeners(window, [
"pageshow" /* DOM_EVENT.PAGE_SHOW */,

@@ -18,34 +23,52 @@ "focus" /* DOM_EVENT.FOCUS */,

// cf: developer extension auto flush: https://github.com/DataDog/browser-sdk/blob/2f72bf05a672794c9e33965351964382a94c72ba/developer-extension/src/panel/flushEvents.ts#L11-L12
if (!event.isTrusted) {
if (event.isTrusted) {
addPageState(computePageState(event), event.timeStamp);
}
}, { capture: true }).stop;
function addPageState(nextPageState, startTime) {
if (startTime === void 0) { startTime = relativeNow(); }
if (nextPageState === currentPageState) {
return;
}
if (event.type === "freeze" /* DOM_EVENT.FREEZE */) {
addPageState("frozen" /* PageState.FROZEN */);
}
else if (event.type === "pagehide" /* DOM_EVENT.PAGE_HIDE */) {
addPageState(event.persisted ? "frozen" /* PageState.FROZEN */ : "terminated" /* PageState.TERMINATED */);
}
else {
addPageState(getPageState());
}
}, { capture: true }).stop;
currentPageState = nextPageState;
pageStateHistory.closeActive(startTime);
pageStateHistory.add({ state: currentPageState, startTime: startTime }, startTime);
}
return {
findAll: function (startTime, duration) {
var entries = [];
var endTime = addDuration(startTime, duration);
for (var i = pageStateEntries.length - 1; i >= 0; i--) {
var stateStartTime = pageStateEntries[i].startTime;
if (stateStartTime >= endTime) {
continue;
}
entries.unshift(pageStateEntries[i]);
if (stateStartTime < startTime) {
break;
}
findAll: function (eventStartTime, duration) {
var pageStateEntries = pageStateHistory.findAll(eventStartTime, duration);
if (pageStateEntries.length === 0) {
return;
}
return entries.length ? entries : undefined;
var pageStateServerEntries = [];
// limit the number of entries to return
var limit = Math.max(0, pageStateEntries.length - maxPageStateEntriesSelectable);
// loop page state entries backward to return the selected ones in desc order
for (var index = pageStateEntries.length - 1; index >= limit; index--) {
var pageState = pageStateEntries[index];
// compute the start time relative to the event start time (ex: to be relative to the view start time)
var relativeStartTime = elapsed(eventStartTime, pageState.startTime);
pageStateServerEntries.push({
state: pageState.state,
start: toServerDuration(relativeStartTime),
});
}
return pageStateServerEntries;
},
stop: stop,
addPageState: addPageState,
stop: function () {
stopEventListeners();
pageStateHistory.stop();
},
};
}
function computePageState(event) {
if (event.type === "freeze" /* DOM_EVENT.FREEZE */) {
return "frozen" /* PageState.FROZEN */;
}
else if (event.type === "pagehide" /* DOM_EVENT.PAGE_HIDE */) {
return event.persisted ? "frozen" /* PageState.FROZEN */ : "terminated" /* PageState.TERMINATED */;
}
return getPageState();
}
function getPageState() {

@@ -60,17 +83,2 @@ if (document.visibilityState === 'hidden') {

}
export function addPageState(nextPageState, maxPageStateEntries) {
if (maxPageStateEntries === void 0) { maxPageStateEntries = MAX_PAGE_STATE_ENTRIES; }
if (nextPageState === currentPageState) {
return;
}
currentPageState = nextPageState;
if (pageStateEntries.length === maxPageStateEntries) {
pageStateEntries.shift();
}
pageStateEntries.push({ state: currentPageState, startTime: relativeNow() });
}
export function resetPageStates() {
pageStateEntries = [];
currentPageState = undefined;
}
//# sourceMappingURL=pageStateHistory.js.map

@@ -25,3 +25,3 @@ import { combine, generateUUID, toServerDuration, relativeToClocks, assign, isNumber, isExperimentalFeatureEnabled, ExperimentalFeature, } from '@datadog/browser-core';

var indexingInfo = computeIndexingInfo(sessionManager, startClocks);
var duration = toServerDuration(request.duration);
var duration = computeRequestDuration(pageStateHistory, startClocks, request.duration);
var pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, (_a = matchingTiming === null || matchingTiming === void 0 ? void 0 : matchingTiming.duration) !== null && _a !== void 0 ? _a : request.duration);

@@ -139,2 +139,12 @@ var resourceEvent = combine({

}
function computeRequestDuration(pageStateHistory, startClocks, duration) {
var _a;
// TODO remove FF in next major
if (!isExperimentalFeatureEnabled(ExperimentalFeature.NO_RESOURCE_DURATION_FROZEN_STATE)) {
return toServerDuration(duration);
}
var requestCrossedFrozenState = (_a = pageStateHistory
.findAll(startClocks.relative, duration)) === null || _a === void 0 ? void 0 : _a.some(function (pageState) { return pageState.state === "frozen" /* PageState.FROZEN */; });
return !requestCrossedFrozenState ? toServerDuration(duration) : undefined;
}
//# sourceMappingURL=resourceCollection.js.map

@@ -8,4 +8,5 @@ import type { Observable } from '@datadog/browser-core';

import type { FeatureFlagContexts } from '../../contexts/featureFlagContext';
import type { PageStateHistory } from '../../contexts/pageStateHistory';
import type { ViewOptions } from './trackViews';
export declare function startViewCollection(lifeCycle: LifeCycle, configuration: RumConfiguration, location: Location, domMutationObservable: Observable<void>, locationChangeObservable: Observable<LocationChange>, foregroundContexts: ForegroundContexts, featureFlagContexts: FeatureFlagContexts, recorderApi: RecorderApi, initialViewOptions?: ViewOptions): {
export declare function startViewCollection(lifeCycle: LifeCycle, configuration: RumConfiguration, location: Location, domMutationObservable: Observable<void>, locationChangeObservable: Observable<LocationChange>, foregroundContexts: ForegroundContexts, featureFlagContexts: FeatureFlagContexts, pageStateHistory: PageStateHistory, recorderApi: RecorderApi, initialViewOptions?: ViewOptions): {
addTiming: (name: string, time?: import("@datadog/browser-core").TimeStamp | import("@datadog/browser-core").RelativeTime) => void;

@@ -12,0 +13,0 @@ startView: (options?: ViewOptions | undefined, startClocks?: import("@datadog/browser-core").ClocksState | undefined) => void;

@@ -1,12 +0,14 @@

import { isEmptyObject, mapValues, toServerDuration, isNumber } from '@datadog/browser-core';
import { isExperimentalFeatureEnabled, ExperimentalFeature, isEmptyObject, mapValues, toServerDuration, isNumber, } from '@datadog/browser-core';
import { trackViews } from './trackViews';
export function startViewCollection(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, recorderApi, initialViewOptions) {
export function startViewCollection(lifeCycle, configuration, location, domMutationObservable, locationChangeObservable, foregroundContexts, featureFlagContexts, pageStateHistory, recorderApi, initialViewOptions) {
lifeCycle.subscribe(3 /* LifeCycleEventType.VIEW_UPDATED */, function (view) {
return lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi));
return lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi, pageStateHistory));
});
return trackViews(location, lifeCycle, domMutationObservable, configuration, locationChangeObservable, !configuration.trackViewsManually, initialViewOptions);
var trackViewResult = trackViews(location, lifeCycle, domMutationObservable, configuration, locationChangeObservable, !configuration.trackViewsManually, initialViewOptions);
return trackViewResult;
}
function processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi) {
function processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi, pageStateHistory) {
var replayStats = recorderApi.getReplayStats(view.id);
var featureFlagContext = featureFlagContexts.findFeatureFlagEvaluations(view.startClocks.relative);
var pageStatesEnabled = isExperimentalFeatureEnabled(ExperimentalFeature.PAGE_STATES);
var viewEvent = {

@@ -16,2 +18,3 @@ _dd: {

replay_stats: replayStats,
page_states: pageStatesEnabled ? pageStateHistory.findAll(view.startClocks.relative, view.duration) : undefined,
},

@@ -51,3 +54,5 @@ date: view.startClocks.timeStamp,

time_spent: toServerDuration(view.duration),
in_foreground_periods: foregroundContexts.selectInForegroundPeriodsFor(view.startClocks.relative, view.duration),
in_foreground_periods: !pageStatesEnabled
? foregroundContexts.selectInForegroundPeriodsFor(view.startClocks.relative, view.duration)
: undefined,
},

@@ -54,0 +59,0 @@ feature_flags: featureFlagContext && !isEmptyObject(featureFlagContext) ? featureFlagContext : undefined,

import { Observable, noop, performDraw, startSessionManager } from '@datadog/browser-core';
export var RUM_SESSION_KEY = 'rum';
export function startRumSessionManager(configuration, lifeCycle) {
var sessionManager = startSessionManager(configuration.cookieOptions, RUM_SESSION_KEY, function (rawTrackingType) {
return computeSessionState(configuration, rawTrackingType);
});
var sessionManager = startSessionManager(
// TODO - Improve configuration type and remove assertion
configuration.sessionStoreStrategyType, RUM_SESSION_KEY, function (rawTrackingType) { return computeSessionState(configuration, rawTrackingType); });
sessionManager.expireObservable.subscribe(function () {

@@ -8,0 +8,0 @@ lifeCycle.notify(7 /* LifeCycleEventType.SESSION_EXPIRED */);

import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause } from '@datadog/browser-core';
import type { PageStateEntry } from './domain/contexts/pageStateHistory';
import type { PageState } from './domain/contexts/pageStateHistory';
import type { RumSessionPlan } from './domain/rumSessionManager';

@@ -17,3 +17,3 @@ export declare const enum RumEventType {

id: string;
duration: ServerDuration;
duration?: ServerDuration;
url: string;

@@ -35,3 +35,3 @@ method?: string;

discarded: boolean;
page_states?: PageStateEntry[];
page_states?: PageStateServerEntry[];
};

@@ -100,2 +100,3 @@ }

replay_stats?: ReplayStats;
page_states?: PageStateServerEntry[];
};

@@ -107,2 +108,6 @@ }

}
export type PageStateServerEntry = {
state: PageState;
start: ServerDuration;
};
export declare const enum ViewLoadingType {

@@ -109,0 +114,0 @@ INITIAL_LOAD = "initial_load",

@@ -353,3 +353,3 @@ /**

*/
readonly duration: number;
readonly duration?: number;
/**

@@ -699,2 +699,6 @@ * Size in octet of the resource response body

readonly is_active?: boolean;
/**
* Whether this session has been sampled for replay
*/
readonly sampled_for_replay?: boolean;
[k: string]: unknown;

@@ -716,2 +720,16 @@ };

readonly document_version: number;
/**
* List of the page states during the view
*/
readonly page_states?: {
/**
* Page state name
*/
readonly state: 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated';
/**
* Duration in ns between start of the view and start of the page state
*/
readonly start: number;
[k: string]: unknown;
}[];
[k: string]: unknown;

@@ -942,5 +960,5 @@ };

/**
* Session plan: 1 is the plan without replay, 2 is the plan with replay
* Session plan: 1 is the plan without replay, 2 is the plan with replay (deprecated)
*/
plan: 1 | 2;
plan?: 1 | 2;
[k: string]: unknown;

@@ -947,0 +965,0 @@ };

{
"name": "@datadog/browser-rum-core",
"version": "4.42.2",
"version": "4.43.0",
"license": "Apache-2.0",

@@ -15,3 +15,3 @@ "main": "cjs/index.js",

"dependencies": {
"@datadog/browser-core": "4.42.2"
"@datadog/browser-core": "4.43.0"
},

@@ -29,3 +29,3 @@ "devDependencies": {

},
"gitHead": "4c15587221b8f3c0c111500d9b65b679f4cf05b0"
"gitHead": "27baf6471a3e48028c52af9c6282e00662687cc2"
}

@@ -8,3 +8,2 @@ import type { Context, InitConfiguration, TimeStamp, RelativeTime, User } from '@datadog/browser-core'

BoundedBuffer,
buildCookieOptions,
createContextManager,

@@ -20,3 +19,2 @@ deepClone,

canUseEventBridge,
areCookiesAuthorized,
checkUser,

@@ -115,6 +113,5 @@ sanitizeUser,

if (canUseEventBridge()) {
const eventBridgeAvailable = canUseEventBridge()
if (eventBridgeAvailable) {
initConfiguration = overrideInitConfigurationForBridge(initConfiguration)
} else if (!canHandleSession(initConfiguration)) {
return
}

@@ -131,2 +128,7 @@

if (!eventBridgeAvailable && !configuration.sessionStoreStrategyType) {
display.warn('No storage available for session. We will not send any data.')
return
}
if (!configuration.trackViewsManually) {

@@ -280,15 +282,2 @@ doStartRum(initConfiguration, configuration)

function canHandleSession(initConfiguration: RumInitConfiguration): boolean {
if (!areCookiesAuthorized(buildCookieOptions(initConfiguration))) {
display.warn('Cookies are not authorized, we will not send any data.')
return false
}
if (isLocalFile()) {
display.error('Execution is not allowed in the current context.')
return false
}
return true
}
function canInitRum(initConfiguration: RumInitConfiguration) {

@@ -311,6 +300,2 @@ if (isAlreadyInitialized) {

}
function isLocalFile() {
return window.location.protocol === 'file:'
}
}

@@ -105,12 +105,13 @@ import type { Observable, TelemetryEvent, RawError, ContextManager } from '@datadog/browser-core'

const { viewContexts, foregroundContexts, urlContexts, actionContexts, addAction } = startRumEventCollection(
lifeCycle,
configuration,
location,
session,
locationChangeObservable,
domMutationObservable,
() => buildCommonContext(globalContextManager, userContextManager, recorderApi),
reportError
)
const { viewContexts, foregroundContexts, pageStateHistory, urlContexts, actionContexts, addAction } =
startRumEventCollection(
lifeCycle,
configuration,
location,
session,
locationChangeObservable,
domMutationObservable,
() => buildCommonContext(globalContextManager, userContextManager, recorderApi),
reportError
)

@@ -120,3 +121,2 @@ addTelemetryConfiguration(serializeRumConfiguration(initConfiguration))

startLongTaskCollection(lifeCycle, session)
const pageStateHistory = startPageStateHistory()
startResourceCollection(lifeCycle, configuration, session, pageStateHistory)

@@ -131,2 +131,3 @@ const { addTiming, startView } = startViewCollection(

featureFlagContexts,
pageStateHistory,
recorderApi,

@@ -185,2 +186,4 @@ initialViewOptions

const foregroundContexts = startForegroundContexts()
const pageStateHistory = startPageStateHistory()
const { addAction, actionContexts } = startActionCollection(

@@ -207,2 +210,3 @@ lifeCycle,

foregroundContexts,
pageStateHistory,
urlContexts,

@@ -209,0 +213,0 @@ addAction,

import type { Duration, RelativeTime } from '@datadog/browser-core'
import { addDuration, addEventListeners, relativeNow, DOM_EVENT } from '@datadog/browser-core'
import {
elapsed,
ValueHistory,
SESSION_TIME_OUT_DELAY,
toServerDuration,
addEventListeners,
relativeNow,
DOM_EVENT,
} from '@datadog/browser-core'
import type { PageStateServerEntry } from '../../rawRumEvent.types'
export const MAX_PAGE_STATE_ENTRIES = 500
// Arbitrary value to cap number of element for memory consumption in the browser
export const MAX_PAGE_STATE_ENTRIES = 4000
// Arbitrary value to cap number of element for backend & to save bandwidth
export const MAX_PAGE_STATE_ENTRIES_SELECTABLE = 500
export const PAGE_STATE_CONTEXT_TIME_OUT_DELAY = SESSION_TIME_OUT_DELAY
export const enum PageState {

@@ -13,14 +27,20 @@ ACTIVE = 'active',

}
export type PageStateEntry = { state: PageState; startTime: RelativeTime }
export interface PageStateHistory {
findAll: (startTime: RelativeTime, duration: Duration) => PageStateEntry[] | undefined
findAll: (startTime: RelativeTime, duration: Duration) => PageStateServerEntry[] | undefined
addPageState(nextPageState: PageState, startTime?: RelativeTime): void
stop: () => void
}
let pageStateEntries: PageStateEntry[] = []
let currentPageState: PageState | undefined
export function startPageStateHistory(): PageStateHistory {
addPageState(getPageState())
export function startPageStateHistory(
maxPageStateEntriesSelectable = MAX_PAGE_STATE_ENTRIES_SELECTABLE
): PageStateHistory {
const pageStateHistory = new ValueHistory<PageStateEntry>(PAGE_STATE_CONTEXT_TIME_OUT_DELAY, MAX_PAGE_STATE_ENTRIES)
const { stop } = addEventListeners(
let currentPageState: PageState
addPageState(getPageState(), relativeNow())
const { stop: stopEventListeners } = addEventListeners(
window,

@@ -39,13 +59,5 @@ [

// cf: developer extension auto flush: https://github.com/DataDog/browser-sdk/blob/2f72bf05a672794c9e33965351964382a94c72ba/developer-extension/src/panel/flushEvents.ts#L11-L12
if (!event.isTrusted) {
return
if (event.isTrusted) {
addPageState(computePageState(event), event.timeStamp as RelativeTime)
}
if (event.type === DOM_EVENT.FREEZE) {
addPageState(PageState.FROZEN)
} else if (event.type === DOM_EVENT.PAGE_HIDE) {
addPageState((event as PageTransitionEvent).persisted ? PageState.FROZEN : PageState.TERMINATED)
} else {
addPageState(getPageState())
}
},

@@ -55,53 +67,65 @@ { capture: true }

function addPageState(nextPageState: PageState, startTime = relativeNow()) {
if (nextPageState === currentPageState) {
return
}
currentPageState = nextPageState
pageStateHistory.closeActive(startTime)
pageStateHistory.add({ state: currentPageState, startTime }, startTime)
}
return {
findAll(startTime: RelativeTime, duration: Duration) {
const entries: PageStateEntry[] = []
const endTime = addDuration(startTime, duration)
for (let i = pageStateEntries.length - 1; i >= 0; i--) {
const { startTime: stateStartTime } = pageStateEntries[i]
findAll: (eventStartTime: RelativeTime, duration: Duration): PageStateServerEntry[] | undefined => {
const pageStateEntries = pageStateHistory.findAll(eventStartTime, duration)
if (stateStartTime >= endTime) {
continue
}
if (pageStateEntries.length === 0) {
return
}
entries.unshift(pageStateEntries[i])
const pageStateServerEntries = []
// limit the number of entries to return
const limit = Math.max(0, pageStateEntries.length - maxPageStateEntriesSelectable)
if (stateStartTime < startTime) {
break
}
// loop page state entries backward to return the selected ones in desc order
for (let index = pageStateEntries.length - 1; index >= limit; index--) {
const pageState = pageStateEntries[index]
// compute the start time relative to the event start time (ex: to be relative to the view start time)
const relativeStartTime = elapsed(eventStartTime, pageState.startTime)
pageStateServerEntries.push({
state: pageState.state,
start: toServerDuration(relativeStartTime),
})
}
return entries.length ? entries : undefined
return pageStateServerEntries
},
stop,
addPageState,
stop: () => {
stopEventListeners()
pageStateHistory.stop()
},
}
}
function getPageState(): PageState {
function computePageState(event: Event) {
if (event.type === DOM_EVENT.FREEZE) {
return PageState.FROZEN
} else if (event.type === DOM_EVENT.PAGE_HIDE) {
return (event as PageTransitionEvent).persisted ? PageState.FROZEN : PageState.TERMINATED
}
return getPageState()
}
function getPageState() {
if (document.visibilityState === 'hidden') {
return PageState.HIDDEN
}
if (document.hasFocus()) {
return PageState.ACTIVE
}
return PageState.PASSIVE
}
export function addPageState(nextPageState: PageState, maxPageStateEntries = MAX_PAGE_STATE_ENTRIES) {
if (nextPageState === currentPageState) {
return
}
currentPageState = nextPageState
if (pageStateEntries.length === maxPageStateEntries) {
pageStateEntries.shift()
}
pageStateEntries.push({ state: currentPageState, startTime: relativeNow() })
}
export function resetPageStates() {
pageStateEntries = []
currentPageState = undefined
}

@@ -28,2 +28,3 @@ import {

import type { PageStateHistory } from '../../contexts/pageStateHistory'
import { PageState } from '../../contexts/pageStateHistory'
import { matchRequestTiming } from './matchRequestTiming'

@@ -78,3 +79,3 @@ import {

const duration = toServerDuration(request.duration)
const duration = computeRequestDuration(pageStateHistory, startClocks, request.duration)
const pageStateInfo = computePageStateInfo(

@@ -229,1 +230,14 @@ pageStateHistory,

}
function computeRequestDuration(pageStateHistory: PageStateHistory, startClocks: ClocksState, duration: Duration) {
// TODO remove FF in next major
if (!isExperimentalFeatureEnabled(ExperimentalFeature.NO_RESOURCE_DURATION_FROZEN_STATE)) {
return toServerDuration(duration)
}
const requestCrossedFrozenState = pageStateHistory
.findAll(startClocks.relative, duration)
?.some((pageState) => pageState.state === PageState.FROZEN)
return !requestCrossedFrozenState ? toServerDuration(duration) : undefined
}
import type { Duration, ServerDuration, Observable } from '@datadog/browser-core'
import { isEmptyObject, mapValues, toServerDuration, isNumber } from '@datadog/browser-core'
import {
isExperimentalFeatureEnabled,
ExperimentalFeature,
isEmptyObject,
mapValues,
toServerDuration,
isNumber,
} from '@datadog/browser-core'
import type { RecorderApi } from '../../../boot/rumPublicApi'

@@ -12,2 +19,3 @@ import type { RawRumViewEvent } from '../../../rawRumEvent.types'

import type { FeatureFlagContexts } from '../../contexts/featureFlagContext'
import type { PageStateHistory } from '../../contexts/pageStateHistory'
import type { ViewEvent, ViewOptions } from './trackViews'

@@ -24,2 +32,3 @@ import { trackViews } from './trackViews'

featureFlagContexts: FeatureFlagContexts,
pageStateHistory: PageStateHistory,
recorderApi: RecorderApi,

@@ -31,7 +40,6 @@ initialViewOptions?: ViewOptions

LifeCycleEventType.RAW_RUM_EVENT_COLLECTED,
processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi)
processViewUpdate(view, foregroundContexts, featureFlagContexts, recorderApi, pageStateHistory)
)
)
return trackViews(
const trackViewResult = trackViews(
location,

@@ -45,2 +53,4 @@ lifeCycle,

)
return trackViewResult
}

@@ -52,7 +62,8 @@

featureFlagContexts: FeatureFlagContexts,
recorderApi: RecorderApi
recorderApi: RecorderApi,
pageStateHistory: PageStateHistory
): RawRumEventCollectedData<RawRumViewEvent> {
const replayStats = recorderApi.getReplayStats(view.id)
const featureFlagContext = featureFlagContexts.findFeatureFlagEvaluations(view.startClocks.relative)
const pageStatesEnabled = isExperimentalFeatureEnabled(ExperimentalFeature.PAGE_STATES)
const viewEvent: RawRumViewEvent = {

@@ -62,2 +73,3 @@ _dd: {

replay_stats: replayStats,
page_states: pageStatesEnabled ? pageStateHistory.findAll(view.startClocks.relative, view.duration) : undefined,
},

@@ -97,3 +109,5 @@ date: view.startClocks.timeStamp,

time_spent: toServerDuration(view.duration),
in_foreground_periods: foregroundContexts.selectInForegroundPeriodsFor(view.startClocks.relative, view.duration),
in_foreground_periods: !pageStatesEnabled
? foregroundContexts.selectInForegroundPeriodsFor(view.startClocks.relative, view.duration)
: undefined,
},

@@ -100,0 +114,0 @@ feature_flags: featureFlagContext && !isEmptyObject(featureFlagContext) ? featureFlagContext : undefined,

@@ -38,4 +38,7 @@ import type { RelativeTime } from '@datadog/browser-core'

export function startRumSessionManager(configuration: RumConfiguration, lifeCycle: LifeCycle): RumSessionManager {
const sessionManager = startSessionManager(configuration.cookieOptions, RUM_SESSION_KEY, (rawTrackingType) =>
computeSessionState(configuration, rawTrackingType)
const sessionManager = startSessionManager(
// TODO - Improve configuration type and remove assertion
configuration.sessionStoreStrategyType!,
RUM_SESSION_KEY,
(rawTrackingType) => computeSessionState(configuration, rawTrackingType)
)

@@ -42,0 +45,0 @@

@@ -11,3 +11,3 @@ import type {

} from '@datadog/browser-core'
import type { PageStateEntry } from './domain/contexts/pageStateHistory'
import type { PageState } from './domain/contexts/pageStateHistory'
import type { RumSessionPlan } from './domain/rumSessionManager'

@@ -29,3 +29,3 @@

id: string
duration: ServerDuration
duration?: ServerDuration
url: string

@@ -47,3 +47,3 @@ method?: string

discarded: boolean
page_states?: PageStateEntry[]
page_states?: PageStateServerEntry[]
}

@@ -116,2 +116,3 @@ }

replay_stats?: ReplayStats
page_states?: PageStateServerEntry[]
}

@@ -125,2 +126,4 @@ }

export type PageStateServerEntry = { state: PageState; start: ServerDuration }
export const enum ViewLoadingType {

@@ -127,0 +130,0 @@ INITIAL_LOAD = 'initial_load',

@@ -383,3 +383,3 @@ /* eslint-disable */

*/
readonly duration: number
readonly duration?: number
/**

@@ -756,2 +756,6 @@ * Size in octet of the resource response body

readonly is_active?: boolean
/**
* Whether this session has been sampled for replay
*/
readonly sampled_for_replay?: boolean
[k: string]: unknown

@@ -773,2 +777,16 @@ }

readonly document_version: number
/**
* List of the page states during the view
*/
readonly page_states?: {
/**
* Page state name
*/
readonly state: 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated'
/**
* Duration in ns between start of the view and start of the page state
*/
readonly start: number
[k: string]: unknown
}[]
[k: string]: unknown

@@ -1010,5 +1028,5 @@ }

/**
* Session plan: 1 is the plan without replay, 2 is the plan with replay
* Session plan: 1 is the plan without replay, 2 is the plan with replay (deprecated)
*/
plan: 1 | 2
plan?: 1 | 2
[k: string]: unknown

@@ -1015,0 +1033,0 @@ }

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