@datadog/browser-rum-core
Advanced tools
Comparing version 5.1.0 to 5.2.0
@@ -1,2 +0,2 @@ | ||
import type { Context, InitConfiguration, User } from '@datadog/browser-core'; | ||
import type { Context, InitConfiguration, User, DeflateWorker, DeflateEncoderStreamId, DeflateEncoder } from '@datadog/browser-core'; | ||
import type { LifeCycle } from '../domain/lifeCycle'; | ||
@@ -14,3 +14,3 @@ import type { ViewContexts } from '../domain/contexts/viewContexts'; | ||
stop: () => void; | ||
onRumStart: (lifeCycle: LifeCycle, configuration: RumConfiguration, sessionManager: RumSessionManager, viewContexts: ViewContexts) => void; | ||
onRumStart: (lifeCycle: LifeCycle, configuration: RumConfiguration, sessionManager: RumSessionManager, viewContexts: ViewContexts, deflateWorker: DeflateWorker | undefined) => void; | ||
isRecording: () => boolean; | ||
@@ -22,4 +22,6 @@ getReplayStats: (viewId: string) => ReplayStats | undefined; | ||
ignoreInitIfSyntheticsWillInjectRum?: boolean; | ||
startDeflateWorker?: (configuration: RumConfiguration, source: string, onInitializationFailure: () => void) => DeflateWorker | undefined; | ||
createDeflateEncoder?: (configuration: RumConfiguration, worker: DeflateWorker, streamId: DeflateEncoderStreamId) => DeflateEncoder; | ||
} | ||
export declare function makeRumPublicApi(startRumImpl: StartRum, recorderApi: RecorderApi, { ignoreInitIfSyntheticsWillInjectRum }?: RumPublicApiOptions): { | ||
export declare function makeRumPublicApi(startRumImpl: StartRum, recorderApi: RecorderApi, { ignoreInitIfSyntheticsWillInjectRum, startDeflateWorker, createDeflateEncoder }?: RumPublicApiOptions): { | ||
init: (initConfiguration: RumInitConfiguration) => void; | ||
@@ -26,0 +28,0 @@ setGlobalContextProperty: (key: any, value: any) => void; |
@@ -9,3 +9,3 @@ "use strict"; | ||
function makeRumPublicApi(startRumImpl, recorderApi, _a) { | ||
var _b = _a === void 0 ? {} : _a, _c = _b.ignoreInitIfSyntheticsWillInjectRum, ignoreInitIfSyntheticsWillInjectRum = _c === void 0 ? true : _c; | ||
var _b = _a === void 0 ? {} : _a, _c = _b.ignoreInitIfSyntheticsWillInjectRum, ignoreInitIfSyntheticsWillInjectRum = _c === void 0 ? true : _c, startDeflateWorker = _b.startDeflateWorker, createDeflateEncoder = _b.createDeflateEncoder; | ||
var isAlreadyInitialized = false; | ||
@@ -44,2 +44,3 @@ var globalContextManager = (0, browser_core_1.createContextManager)(2 /* CustomerDataType.GlobalContext */); | ||
}; | ||
var deflateWorker; | ||
function initRum(initConfiguration) { | ||
@@ -74,2 +75,14 @@ if (!initConfiguration) { | ||
} | ||
if ((0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.COMPRESS_BATCH) && | ||
!eventBridgeAvailable && | ||
startDeflateWorker) { | ||
deflateWorker = startDeflateWorker(configuration, 'Datadog RUM', | ||
// Worker initialization can fail asynchronously, especially in Firefox where even CSP | ||
// issues are reported asynchronously. For now, the SDK will continue its execution even if | ||
// data won't be sent to Datadog. We could improve this behavior in the future. | ||
browser_core_1.noop); | ||
if (!deflateWorker) { | ||
return; | ||
} | ||
} | ||
if (!configuration.trackViewsManually) { | ||
@@ -100,3 +113,5 @@ doStartRum(initConfiguration, configuration); | ||
} | ||
var startRumResults = startRumImpl(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions); | ||
var startRumResults = startRumImpl(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions, deflateWorker && createDeflateEncoder | ||
? function (streamId) { return createDeflateEncoder(configuration, deflateWorker, streamId); } | ||
: browser_core_1.createIdentityEncoder); | ||
getSessionReplayLinkStrategy = function () { | ||
@@ -108,3 +123,3 @@ return recorderApi.getSessionReplayLink(configuration, startRumResults.session, startRumResults.viewContexts); | ||
(startViewStrategy = startRumResults.startView, addActionStrategy = startRumResults.addAction, addErrorStrategy = startRumResults.addError, addTimingStrategy = startRumResults.addTiming, addFeatureFlagEvaluationStrategy = startRumResults.addFeatureFlagEvaluation, getInternalContextStrategy = startRumResults.getInternalContext, stopSessionStrategy = startRumResults.stopSession); | ||
recorderApi.onRumStart(startRumResults.lifeCycle, configuration, startRumResults.session, startRumResults.viewContexts); | ||
recorderApi.onRumStart(startRumResults.lifeCycle, configuration, startRumResults.session, startRumResults.viewContexts, deflateWorker); | ||
bufferApiCalls.drain(); | ||
@@ -111,0 +126,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import type { Observable, RawError, ContextManager } from '@datadog/browser-core'; | ||
import type { Observable, RawError, ContextManager, DeflateEncoderStreamId, Encoder } from '@datadog/browser-core'; | ||
import { LifeCycle } from '../domain/lifeCycle'; | ||
@@ -9,3 +9,3 @@ import type { RumSessionManager } from '../domain/rumSessionManager'; | ||
import type { RecorderApi } from './rumPublicApi'; | ||
export declare function startRum(initConfiguration: RumInitConfiguration, configuration: RumConfiguration, recorderApi: RecorderApi, globalContextManager: ContextManager, userContextManager: ContextManager, initialViewOptions?: ViewOptions): { | ||
export declare function startRum(initConfiguration: RumInitConfiguration, configuration: RumConfiguration, recorderApi: RecorderApi, globalContextManager: ContextManager, userContextManager: ContextManager, initialViewOptions: ViewOptions | undefined, createEncoder: (streamId: DeflateEncoderStreamId) => Encoder): { | ||
addAction: (action: import("../domain/action/actionCollection").CustomAction, savedCommonContext?: CommonContext | undefined) => void; | ||
@@ -12,0 +12,0 @@ addError: ({ error, handlingStack, startClocks, context: customerContext }: import("../domain/error/errorCollection").ProvidedError, savedCommonContext?: CommonContext | undefined) => void; |
@@ -28,3 +28,3 @@ "use strict"; | ||
var displayContext_1 = require("../domain/contexts/displayContext"); | ||
function startRum(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions) { | ||
function startRum(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions, createEncoder) { | ||
var cleanupTasks = []; | ||
@@ -63,3 +63,3 @@ var lifeCycle = new lifeCycle_1.LifeCycle(); | ||
if (!(0, browser_core_1.canUseEventBridge)()) { | ||
var batch_1 = (0, startRumBatch_1.startRumBatch)(configuration, lifeCycle, telemetry.observable, reportError, pageExitObservable, session.expireObservable); | ||
var batch_1 = (0, startRumBatch_1.startRumBatch)(configuration, lifeCycle, telemetry.observable, reportError, pageExitObservable, session.expireObservable, createEncoder); | ||
cleanupTasks.push(function () { return batch_1.stop(); }); | ||
@@ -66,0 +66,0 @@ (0, startCustomerDataTelemetry_1.startCustomerDataTelemetry)(configuration, telemetry, lifeCycle, globalContextManager, userContextManager, featureFlagContexts, batch_1.flushObservable); |
@@ -57,3 +57,3 @@ "use strict"; | ||
}, | ||
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "5.1.0" : undefined, | ||
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "5.2.0" : undefined, | ||
}, | ||
@@ -60,0 +60,0 @@ application: { |
@@ -10,3 +10,6 @@ "use strict"; | ||
lifeCycle.subscribe(6 /* LifeCycleEventType.REQUEST_COMPLETED */, function (request) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processRequest(request, configuration, sessionManager, pageStateHistory)); | ||
var rawEvent = processRequest(request, configuration, sessionManager, pageStateHistory); | ||
if (rawEvent) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, rawEvent); | ||
} | ||
}); | ||
@@ -17,3 +20,6 @@ lifeCycle.subscribe(0 /* LifeCycleEventType.PERFORMANCE_ENTRIES_COLLECTED */, function (entries) { | ||
if (entry.entryType === performanceCollection_1.RumPerformanceEntryType.RESOURCE && !(0, resourceUtils_1.isRequestKind)(entry)) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processResourceEntry(entry, configuration, sessionManager, pageStateHistory)); | ||
var rawEvent = processResourceEntry(entry, configuration, sessionManager, pageStateHistory); | ||
if (rawEvent) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, rawEvent); | ||
} | ||
} | ||
@@ -26,8 +32,11 @@ } | ||
var _a; | ||
var type = request.type === "xhr" /* RequestType.XHR */ ? "xhr" /* ResourceType.XHR */ : "fetch" /* ResourceType.FETCH */; | ||
var matchingTiming = (0, matchRequestTiming_1.matchRequestTiming)(request); | ||
var startClocks = matchingTiming ? (0, browser_core_1.relativeToClocks)(matchingTiming.startTime) : request.startClocks; | ||
var shouldIndex = shouldIndexResource(configuration, sessionManager, startClocks); | ||
var tracingInfo = computeRequestTracingInfo(request, configuration); | ||
if (!shouldIndex && !tracingInfo) { | ||
return; | ||
} | ||
var type = request.type === "xhr" /* RequestType.XHR */ ? "xhr" /* ResourceType.XHR */ : "fetch" /* ResourceType.FETCH */; | ||
var correspondingTimingOverrides = matchingTiming ? computePerformanceEntryMetrics(matchingTiming) : undefined; | ||
var tracingInfo = computeRequestTracingInfo(request, configuration); | ||
var indexingInfo = computeIndexingInfo(configuration, sessionManager, startClocks); | ||
var duration = computeRequestDuration(pageStateHistory, startClocks, request.duration); | ||
@@ -46,3 +55,6 @@ var pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, (_a = matchingTiming === null || matchingTiming === void 0 ? void 0 : matchingTiming.duration) !== null && _a !== void 0 ? _a : request.duration); | ||
type: "resource" /* RumEventType.RESOURCE */, | ||
}, tracingInfo, correspondingTimingOverrides, indexingInfo, pageStateInfo); | ||
_dd: { | ||
discarded: !shouldIndex, | ||
}, | ||
}, tracingInfo, correspondingTimingOverrides, pageStateInfo); | ||
return { | ||
@@ -62,7 +74,10 @@ startTime: startClocks.relative, | ||
function processResourceEntry(entry, configuration, sessionManager, pageStateHistory) { | ||
var startClocks = (0, browser_core_1.relativeToClocks)(entry.startTime); | ||
var shouldIndex = shouldIndexResource(configuration, sessionManager, startClocks); | ||
var tracingInfo = computeEntryTracingInfo(entry, configuration); | ||
if (!shouldIndex && !tracingInfo) { | ||
return; | ||
} | ||
var type = (0, resourceUtils_1.computeResourceKind)(entry); | ||
var entryMetrics = computePerformanceEntryMetrics(entry); | ||
var startClocks = (0, browser_core_1.relativeToClocks)(entry.startTime); | ||
var tracingInfo = computeEntryTracingInfo(entry, configuration); | ||
var indexingInfo = computeIndexingInfo(configuration, sessionManager, startClocks); | ||
var pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, entry.duration); | ||
@@ -77,3 +92,6 @@ var resourceEvent = (0, browser_core_1.combine)({ | ||
type: "resource" /* RumEventType.RESOURCE */, | ||
}, tracingInfo, entryMetrics, indexingInfo, pageStateInfo); | ||
_dd: { | ||
discarded: !shouldIndex, | ||
}, | ||
}, tracingInfo, entryMetrics, pageStateInfo); | ||
return { | ||
@@ -87,2 +105,5 @@ startTime: startClocks.relative, | ||
} | ||
function shouldIndexResource(configuration, sessionManager, resourceStart) { | ||
return configuration.trackResources && sessionManager.findTrackedSession(resourceStart.relative); | ||
} | ||
function computePerformanceEntryMetrics(timing) { | ||
@@ -127,10 +148,2 @@ return { | ||
} | ||
function computeIndexingInfo(configuration, sessionManager, resourceStart) { | ||
var session = sessionManager.findTrackedSession(resourceStart.relative); | ||
return { | ||
_dd: { | ||
discarded: !session || !configuration.trackResources, | ||
}, | ||
}; | ||
} | ||
function computePageStateInfo(pageStateHistory, startClocks, duration) { | ||
@@ -137,0 +150,0 @@ if (!(0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.RESOURCE_PAGE_STATES)) { |
@@ -23,2 +23,5 @@ "use strict"; | ||
page_states: pageStates, | ||
configuration: { | ||
start_session_replay_recording_manually: configuration.startSessionReplayRecordingManually, | ||
}, | ||
}, | ||
@@ -25,0 +28,0 @@ date: view.startClocks.timeStamp, |
@@ -37,7 +37,9 @@ "use strict"; | ||
var window = slidingSessionWindow(); | ||
var selectorComputationTelemetrySent = false; | ||
var stop = lifeCycle.subscribe(0 /* LifeCycleEventType.PERFORMANCE_ENTRIES_COLLECTED */, function (entries) { | ||
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { | ||
var entry = entries_1[_i]; | ||
var shiftEntries = entries.filter(function (e) { return e.entryType === performanceCollection_1.RumPerformanceEntryType.LAYOUT_SHIFT && !e.hadRecentInput; }); | ||
for (var _i = 0, shiftEntries_1 = shiftEntries; _i < shiftEntries_1.length; _i++) { | ||
var entry = shiftEntries_1[_i]; | ||
if (entry.entryType === performanceCollection_1.RumPerformanceEntryType.LAYOUT_SHIFT && !entry.hadRecentInput) { | ||
window.update(entry); | ||
window.update(entry, shiftEntries.length); | ||
if (window.value() > maxClsValue) { | ||
@@ -48,4 +50,15 @@ maxClsValue = window.value(); | ||
var cslTargetSelector = void 0; | ||
if ((0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.WEB_VITALS_ATTRIBUTION) && clsTarget) { | ||
if ((0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.WEB_VITALS_ATTRIBUTION) && | ||
clsTarget && | ||
clsTarget.parentElement) { | ||
var selectorComputationStart = (0, browser_core_1.relativeNow)(); | ||
cslTargetSelector = (0, getSelectorFromElement_1.getSelectorFromElement)(clsTarget, configuration.actionNameAttribute); | ||
var selectorComputationEnd = (0, browser_core_1.relativeNow)(); | ||
if (!selectorComputationTelemetrySent) { | ||
(0, browser_core_1.addTelemetryDebug)('CLS target selector computation time', { | ||
duration: selectorComputationEnd - selectorComputationStart, | ||
selector: cslTargetSelector, | ||
}); | ||
selectorComputationTelemetrySent = true; | ||
} | ||
} | ||
@@ -65,2 +78,3 @@ callback({ | ||
exports.trackCumulativeLayoutShift = trackCumulativeLayoutShift; | ||
var maxTargetUpdateTelemetry = 5; | ||
function slidingSessionWindow() { | ||
@@ -73,4 +87,7 @@ var value = 0; | ||
var largestLayoutShiftTime; | ||
var targetUpdates = []; | ||
var maxEntriesAtOnceCount = 0; | ||
var updateCount = 0; | ||
return { | ||
update: function (entry) { | ||
update: function (entry, entriesAtOnceCount) { | ||
var _a, _b; | ||
@@ -80,7 +97,21 @@ var shouldCreateNewWindow = startTime === undefined || | ||
entry.startTime - startTime >= 5 * browser_core_1.ONE_SECOND; | ||
maxEntriesAtOnceCount = Math.max(maxEntriesAtOnceCount, entriesAtOnceCount); | ||
updateCount++; | ||
if (shouldCreateNewWindow) { | ||
startTime = endTime = entry.startTime; | ||
if (startTime !== undefined && maxTargetUpdateTelemetry) { | ||
maxTargetUpdateTelemetry--; | ||
(0, browser_core_1.addTelemetryDebug)('CLS window', { | ||
targetUpdates: targetUpdates, | ||
targetUpdatesCount: targetUpdates.length, | ||
maxEntriesAtOnceCount: maxEntriesAtOnceCount, | ||
updateCount: updateCount, | ||
}); | ||
} | ||
value = entry.value; | ||
largestLayoutShift = 0; | ||
largestLayoutShiftTarget = undefined; | ||
maxEntriesAtOnceCount = 0; | ||
updateCount = 0; | ||
targetUpdates = []; | ||
} | ||
@@ -95,2 +126,3 @@ else { | ||
if ((_a = entry.sources) === null || _a === void 0 ? void 0 : _a.length) { | ||
targetUpdates.push((0, browser_core_1.relativeNow)()); | ||
largestLayoutShiftTarget = (_b = (0, browser_core_1.find)(entry.sources, function (s) { return !!s.node && (0, htmlDomUtils_1.isElementNode)(s.node); })) === null || _b === void 0 ? void 0 : _b.node; | ||
@@ -97,0 +129,0 @@ } |
@@ -106,2 +106,5 @@ import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause, DefaultPrivacyLevel } from '@datadog/browser-core'; | ||
page_states?: PageStateServerEntry[]; | ||
configuration: { | ||
start_session_replay_recording_manually: boolean; | ||
}; | ||
}; | ||
@@ -108,0 +111,0 @@ } |
@@ -802,2 +802,12 @@ /** | ||
}; | ||
/** | ||
* Subset of the SDK configuration options in use during its execution | ||
*/ | ||
readonly configuration?: { | ||
/** | ||
* Whether session replay recording configured to start manually | ||
*/ | ||
readonly start_session_replay_recording_manually?: boolean; | ||
[k: string]: unknown; | ||
}; | ||
[k: string]: unknown; | ||
@@ -804,0 +814,0 @@ }; |
@@ -1,5 +0,6 @@ | ||
import type { Context, TelemetryEvent, Observable, RawError, PageExitEvent } from '@datadog/browser-core'; | ||
import type { Context, TelemetryEvent, Observable, RawError, PageExitEvent, Encoder } from '@datadog/browser-core'; | ||
import { DeflateEncoderStreamId } from '@datadog/browser-core'; | ||
import type { RumConfiguration } from '../domain/configuration'; | ||
import type { LifeCycle } from '../domain/lifeCycle'; | ||
export declare function startRumBatch(configuration: RumConfiguration, lifeCycle: LifeCycle, telemetryEventObservable: Observable<TelemetryEvent & Context>, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>): { | ||
export declare function startRumBatch(configuration: RumConfiguration, lifeCycle: LifeCycle, telemetryEventObservable: Observable<TelemetryEvent & Context>, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>, createEncoder: (streamId: DeflateEncoderStreamId) => Encoder): { | ||
flushObservable: Observable<import("@datadog/browser-core").FlushEvent>; | ||
@@ -6,0 +7,0 @@ add(message: Context, replicated?: boolean | undefined): void; |
@@ -5,9 +5,11 @@ "use strict"; | ||
var browser_core_1 = require("@datadog/browser-core"); | ||
function startRumBatch(configuration, lifeCycle, telemetryEventObservable, reportError, pageExitObservable, sessionExpireObservable) { | ||
function startRumBatch(configuration, lifeCycle, telemetryEventObservable, reportError, pageExitObservable, sessionExpireObservable, createEncoder) { | ||
var replica = configuration.replica; | ||
var batch = (0, browser_core_1.startBatchWithReplica)(configuration, { | ||
endpoint: configuration.rumEndpointBuilder, | ||
encoder: createEncoder(2 /* DeflateEncoderStreamId.RUM */), | ||
}, replica && { | ||
endpoint: replica.rumEndpointBuilder, | ||
transformMessage: function (message) { return (0, browser_core_1.combine)(message, { application: { id: replica.applicationId } }); }, | ||
encoder: createEncoder(3 /* DeflateEncoderStreamId.RUM_REPLICA */), | ||
}, reportError, pageExitObservable, sessionExpireObservable); | ||
@@ -14,0 +16,0 @@ lifeCycle.subscribe(11 /* LifeCycleEventType.RUM_EVENT_COLLECTED */, function (serverRumEvent) { |
@@ -1,2 +0,2 @@ | ||
import type { Context, InitConfiguration, User } from '@datadog/browser-core'; | ||
import type { Context, InitConfiguration, User, DeflateWorker, DeflateEncoderStreamId, DeflateEncoder } from '@datadog/browser-core'; | ||
import type { LifeCycle } from '../domain/lifeCycle'; | ||
@@ -14,3 +14,3 @@ import type { ViewContexts } from '../domain/contexts/viewContexts'; | ||
stop: () => void; | ||
onRumStart: (lifeCycle: LifeCycle, configuration: RumConfiguration, sessionManager: RumSessionManager, viewContexts: ViewContexts) => void; | ||
onRumStart: (lifeCycle: LifeCycle, configuration: RumConfiguration, sessionManager: RumSessionManager, viewContexts: ViewContexts, deflateWorker: DeflateWorker | undefined) => void; | ||
isRecording: () => boolean; | ||
@@ -22,4 +22,6 @@ getReplayStats: (viewId: string) => ReplayStats | undefined; | ||
ignoreInitIfSyntheticsWillInjectRum?: boolean; | ||
startDeflateWorker?: (configuration: RumConfiguration, source: string, onInitializationFailure: () => void) => DeflateWorker | undefined; | ||
createDeflateEncoder?: (configuration: RumConfiguration, worker: DeflateWorker, streamId: DeflateEncoderStreamId) => DeflateEncoder; | ||
} | ||
export declare function makeRumPublicApi(startRumImpl: StartRum, recorderApi: RecorderApi, { ignoreInitIfSyntheticsWillInjectRum }?: RumPublicApiOptions): { | ||
export declare function makeRumPublicApi(startRumImpl: StartRum, recorderApi: RecorderApi, { ignoreInitIfSyntheticsWillInjectRum, startDeflateWorker, createDeflateEncoder }?: RumPublicApiOptions): { | ||
init: (initConfiguration: RumInitConfiguration) => void; | ||
@@ -26,0 +28,0 @@ setGlobalContextProperty: (key: any, value: any) => void; |
@@ -1,2 +0,2 @@ | ||
import { noop, willSyntheticsInjectRum, assign, BoundedBuffer, createContextManager, deepClone, makePublicApi, monitor, clocksNow, timeStampNow, display, callMonitored, createHandlingStack, canUseEventBridge, checkUser, sanitizeUser, sanitize, createStoredContextManager, combine, } from '@datadog/browser-core'; | ||
import { noop, willSyntheticsInjectRum, assign, BoundedBuffer, createContextManager, deepClone, makePublicApi, monitor, clocksNow, timeStampNow, display, callMonitored, createHandlingStack, canUseEventBridge, checkUser, sanitizeUser, sanitize, createStoredContextManager, combine, isExperimentalFeatureEnabled, ExperimentalFeature, createIdentityEncoder, } from '@datadog/browser-core'; | ||
import { validateAndBuildRumConfiguration } from '../domain/configuration'; | ||
@@ -6,3 +6,3 @@ import { buildCommonContext } from '../domain/contexts/commonContext'; | ||
export function makeRumPublicApi(startRumImpl, recorderApi, _a) { | ||
var _b = _a === void 0 ? {} : _a, _c = _b.ignoreInitIfSyntheticsWillInjectRum, ignoreInitIfSyntheticsWillInjectRum = _c === void 0 ? true : _c; | ||
var _b = _a === void 0 ? {} : _a, _c = _b.ignoreInitIfSyntheticsWillInjectRum, ignoreInitIfSyntheticsWillInjectRum = _c === void 0 ? true : _c, startDeflateWorker = _b.startDeflateWorker, createDeflateEncoder = _b.createDeflateEncoder; | ||
var isAlreadyInitialized = false; | ||
@@ -41,2 +41,3 @@ var globalContextManager = createContextManager(2 /* CustomerDataType.GlobalContext */); | ||
}; | ||
var deflateWorker; | ||
function initRum(initConfiguration) { | ||
@@ -71,2 +72,14 @@ if (!initConfiguration) { | ||
} | ||
if (isExperimentalFeatureEnabled(ExperimentalFeature.COMPRESS_BATCH) && | ||
!eventBridgeAvailable && | ||
startDeflateWorker) { | ||
deflateWorker = startDeflateWorker(configuration, 'Datadog RUM', | ||
// Worker initialization can fail asynchronously, especially in Firefox where even CSP | ||
// issues are reported asynchronously. For now, the SDK will continue its execution even if | ||
// data won't be sent to Datadog. We could improve this behavior in the future. | ||
noop); | ||
if (!deflateWorker) { | ||
return; | ||
} | ||
} | ||
if (!configuration.trackViewsManually) { | ||
@@ -97,3 +110,5 @@ doStartRum(initConfiguration, configuration); | ||
} | ||
var startRumResults = startRumImpl(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions); | ||
var startRumResults = startRumImpl(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions, deflateWorker && createDeflateEncoder | ||
? function (streamId) { return createDeflateEncoder(configuration, deflateWorker, streamId); } | ||
: createIdentityEncoder); | ||
getSessionReplayLinkStrategy = function () { | ||
@@ -105,3 +120,3 @@ return recorderApi.getSessionReplayLink(configuration, startRumResults.session, startRumResults.viewContexts); | ||
(startViewStrategy = startRumResults.startView, addActionStrategy = startRumResults.addAction, addErrorStrategy = startRumResults.addError, addTimingStrategy = startRumResults.addTiming, addFeatureFlagEvaluationStrategy = startRumResults.addFeatureFlagEvaluation, getInternalContextStrategy = startRumResults.getInternalContext, stopSessionStrategy = startRumResults.stopSession); | ||
recorderApi.onRumStart(startRumResults.lifeCycle, configuration, startRumResults.session, startRumResults.viewContexts); | ||
recorderApi.onRumStart(startRumResults.lifeCycle, configuration, startRumResults.session, startRumResults.viewContexts, deflateWorker); | ||
bufferApiCalls.drain(); | ||
@@ -108,0 +123,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import type { Observable, RawError, ContextManager } from '@datadog/browser-core'; | ||
import type { Observable, RawError, ContextManager, DeflateEncoderStreamId, Encoder } from '@datadog/browser-core'; | ||
import { LifeCycle } from '../domain/lifeCycle'; | ||
@@ -9,3 +9,3 @@ import type { RumSessionManager } from '../domain/rumSessionManager'; | ||
import type { RecorderApi } from './rumPublicApi'; | ||
export declare function startRum(initConfiguration: RumInitConfiguration, configuration: RumConfiguration, recorderApi: RecorderApi, globalContextManager: ContextManager, userContextManager: ContextManager, initialViewOptions?: ViewOptions): { | ||
export declare function startRum(initConfiguration: RumInitConfiguration, configuration: RumConfiguration, recorderApi: RecorderApi, globalContextManager: ContextManager, userContextManager: ContextManager, initialViewOptions: ViewOptions | undefined, createEncoder: (streamId: DeflateEncoderStreamId) => Encoder): { | ||
addAction: (action: import("../domain/action/actionCollection").CustomAction, savedCommonContext?: CommonContext | undefined) => void; | ||
@@ -12,0 +12,0 @@ addError: ({ error, handlingStack, startClocks, context: customerContext }: import("../domain/error/errorCollection").ProvidedError, savedCommonContext?: CommonContext | undefined) => void; |
@@ -25,3 +25,3 @@ import { sendToExtension, createPageExitObservable, addTelemetryConfiguration, startTelemetry, canUseEventBridge, getEventBridge, addTelemetryDebug, } from '@datadog/browser-core'; | ||
import { startDisplayContext } from '../domain/contexts/displayContext'; | ||
export function startRum(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions) { | ||
export function startRum(initConfiguration, configuration, recorderApi, globalContextManager, userContextManager, initialViewOptions, createEncoder) { | ||
var cleanupTasks = []; | ||
@@ -60,3 +60,3 @@ var lifeCycle = new LifeCycle(); | ||
if (!canUseEventBridge()) { | ||
var batch_1 = startRumBatch(configuration, lifeCycle, telemetry.observable, reportError, pageExitObservable, session.expireObservable); | ||
var batch_1 = startRumBatch(configuration, lifeCycle, telemetry.observable, reportError, pageExitObservable, session.expireObservable, createEncoder); | ||
cleanupTasks.push(function () { return batch_1.stop(); }); | ||
@@ -63,0 +63,0 @@ startCustomerDataTelemetry(configuration, telemetry, lifeCycle, globalContextManager, userContextManager, featureFlagContexts, batch_1.flushObservable); |
@@ -54,3 +54,3 @@ import { combine, isEmptyObject, timeStampNow, currentDrift, display, createEventRateLimiter, canUseEventBridge, assign, round, } from '@datadog/browser-core'; | ||
}, | ||
browser_sdk_version: canUseEventBridge() ? "5.1.0" : undefined, | ||
browser_sdk_version: canUseEventBridge() ? "5.2.0" : undefined, | ||
}, | ||
@@ -57,0 +57,0 @@ application: { |
@@ -7,3 +7,6 @@ import { combine, generateUUID, toServerDuration, relativeToClocks, assign, isNumber, isExperimentalFeatureEnabled, ExperimentalFeature, } from '@datadog/browser-core'; | ||
lifeCycle.subscribe(6 /* LifeCycleEventType.REQUEST_COMPLETED */, function (request) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processRequest(request, configuration, sessionManager, pageStateHistory)); | ||
var rawEvent = processRequest(request, configuration, sessionManager, pageStateHistory); | ||
if (rawEvent) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, rawEvent); | ||
} | ||
}); | ||
@@ -14,3 +17,6 @@ lifeCycle.subscribe(0 /* LifeCycleEventType.PERFORMANCE_ENTRIES_COLLECTED */, function (entries) { | ||
if (entry.entryType === RumPerformanceEntryType.RESOURCE && !isRequestKind(entry)) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, processResourceEntry(entry, configuration, sessionManager, pageStateHistory)); | ||
var rawEvent = processResourceEntry(entry, configuration, sessionManager, pageStateHistory); | ||
if (rawEvent) { | ||
lifeCycle.notify(10 /* LifeCycleEventType.RAW_RUM_EVENT_COLLECTED */, rawEvent); | ||
} | ||
} | ||
@@ -22,8 +28,11 @@ } | ||
var _a; | ||
var type = request.type === "xhr" /* RequestType.XHR */ ? "xhr" /* ResourceType.XHR */ : "fetch" /* ResourceType.FETCH */; | ||
var matchingTiming = matchRequestTiming(request); | ||
var startClocks = matchingTiming ? relativeToClocks(matchingTiming.startTime) : request.startClocks; | ||
var shouldIndex = shouldIndexResource(configuration, sessionManager, startClocks); | ||
var tracingInfo = computeRequestTracingInfo(request, configuration); | ||
if (!shouldIndex && !tracingInfo) { | ||
return; | ||
} | ||
var type = request.type === "xhr" /* RequestType.XHR */ ? "xhr" /* ResourceType.XHR */ : "fetch" /* ResourceType.FETCH */; | ||
var correspondingTimingOverrides = matchingTiming ? computePerformanceEntryMetrics(matchingTiming) : undefined; | ||
var tracingInfo = computeRequestTracingInfo(request, configuration); | ||
var indexingInfo = computeIndexingInfo(configuration, sessionManager, startClocks); | ||
var duration = computeRequestDuration(pageStateHistory, startClocks, request.duration); | ||
@@ -42,3 +51,6 @@ var pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, (_a = matchingTiming === null || matchingTiming === void 0 ? void 0 : matchingTiming.duration) !== null && _a !== void 0 ? _a : request.duration); | ||
type: "resource" /* RumEventType.RESOURCE */, | ||
}, tracingInfo, correspondingTimingOverrides, indexingInfo, pageStateInfo); | ||
_dd: { | ||
discarded: !shouldIndex, | ||
}, | ||
}, tracingInfo, correspondingTimingOverrides, pageStateInfo); | ||
return { | ||
@@ -58,7 +70,10 @@ startTime: startClocks.relative, | ||
function processResourceEntry(entry, configuration, sessionManager, pageStateHistory) { | ||
var startClocks = relativeToClocks(entry.startTime); | ||
var shouldIndex = shouldIndexResource(configuration, sessionManager, startClocks); | ||
var tracingInfo = computeEntryTracingInfo(entry, configuration); | ||
if (!shouldIndex && !tracingInfo) { | ||
return; | ||
} | ||
var type = computeResourceKind(entry); | ||
var entryMetrics = computePerformanceEntryMetrics(entry); | ||
var startClocks = relativeToClocks(entry.startTime); | ||
var tracingInfo = computeEntryTracingInfo(entry, configuration); | ||
var indexingInfo = computeIndexingInfo(configuration, sessionManager, startClocks); | ||
var pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, entry.duration); | ||
@@ -73,3 +88,6 @@ var resourceEvent = combine({ | ||
type: "resource" /* RumEventType.RESOURCE */, | ||
}, tracingInfo, entryMetrics, indexingInfo, pageStateInfo); | ||
_dd: { | ||
discarded: !shouldIndex, | ||
}, | ||
}, tracingInfo, entryMetrics, pageStateInfo); | ||
return { | ||
@@ -83,2 +101,5 @@ startTime: startClocks.relative, | ||
} | ||
function shouldIndexResource(configuration, sessionManager, resourceStart) { | ||
return configuration.trackResources && sessionManager.findTrackedSession(resourceStart.relative); | ||
} | ||
function computePerformanceEntryMetrics(timing) { | ||
@@ -123,10 +144,2 @@ return { | ||
} | ||
function computeIndexingInfo(configuration, sessionManager, resourceStart) { | ||
var session = sessionManager.findTrackedSession(resourceStart.relative); | ||
return { | ||
_dd: { | ||
discarded: !session || !configuration.trackResources, | ||
}, | ||
}; | ||
} | ||
function computePageStateInfo(pageStateHistory, startClocks, duration) { | ||
@@ -133,0 +146,0 @@ if (!isExperimentalFeatureEnabled(ExperimentalFeature.RESOURCE_PAGE_STATES)) { |
@@ -19,2 +19,5 @@ import { isEmptyObject, mapValues, toServerDuration, isNumber } from '@datadog/browser-core'; | ||
page_states: pageStates, | ||
configuration: { | ||
start_session_replay_recording_manually: configuration.startSessionReplayRecordingManually, | ||
}, | ||
}, | ||
@@ -21,0 +24,0 @@ date: view.startClocks.timeStamp, |
@@ -1,2 +0,2 @@ | ||
import { round, find, ONE_SECOND, isExperimentalFeatureEnabled, ExperimentalFeature, noop, } from '@datadog/browser-core'; | ||
import { round, find, ONE_SECOND, isExperimentalFeatureEnabled, ExperimentalFeature, noop, addTelemetryDebug, relativeNow, } from '@datadog/browser-core'; | ||
import { isElementNode } from '../../../browser/htmlDomUtils'; | ||
@@ -34,7 +34,9 @@ import { supportPerformanceTimingEvent, RumPerformanceEntryType } from '../../../browser/performanceCollection'; | ||
var window = slidingSessionWindow(); | ||
var selectorComputationTelemetrySent = false; | ||
var stop = lifeCycle.subscribe(0 /* LifeCycleEventType.PERFORMANCE_ENTRIES_COLLECTED */, function (entries) { | ||
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { | ||
var entry = entries_1[_i]; | ||
var shiftEntries = entries.filter(function (e) { return e.entryType === RumPerformanceEntryType.LAYOUT_SHIFT && !e.hadRecentInput; }); | ||
for (var _i = 0, shiftEntries_1 = shiftEntries; _i < shiftEntries_1.length; _i++) { | ||
var entry = shiftEntries_1[_i]; | ||
if (entry.entryType === RumPerformanceEntryType.LAYOUT_SHIFT && !entry.hadRecentInput) { | ||
window.update(entry); | ||
window.update(entry, shiftEntries.length); | ||
if (window.value() > maxClsValue) { | ||
@@ -45,4 +47,15 @@ maxClsValue = window.value(); | ||
var cslTargetSelector = void 0; | ||
if (isExperimentalFeatureEnabled(ExperimentalFeature.WEB_VITALS_ATTRIBUTION) && clsTarget) { | ||
if (isExperimentalFeatureEnabled(ExperimentalFeature.WEB_VITALS_ATTRIBUTION) && | ||
clsTarget && | ||
clsTarget.parentElement) { | ||
var selectorComputationStart = relativeNow(); | ||
cslTargetSelector = getSelectorFromElement(clsTarget, configuration.actionNameAttribute); | ||
var selectorComputationEnd = relativeNow(); | ||
if (!selectorComputationTelemetrySent) { | ||
addTelemetryDebug('CLS target selector computation time', { | ||
duration: selectorComputationEnd - selectorComputationStart, | ||
selector: cslTargetSelector, | ||
}); | ||
selectorComputationTelemetrySent = true; | ||
} | ||
} | ||
@@ -61,2 +74,3 @@ callback({ | ||
} | ||
var maxTargetUpdateTelemetry = 5; | ||
function slidingSessionWindow() { | ||
@@ -69,4 +83,7 @@ var value = 0; | ||
var largestLayoutShiftTime; | ||
var targetUpdates = []; | ||
var maxEntriesAtOnceCount = 0; | ||
var updateCount = 0; | ||
return { | ||
update: function (entry) { | ||
update: function (entry, entriesAtOnceCount) { | ||
var _a, _b; | ||
@@ -76,7 +93,21 @@ var shouldCreateNewWindow = startTime === undefined || | ||
entry.startTime - startTime >= 5 * ONE_SECOND; | ||
maxEntriesAtOnceCount = Math.max(maxEntriesAtOnceCount, entriesAtOnceCount); | ||
updateCount++; | ||
if (shouldCreateNewWindow) { | ||
startTime = endTime = entry.startTime; | ||
if (startTime !== undefined && maxTargetUpdateTelemetry) { | ||
maxTargetUpdateTelemetry--; | ||
addTelemetryDebug('CLS window', { | ||
targetUpdates: targetUpdates, | ||
targetUpdatesCount: targetUpdates.length, | ||
maxEntriesAtOnceCount: maxEntriesAtOnceCount, | ||
updateCount: updateCount, | ||
}); | ||
} | ||
value = entry.value; | ||
largestLayoutShift = 0; | ||
largestLayoutShiftTarget = undefined; | ||
maxEntriesAtOnceCount = 0; | ||
updateCount = 0; | ||
targetUpdates = []; | ||
} | ||
@@ -91,2 +122,3 @@ else { | ||
if ((_a = entry.sources) === null || _a === void 0 ? void 0 : _a.length) { | ||
targetUpdates.push(relativeNow()); | ||
largestLayoutShiftTarget = (_b = find(entry.sources, function (s) { return !!s.node && isElementNode(s.node); })) === null || _b === void 0 ? void 0 : _b.node; | ||
@@ -93,0 +125,0 @@ } |
@@ -106,2 +106,5 @@ import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause, DefaultPrivacyLevel } from '@datadog/browser-core'; | ||
page_states?: PageStateServerEntry[]; | ||
configuration: { | ||
start_session_replay_recording_manually: boolean; | ||
}; | ||
}; | ||
@@ -108,0 +111,0 @@ } |
@@ -802,2 +802,12 @@ /** | ||
}; | ||
/** | ||
* Subset of the SDK configuration options in use during its execution | ||
*/ | ||
readonly configuration?: { | ||
/** | ||
* Whether session replay recording configured to start manually | ||
*/ | ||
readonly start_session_replay_recording_manually?: boolean; | ||
[k: string]: unknown; | ||
}; | ||
[k: string]: unknown; | ||
@@ -804,0 +814,0 @@ }; |
@@ -1,5 +0,6 @@ | ||
import type { Context, TelemetryEvent, Observable, RawError, PageExitEvent } from '@datadog/browser-core'; | ||
import type { Context, TelemetryEvent, Observable, RawError, PageExitEvent, Encoder } from '@datadog/browser-core'; | ||
import { DeflateEncoderStreamId } from '@datadog/browser-core'; | ||
import type { RumConfiguration } from '../domain/configuration'; | ||
import type { LifeCycle } from '../domain/lifeCycle'; | ||
export declare function startRumBatch(configuration: RumConfiguration, lifeCycle: LifeCycle, telemetryEventObservable: Observable<TelemetryEvent & Context>, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>): { | ||
export declare function startRumBatch(configuration: RumConfiguration, lifeCycle: LifeCycle, telemetryEventObservable: Observable<TelemetryEvent & Context>, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>, createEncoder: (streamId: DeflateEncoderStreamId) => Encoder): { | ||
flushObservable: Observable<import("@datadog/browser-core").FlushEvent>; | ||
@@ -6,0 +7,0 @@ add(message: Context, replicated?: boolean | undefined): void; |
@@ -1,9 +0,11 @@ | ||
import { combine, isTelemetryReplicationAllowed, startBatchWithReplica } from '@datadog/browser-core'; | ||
export function startRumBatch(configuration, lifeCycle, telemetryEventObservable, reportError, pageExitObservable, sessionExpireObservable) { | ||
import { combine, isTelemetryReplicationAllowed, startBatchWithReplica, } from '@datadog/browser-core'; | ||
export function startRumBatch(configuration, lifeCycle, telemetryEventObservable, reportError, pageExitObservable, sessionExpireObservable, createEncoder) { | ||
var replica = configuration.replica; | ||
var batch = startBatchWithReplica(configuration, { | ||
endpoint: configuration.rumEndpointBuilder, | ||
encoder: createEncoder(2 /* DeflateEncoderStreamId.RUM */), | ||
}, replica && { | ||
endpoint: replica.rumEndpointBuilder, | ||
transformMessage: function (message) { return combine(message, { application: { id: replica.applicationId } }); }, | ||
encoder: createEncoder(3 /* DeflateEncoderStreamId.RUM_REPLICA */), | ||
}, reportError, pageExitObservable, sessionExpireObservable); | ||
@@ -10,0 +12,0 @@ lifeCycle.subscribe(11 /* LifeCycleEventType.RUM_EVENT_COLLECTED */, function (serverRumEvent) { |
{ | ||
"name": "@datadog/browser-rum-core", | ||
"version": "5.1.0", | ||
"version": "5.2.0", | ||
"license": "Apache-2.0", | ||
@@ -15,3 +15,3 @@ "main": "cjs/index.js", | ||
"dependencies": { | ||
"@datadog/browser-core": "5.1.0" | ||
"@datadog/browser-core": "5.2.0" | ||
}, | ||
@@ -32,3 +32,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "3a31ebae7c56ed6d68cabf3cd96391ad57be0ab3" | ||
"gitHead": "1896ddf29a7da4ea02b3d229f583d4a72d87d0a8" | ||
} |
@@ -1,2 +0,11 @@ | ||
import type { Context, InitConfiguration, TimeStamp, RelativeTime, User } from '@datadog/browser-core' | ||
import type { | ||
Context, | ||
InitConfiguration, | ||
TimeStamp, | ||
RelativeTime, | ||
User, | ||
DeflateWorker, | ||
DeflateEncoderStreamId, | ||
DeflateEncoder, | ||
} from '@datadog/browser-core' | ||
import { | ||
@@ -23,2 +32,5 @@ noop, | ||
combine, | ||
isExperimentalFeatureEnabled, | ||
ExperimentalFeature, | ||
createIdentityEncoder, | ||
} from '@datadog/browser-core' | ||
@@ -49,3 +61,4 @@ import type { LifeCycle } from '../domain/lifeCycle' | ||
sessionManager: RumSessionManager, | ||
viewContexts: ViewContexts | ||
viewContexts: ViewContexts, | ||
deflateWorker: DeflateWorker | undefined | ||
) => void | ||
@@ -62,2 +75,12 @@ isRecording: () => boolean | ||
ignoreInitIfSyntheticsWillInjectRum?: boolean | ||
startDeflateWorker?: ( | ||
configuration: RumConfiguration, | ||
source: string, | ||
onInitializationFailure: () => void | ||
) => DeflateWorker | undefined | ||
createDeflateEncoder?: ( | ||
configuration: RumConfiguration, | ||
worker: DeflateWorker, | ||
streamId: DeflateEncoderStreamId | ||
) => DeflateEncoder | ||
} | ||
@@ -70,3 +93,3 @@ | ||
recorderApi: RecorderApi, | ||
{ ignoreInitIfSyntheticsWillInjectRum = true }: RumPublicApiOptions = {} | ||
{ ignoreInitIfSyntheticsWillInjectRum = true, startDeflateWorker, createDeflateEncoder }: RumPublicApiOptions = {} | ||
) { | ||
@@ -115,2 +138,4 @@ let isAlreadyInitialized = false | ||
let deflateWorker: DeflateWorker | undefined | ||
function initRum(initConfiguration: RumInitConfiguration) { | ||
@@ -151,2 +176,20 @@ if (!initConfiguration) { | ||
if ( | ||
isExperimentalFeatureEnabled(ExperimentalFeature.COMPRESS_BATCH) && | ||
!eventBridgeAvailable && | ||
startDeflateWorker | ||
) { | ||
deflateWorker = startDeflateWorker( | ||
configuration, | ||
'Datadog RUM', | ||
// Worker initialization can fail asynchronously, especially in Firefox where even CSP | ||
// issues are reported asynchronously. For now, the SDK will continue its execution even if | ||
// data won't be sent to Datadog. We could improve this behavior in the future. | ||
noop | ||
) | ||
if (!deflateWorker) { | ||
return | ||
} | ||
} | ||
if (!configuration.trackViewsManually) { | ||
@@ -191,3 +234,6 @@ doStartRum(initConfiguration, configuration) | ||
userContextManager, | ||
initialViewOptions | ||
initialViewOptions, | ||
deflateWorker && createDeflateEncoder | ||
? (streamId) => createDeflateEncoder(configuration, deflateWorker!, streamId) | ||
: createIdentityEncoder | ||
) | ||
@@ -212,3 +258,4 @@ getSessionReplayLinkStrategy = () => | ||
startRumResults.session, | ||
startRumResults.viewContexts | ||
startRumResults.viewContexts, | ||
deflateWorker | ||
) | ||
@@ -215,0 +262,0 @@ bufferApiCalls.drain() |
@@ -1,2 +0,9 @@ | ||
import type { Observable, TelemetryEvent, RawError, ContextManager } from '@datadog/browser-core' | ||
import type { | ||
Observable, | ||
TelemetryEvent, | ||
RawError, | ||
ContextManager, | ||
DeflateEncoderStreamId, | ||
Encoder, | ||
} from '@datadog/browser-core' | ||
import { | ||
@@ -48,3 +55,4 @@ sendToExtension, | ||
userContextManager: ContextManager, | ||
initialViewOptions?: ViewOptions | ||
initialViewOptions: ViewOptions | undefined, | ||
createEncoder: (streamId: DeflateEncoderStreamId) => Encoder | ||
) { | ||
@@ -92,3 +100,4 @@ const cleanupTasks: Array<() => void> = [] | ||
pageExitObservable, | ||
session.expireObservable | ||
session.expireObservable, | ||
createEncoder | ||
) | ||
@@ -95,0 +104,0 @@ cleanupTasks.push(() => batch.stop()) |
@@ -42,6 +42,6 @@ import { | ||
lifeCycle.subscribe(LifeCycleEventType.REQUEST_COMPLETED, (request: RequestCompleteEvent) => { | ||
lifeCycle.notify( | ||
LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, | ||
processRequest(request, configuration, sessionManager, pageStateHistory) | ||
) | ||
const rawEvent = processRequest(request, configuration, sessionManager, pageStateHistory) | ||
if (rawEvent) { | ||
lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, rawEvent) | ||
} | ||
}) | ||
@@ -52,6 +52,6 @@ | ||
if (entry.entryType === RumPerformanceEntryType.RESOURCE && !isRequestKind(entry)) { | ||
lifeCycle.notify( | ||
LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, | ||
processResourceEntry(entry, configuration, sessionManager, pageStateHistory) | ||
) | ||
const rawEvent = processResourceEntry(entry, configuration, sessionManager, pageStateHistory) | ||
if (rawEvent) { | ||
lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, rawEvent) | ||
} | ||
} | ||
@@ -67,12 +67,15 @@ } | ||
pageStateHistory: PageStateHistory | ||
): RawRumEventCollectedData<RawRumResourceEvent> { | ||
): RawRumEventCollectedData<RawRumResourceEvent> | undefined { | ||
const matchingTiming = matchRequestTiming(request) | ||
const startClocks = matchingTiming ? relativeToClocks(matchingTiming.startTime) : request.startClocks | ||
const shouldIndex = shouldIndexResource(configuration, sessionManager, startClocks) | ||
const tracingInfo = computeRequestTracingInfo(request, configuration) | ||
if (!shouldIndex && !tracingInfo) { | ||
return | ||
} | ||
const type = request.type === RequestType.XHR ? ResourceType.XHR : ResourceType.FETCH | ||
const matchingTiming = matchRequestTiming(request) | ||
const startClocks = matchingTiming ? relativeToClocks(matchingTiming.startTime) : request.startClocks | ||
const correspondingTimingOverrides = matchingTiming ? computePerformanceEntryMetrics(matchingTiming) : undefined | ||
const tracingInfo = computeRequestTracingInfo(request, configuration) | ||
const indexingInfo = computeIndexingInfo(configuration, sessionManager, startClocks) | ||
const duration = computeRequestDuration(pageStateHistory, startClocks, request.duration) | ||
@@ -97,6 +100,8 @@ const pageStateInfo = computePageStateInfo( | ||
type: RumEventType.RESOURCE as const, | ||
_dd: { | ||
discarded: !shouldIndex, | ||
}, | ||
}, | ||
tracingInfo, | ||
correspondingTimingOverrides, | ||
indexingInfo, | ||
pageStateInfo | ||
@@ -124,9 +129,13 @@ ) | ||
pageStateHistory: PageStateHistory | ||
): RawRumEventCollectedData<RawRumResourceEvent> { | ||
): RawRumEventCollectedData<RawRumResourceEvent> | undefined { | ||
const startClocks = relativeToClocks(entry.startTime) | ||
const shouldIndex = shouldIndexResource(configuration, sessionManager, startClocks) | ||
const tracingInfo = computeEntryTracingInfo(entry, configuration) | ||
if (!shouldIndex && !tracingInfo) { | ||
return | ||
} | ||
const type = computeResourceKind(entry) | ||
const entryMetrics = computePerformanceEntryMetrics(entry) | ||
const startClocks = relativeToClocks(entry.startTime) | ||
const tracingInfo = computeEntryTracingInfo(entry, configuration) | ||
const indexingInfo = computeIndexingInfo(configuration, sessionManager, startClocks) | ||
const pageStateInfo = computePageStateInfo(pageStateHistory, startClocks, entry.duration) | ||
@@ -143,6 +152,8 @@ | ||
type: RumEventType.RESOURCE as const, | ||
_dd: { | ||
discarded: !shouldIndex, | ||
}, | ||
}, | ||
tracingInfo, | ||
entryMetrics, | ||
indexingInfo, | ||
pageStateInfo | ||
@@ -159,2 +170,10 @@ ) | ||
function shouldIndexResource( | ||
configuration: RumConfiguration, | ||
sessionManager: RumSessionManager, | ||
resourceStart: ClocksState | ||
) { | ||
return configuration.trackResources && sessionManager.findTrackedSession(resourceStart.relative) | ||
} | ||
function computePerformanceEntryMetrics(timing: RumPerformanceResourceTiming) { | ||
@@ -206,15 +225,2 @@ return { | ||
function computeIndexingInfo( | ||
configuration: RumConfiguration, | ||
sessionManager: RumSessionManager, | ||
resourceStart: ClocksState | ||
) { | ||
const session = sessionManager.findTrackedSession(resourceStart.relative) | ||
return { | ||
_dd: { | ||
discarded: !session || !configuration.trackResources, | ||
}, | ||
} | ||
} | ||
function computePageStateInfo(pageStateHistory: PageStateHistory, startClocks: ClocksState, duration: Duration) { | ||
@@ -221,0 +227,0 @@ if (!isExperimentalFeatureEnabled(ExperimentalFeature.RESOURCE_PAGE_STATES)) { |
@@ -58,2 +58,5 @@ import type { Duration, ServerDuration, Observable } from '@datadog/browser-core' | ||
page_states: pageStates, | ||
configuration: { | ||
start_session_replay_recording_manually: configuration.startSessionReplayRecordingManually, | ||
}, | ||
}, | ||
@@ -60,0 +63,0 @@ date: view.startClocks.timeStamp, |
@@ -9,2 +9,4 @@ import { | ||
noop, | ||
addTelemetryDebug, | ||
relativeNow, | ||
} from '@datadog/browser-core' | ||
@@ -60,7 +62,10 @@ import { isElementNode } from '../../../browser/htmlDomUtils' | ||
const window = slidingSessionWindow() | ||
let selectorComputationTelemetrySent = false | ||
const { unsubscribe: stop } = lifeCycle.subscribe(LifeCycleEventType.PERFORMANCE_ENTRIES_COLLECTED, (entries) => { | ||
for (const entry of entries) { | ||
const shiftEntries = entries.filter( | ||
(e) => e.entryType === RumPerformanceEntryType.LAYOUT_SHIFT && !e.hadRecentInput | ||
) | ||
for (const entry of shiftEntries) { | ||
if (entry.entryType === RumPerformanceEntryType.LAYOUT_SHIFT && !entry.hadRecentInput) { | ||
window.update(entry) | ||
window.update(entry, shiftEntries.length) | ||
@@ -73,4 +78,18 @@ if (window.value() > maxClsValue) { | ||
if (isExperimentalFeatureEnabled(ExperimentalFeature.WEB_VITALS_ATTRIBUTION) && clsTarget) { | ||
if ( | ||
isExperimentalFeatureEnabled(ExperimentalFeature.WEB_VITALS_ATTRIBUTION) && | ||
clsTarget && | ||
clsTarget.parentElement | ||
) { | ||
const selectorComputationStart = relativeNow() | ||
cslTargetSelector = getSelectorFromElement(clsTarget, configuration.actionNameAttribute) | ||
const selectorComputationEnd = relativeNow() | ||
if (!selectorComputationTelemetrySent) { | ||
addTelemetryDebug('CLS target selector computation time', { | ||
duration: selectorComputationEnd - selectorComputationStart, | ||
selector: cslTargetSelector, | ||
}) | ||
selectorComputationTelemetrySent = true | ||
} | ||
} | ||
@@ -92,2 +111,4 @@ | ||
let maxTargetUpdateTelemetry = 5 | ||
function slidingSessionWindow() { | ||
@@ -101,5 +122,7 @@ let value = 0 | ||
let largestLayoutShiftTime: RelativeTime | ||
let targetUpdates: RelativeTime[] = [] | ||
let maxEntriesAtOnceCount = 0 | ||
let updateCount = 0 | ||
return { | ||
update: (entry: RumLayoutShiftTiming) => { | ||
update: (entry: RumLayoutShiftTiming, entriesAtOnceCount: number) => { | ||
const shouldCreateNewWindow = | ||
@@ -109,7 +132,22 @@ startTime === undefined || | ||
entry.startTime - startTime >= 5 * ONE_SECOND | ||
maxEntriesAtOnceCount = Math.max(maxEntriesAtOnceCount, entriesAtOnceCount) | ||
updateCount++ | ||
if (shouldCreateNewWindow) { | ||
startTime = endTime = entry.startTime | ||
if (startTime !== undefined && maxTargetUpdateTelemetry) { | ||
maxTargetUpdateTelemetry-- | ||
addTelemetryDebug('CLS window', { | ||
targetUpdates, | ||
targetUpdatesCount: targetUpdates.length, | ||
maxEntriesAtOnceCount, | ||
updateCount, | ||
}) | ||
} | ||
value = entry.value | ||
largestLayoutShift = 0 | ||
largestLayoutShiftTarget = undefined | ||
maxEntriesAtOnceCount = 0 | ||
updateCount = 0 | ||
targetUpdates = [] | ||
} else { | ||
@@ -123,4 +161,4 @@ value += entry.value | ||
largestLayoutShiftTime = entry.startTime | ||
if (entry.sources?.length) { | ||
targetUpdates.push(relativeNow()) | ||
largestLayoutShiftTarget = find( | ||
@@ -127,0 +165,0 @@ entry.sources, |
@@ -122,2 +122,5 @@ import type { | ||
page_states?: PageStateServerEntry[] | ||
configuration: { | ||
start_session_replay_recording_manually: boolean | ||
} | ||
} | ||
@@ -124,0 +127,0 @@ } |
@@ -859,2 +859,12 @@ /* eslint-disable */ | ||
} | ||
/** | ||
* Subset of the SDK configuration options in use during its execution | ||
*/ | ||
readonly configuration?: { | ||
/** | ||
* Whether session replay recording configured to start manually | ||
*/ | ||
readonly start_session_replay_recording_manually?: boolean | ||
[k: string]: unknown | ||
} | ||
[k: string]: unknown | ||
@@ -861,0 +871,0 @@ } |
@@ -1,3 +0,8 @@ | ||
import type { Context, TelemetryEvent, Observable, RawError, PageExitEvent } from '@datadog/browser-core' | ||
import { combine, isTelemetryReplicationAllowed, startBatchWithReplica } from '@datadog/browser-core' | ||
import type { Context, TelemetryEvent, Observable, RawError, PageExitEvent, Encoder } from '@datadog/browser-core' | ||
import { | ||
DeflateEncoderStreamId, | ||
combine, | ||
isTelemetryReplicationAllowed, | ||
startBatchWithReplica, | ||
} from '@datadog/browser-core' | ||
import type { RumConfiguration } from '../domain/configuration' | ||
@@ -15,3 +20,4 @@ import type { LifeCycle } from '../domain/lifeCycle' | ||
pageExitObservable: Observable<PageExitEvent>, | ||
sessionExpireObservable: Observable<void> | ||
sessionExpireObservable: Observable<void>, | ||
createEncoder: (streamId: DeflateEncoderStreamId) => Encoder | ||
) { | ||
@@ -24,2 +30,3 @@ const replica = configuration.replica | ||
endpoint: configuration.rumEndpointBuilder, | ||
encoder: createEncoder(DeflateEncoderStreamId.RUM), | ||
}, | ||
@@ -29,2 +36,3 @@ replica && { | ||
transformMessage: (message) => combine(message, { application: { id: replica.applicationId } }), | ||
encoder: createEncoder(DeflateEncoderStreamId.RUM_REPLICA), | ||
}, | ||
@@ -31,0 +39,0 @@ reportError, |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1192917
21817
+ Added@datadog/browser-core@5.2.0(transitive)
- Removed@datadog/browser-core@5.1.0(transitive)
Updated@datadog/browser-core@5.2.0