Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

@datadog/browser-rum-core

Package Overview
Dependencies
Maintainers
1
Versions
179
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.25.0 to 4.26.0

2

cjs/domain/assembly.js

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

},
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "4.25.0" : undefined,
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "4.26.0" : undefined,
},

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

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

import type { Duration, XhrCompleteContext, XhrStartContext, ClocksState, FetchStartContext, FetchCompleteContext } from '@datadog/browser-core';
import type { Duration, XhrCompleteContext, XhrStartContext, ClocksState, FetchStartContext, FetchResolveContext } from '@datadog/browser-core';
import { RequestType } from '@datadog/browser-core';

@@ -15,3 +15,3 @@ import type { RumSessionManager } from '..';

}
export interface RumFetchCompleteContext extends FetchCompleteContext, CustomContext {
export interface RumFetchResolveContext extends FetchResolveContext, CustomContext {
}

@@ -34,2 +34,3 @@ export interface RumXhrStartContext extends XhrStartContext, CustomContext {

startClocks: ClocksState;
resolveDuration?: Duration;
duration: Duration;

@@ -36,0 +37,0 @@ spanId?: TraceIdentifier;

@@ -65,19 +65,22 @@ "use strict";

break;
case 'complete':
tracer.clearTracingIfNeeded(context);
lifeCycle.notify(6 /* REQUEST_COMPLETED */, {
duration: context.duration,
method: context.method,
requestIndex: context.requestIndex,
responseType: context.responseType,
spanId: context.spanId,
startClocks: context.startClocks,
status: context.status,
traceId: context.traceId,
traceSampled: context.traceSampled,
type: "fetch" /* FETCH */,
url: context.url,
response: context.response,
init: context.init,
input: context.input,
case 'resolve':
waitForResponseToComplete(context, function (duration) {
tracer.clearTracingIfNeeded(context);
lifeCycle.notify(6 /* REQUEST_COMPLETED */, {
resolveDuration: context.resolveDuration,
duration: duration,
method: context.method,
requestIndex: context.requestIndex,
responseType: context.responseType,
spanId: context.spanId,
startClocks: context.startClocks,
status: context.status,
traceId: context.traceId,
traceSampled: context.traceSampled,
type: "fetch" /* FETCH */,
url: context.url,
response: context.response,
init: context.init,
input: context.input,
});
});

@@ -95,2 +98,17 @@ break;

}
function waitForResponseToComplete(context, callback) {
if (context.response && (0, browser_core_1.isExperimentalFeatureEnabled)('fetch_duration')) {
var responseClone = context.response.clone();
if (responseClone.body) {
(0, browser_core_1.readBytesFromStream)(responseClone.body, function () {
callback((0, browser_core_1.elapsed)(context.startClocks.timeStamp, (0, browser_core_1.timeStampNow)()));
}, {
bytesLimit: Number.POSITIVE_INFINITY,
collectStreamBody: false,
});
return;
}
}
callback((0, browser_core_1.elapsed)(context.startClocks.timeStamp, (0, browser_core_1.timeStampNow)()));
}
//# sourceMappingURL=requestCollection.js.map

@@ -137,3 +137,9 @@ "use strict";

var historyEntry = history.add(id, startClocks.relative);
var eventCountsSubscription = (0, trackEventCounts_1.trackEventCounts)(lifeCycle);
var eventCountsSubscription = (0, trackEventCounts_1.trackEventCounts)({
lifeCycle: lifeCycle,
isChildEvent: function (event) {
return event.action !== undefined &&
(Array.isArray(event.action.id) ? (0, browser_core_1.includes)(event.action.id, id) : event.action.id === id);
},
});
var status = 0 /* ONGOING */;

@@ -140,0 +146,0 @@ var activityEndTime;

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

var indexingInfo = computeIndexingInfo(sessionManager, startClocks);
var responseDurationInfo = computeResponseDurationInfo(request);
var resourceEvent = (0, browser_core_1.combine)({

@@ -40,3 +41,3 @@ date: startClocks.timeStamp,

type: "resource" /* RESOURCE */,
}, tracingInfo, correspondingTimingOverrides, indexingInfo);
}, tracingInfo, correspondingTimingOverrides, indexingInfo, responseDurationInfo);
return {

@@ -111,2 +112,17 @@ startTime: startClocks.relative,

}
function computeResponseDurationInfo(request) {
var durationDiff;
var durationPercentageDiff;
if (request.resolveDuration) {
durationDiff = (0, browser_core_1.toServerDuration)((request.duration - request.resolveDuration));
durationPercentageDiff = Math.round((durationDiff / (0, browser_core_1.toServerDuration)(request.duration)) * 100);
}
return {
_dd: {
resolveDuration: (0, browser_core_1.toServerDuration)(request.resolveDuration),
durationDiff: durationDiff,
durationPercentageDiff: durationPercentageDiff,
},
};
}
// TODO next major: use directly PerformanceEntry type in domain context

@@ -113,0 +129,0 @@ function toPerformanceEntryRepresentation(entry) {

@@ -11,3 +11,3 @@ import type { Duration, Observable, ClocksState } from '@datadog/browser-core';

}
export declare function trackViewMetrics(lifeCycle: LifeCycle, domMutationObservable: Observable<void>, configuration: RumConfiguration, scheduleViewUpdate: () => void, loadingType: ViewLoadingType, viewStart: ClocksState): {
export declare function trackViewMetrics(lifeCycle: LifeCycle, domMutationObservable: Observable<void>, configuration: RumConfiguration, scheduleViewUpdate: () => void, viewId: string, loadingType: ViewLoadingType, viewStart: ClocksState): {
stop: () => void;

@@ -14,0 +14,0 @@ setLoadEvent: (loadEvent: Duration) => void;

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

var waitPageActivityEnd_1 = require("../../waitPageActivityEnd");
function trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, loadingType, viewStart) {
function trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, viewId, loadingType, viewStart) {
var viewMetrics = {

@@ -19,5 +19,9 @@ eventCounts: {

};
var stopEventCountsTracking = (0, trackEventCounts_1.trackEventCounts)(lifeCycle, function (newEventCounts) {
viewMetrics.eventCounts = newEventCounts;
scheduleViewUpdate();
var stopEventCountsTracking = (0, trackEventCounts_1.trackEventCounts)({
lifeCycle: lifeCycle,
isChildEvent: function (event) { return event.view.id === viewId; },
callback: function (newEventCounts) {
viewMetrics.eventCounts = newEventCounts;
scheduleViewUpdate();
},
}).stop;

@@ -24,0 +28,0 @@ var _a = trackLoadingTime(lifeCycle, domMutationObservable, configuration, loadingType, viewStart, function (newLoadingTime) {

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

}), scheduleViewUpdate = _a.throttled, cancelScheduleViewUpdate = _a.cancel;
var _b = (0, trackViewMetrics_1.trackViewMetrics)(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, loadingType, startClocks), setLoadEvent = _b.setLoadEvent, stopViewMetricsTracking = _b.stop, viewMetrics = _b.viewMetrics;
var _b = (0, trackViewMetrics_1.trackViewMetrics)(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, id, loadingType, startClocks), setLoadEvent = _b.setLoadEvent, stopViewMetricsTracking = _b.stop, viewMetrics = _b.viewMetrics;
// Initial view update

@@ -124,0 +124,0 @@ triggerViewUpdate();

import type { RumConfiguration } from '../configuration';
import type { RumFetchCompleteContext, RumFetchStartContext, RumXhrCompleteContext, RumXhrStartContext } from '../requestCollection';
import type { RumFetchResolveContext, RumFetchStartContext, RumXhrCompleteContext, RumXhrStartContext } from '../requestCollection';
import type { RumSessionManager } from '../rumSessionManager';

@@ -7,3 +7,3 @@ export interface Tracer {

traceXhr: (context: Partial<RumXhrStartContext>, xhr: XMLHttpRequest) => void;
clearTracingIfNeeded: (context: RumFetchCompleteContext | RumXhrCompleteContext) => void;
clearTracingIfNeeded: (context: RumFetchResolveContext | RumXhrCompleteContext) => void;
}

@@ -27,3 +27,3 @@ /**

* */
export declare function clearTracingIfNeeded(context: RumFetchCompleteContext | RumXhrCompleteContext): void;
export declare function clearTracingIfNeeded(context: RumFetchResolveContext | RumXhrCompleteContext): void;
export declare function startTracer(configuration: RumConfiguration, sessionManager: RumSessionManager): Tracer;

@@ -30,0 +30,0 @@ export declare function isTracingSupported(): boolean;

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

import type { RumActionEvent, RumErrorEvent, RumLongTaskEvent, RumResourceEvent } from '../rumEvent.types';
import type { LifeCycle } from './lifeCycle';

@@ -9,5 +10,9 @@ export interface EventCounts {

}
export declare function trackEventCounts(lifeCycle: LifeCycle, callback?: (eventCounts: EventCounts) => void): {
export declare function trackEventCounts({ lifeCycle, isChildEvent, callback, }: {
lifeCycle: LifeCycle;
isChildEvent: (event: RumActionEvent | RumErrorEvent | RumLongTaskEvent | RumResourceEvent) => boolean;
callback?: (eventCounts: EventCounts) => void;
}): {
stop: () => void;
eventCounts: EventCounts;
};

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

var browser_core_1 = require("@datadog/browser-core");
function trackEventCounts(lifeCycle, callback) {
if (callback === void 0) { callback = browser_core_1.noop; }
function trackEventCounts(_a) {
var lifeCycle = _a.lifeCycle, isChildEvent = _a.isChildEvent, _b = _a.callback, callback = _b === void 0 ? browser_core_1.noop : _b;
var eventCounts = {

@@ -16,2 +16,5 @@ errorCount: 0,

var subscription = lifeCycle.subscribe(11 /* RUM_EVENT_COLLECTED */, function (event) {
if (event.type === 'view' || !isChildEvent(event)) {
return;
}
switch (event.type) {

@@ -18,0 +21,0 @@ case "error" /* ERROR */:

@@ -33,2 +33,5 @@ import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause, User } from '@datadog/browser-core';

discarded: boolean;
resolveDuration?: ServerDuration;
durationDiff?: ServerDuration;
durationPercentageDiff?: number;
};

@@ -35,0 +38,0 @@ }

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

},
browser_sdk_version: canUseEventBridge() ? "4.25.0" : undefined,
browser_sdk_version: canUseEventBridge() ? "4.26.0" : undefined,
},

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

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

import type { Duration, XhrCompleteContext, XhrStartContext, ClocksState, FetchStartContext, FetchCompleteContext } from '@datadog/browser-core';
import type { Duration, XhrCompleteContext, XhrStartContext, ClocksState, FetchStartContext, FetchResolveContext } from '@datadog/browser-core';
import { RequestType } from '@datadog/browser-core';

@@ -15,3 +15,3 @@ import type { RumSessionManager } from '..';

}
export interface RumFetchCompleteContext extends FetchCompleteContext, CustomContext {
export interface RumFetchResolveContext extends FetchResolveContext, CustomContext {
}

@@ -34,2 +34,3 @@ export interface RumXhrStartContext extends XhrStartContext, CustomContext {

startClocks: ClocksState;
resolveDuration?: Duration;
duration: Duration;

@@ -36,0 +37,0 @@ spanId?: TraceIdentifier;

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

import { initFetchObservable, initXhrObservable } from '@datadog/browser-core';
import { initFetchObservable, initXhrObservable, readBytesFromStream, elapsed, timeStampNow, isExperimentalFeatureEnabled, } from '@datadog/browser-core';
import { isAllowedRequestUrl } from './rumEventsCollection/resource/resourceUtils';

@@ -60,19 +60,22 @@ import { startTracer } from './tracing/tracer';

break;
case 'complete':
tracer.clearTracingIfNeeded(context);
lifeCycle.notify(6 /* REQUEST_COMPLETED */, {
duration: context.duration,
method: context.method,
requestIndex: context.requestIndex,
responseType: context.responseType,
spanId: context.spanId,
startClocks: context.startClocks,
status: context.status,
traceId: context.traceId,
traceSampled: context.traceSampled,
type: "fetch" /* FETCH */,
url: context.url,
response: context.response,
init: context.init,
input: context.input,
case 'resolve':
waitForResponseToComplete(context, function (duration) {
tracer.clearTracingIfNeeded(context);
lifeCycle.notify(6 /* REQUEST_COMPLETED */, {
resolveDuration: context.resolveDuration,
duration: duration,
method: context.method,
requestIndex: context.requestIndex,
responseType: context.responseType,
spanId: context.spanId,
startClocks: context.startClocks,
status: context.status,
traceId: context.traceId,
traceSampled: context.traceSampled,
type: "fetch" /* FETCH */,
url: context.url,
response: context.response,
init: context.init,
input: context.input,
});
});

@@ -89,2 +92,17 @@ break;

}
function waitForResponseToComplete(context, callback) {
if (context.response && isExperimentalFeatureEnabled('fetch_duration')) {
var responseClone = context.response.clone();
if (responseClone.body) {
readBytesFromStream(responseClone.body, function () {
callback(elapsed(context.startClocks.timeStamp, timeStampNow()));
}, {
bytesLimit: Number.POSITIVE_INFINITY,
collectStreamBody: false,
});
return;
}
}
callback(elapsed(context.startClocks.timeStamp, timeStampNow()));
}
//# sourceMappingURL=requestCollection.js.map

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

import { timeStampNow, isExperimentalFeatureEnabled, Observable, assign, getRelativeTime, ONE_MINUTE, ContextHistory, generateUUID, clocksNow, ONE_SECOND, elapsed, } from '@datadog/browser-core';
import { includes, timeStampNow, isExperimentalFeatureEnabled, Observable, assign, getRelativeTime, ONE_MINUTE, ContextHistory, generateUUID, clocksNow, ONE_SECOND, elapsed, } from '@datadog/browser-core';
import { trackEventCounts } from '../../trackEventCounts';

@@ -133,3 +133,9 @@ import { waitPageActivityEnd } from '../../waitPageActivityEnd';

var historyEntry = history.add(id, startClocks.relative);
var eventCountsSubscription = trackEventCounts(lifeCycle);
var eventCountsSubscription = trackEventCounts({
lifeCycle: lifeCycle,
isChildEvent: function (event) {
return event.action !== undefined &&
(Array.isArray(event.action.id) ? includes(event.action.id, id) : event.action.id === id);
},
});
var status = 0 /* ONGOING */;

@@ -136,0 +142,0 @@ var activityEndTime;

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

var indexingInfo = computeIndexingInfo(sessionManager, startClocks);
var responseDurationInfo = computeResponseDurationInfo(request);
var resourceEvent = combine({

@@ -36,3 +37,3 @@ date: startClocks.timeStamp,

type: "resource" /* RESOURCE */,
}, tracingInfo, correspondingTimingOverrides, indexingInfo);
}, tracingInfo, correspondingTimingOverrides, indexingInfo, responseDurationInfo);
return {

@@ -107,2 +108,17 @@ startTime: startClocks.relative,

}
function computeResponseDurationInfo(request) {
var durationDiff;
var durationPercentageDiff;
if (request.resolveDuration) {
durationDiff = toServerDuration((request.duration - request.resolveDuration));
durationPercentageDiff = Math.round((durationDiff / toServerDuration(request.duration)) * 100);
}
return {
_dd: {
resolveDuration: toServerDuration(request.resolveDuration),
durationDiff: durationDiff,
durationPercentageDiff: durationPercentageDiff,
},
};
}
// TODO next major: use directly PerformanceEntry type in domain context

@@ -109,0 +125,0 @@ function toPerformanceEntryRepresentation(entry) {

@@ -11,3 +11,3 @@ import type { Duration, Observable, ClocksState } from '@datadog/browser-core';

}
export declare function trackViewMetrics(lifeCycle: LifeCycle, domMutationObservable: Observable<void>, configuration: RumConfiguration, scheduleViewUpdate: () => void, loadingType: ViewLoadingType, viewStart: ClocksState): {
export declare function trackViewMetrics(lifeCycle: LifeCycle, domMutationObservable: Observable<void>, configuration: RumConfiguration, scheduleViewUpdate: () => void, viewId: string, loadingType: ViewLoadingType, viewStart: ClocksState): {
stop: () => void;

@@ -14,0 +14,0 @@ setLoadEvent: (loadEvent: Duration) => void;

@@ -5,3 +5,3 @@ import { noop, round, ONE_SECOND, elapsed } from '@datadog/browser-core';

import { waitPageActivityEnd } from '../../waitPageActivityEnd';
export function trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, loadingType, viewStart) {
export function trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, viewId, loadingType, viewStart) {
var viewMetrics = {

@@ -16,5 +16,9 @@ eventCounts: {

};
var stopEventCountsTracking = trackEventCounts(lifeCycle, function (newEventCounts) {
viewMetrics.eventCounts = newEventCounts;
scheduleViewUpdate();
var stopEventCountsTracking = trackEventCounts({
lifeCycle: lifeCycle,
isChildEvent: function (event) { return event.view.id === viewId; },
callback: function (newEventCounts) {
viewMetrics.eventCounts = newEventCounts;
scheduleViewUpdate();
},
}).stop;

@@ -21,0 +25,0 @@ var _a = trackLoadingTime(lifeCycle, domMutationObservable, configuration, loadingType, viewStart, function (newLoadingTime) {

@@ -117,3 +117,3 @@ import { isExperimentalFeatureEnabled, shallowClone, assign, elapsed, generateUUID, monitor, ONE_MINUTE, throttle, clocksNow, clocksOrigin, timeStampNow, display, looksLikeRelativeTime, } from '@datadog/browser-core';

}), scheduleViewUpdate = _a.throttled, cancelScheduleViewUpdate = _a.cancel;
var _b = trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, loadingType, startClocks), setLoadEvent = _b.setLoadEvent, stopViewMetricsTracking = _b.stop, viewMetrics = _b.viewMetrics;
var _b = trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, id, loadingType, startClocks), setLoadEvent = _b.setLoadEvent, stopViewMetricsTracking = _b.stop, viewMetrics = _b.viewMetrics;
// Initial view update

@@ -120,0 +120,0 @@ triggerViewUpdate();

import type { RumConfiguration } from '../configuration';
import type { RumFetchCompleteContext, RumFetchStartContext, RumXhrCompleteContext, RumXhrStartContext } from '../requestCollection';
import type { RumFetchResolveContext, RumFetchStartContext, RumXhrCompleteContext, RumXhrStartContext } from '../requestCollection';
import type { RumSessionManager } from '../rumSessionManager';

@@ -7,3 +7,3 @@ export interface Tracer {

traceXhr: (context: Partial<RumXhrStartContext>, xhr: XMLHttpRequest) => void;
clearTracingIfNeeded: (context: RumFetchCompleteContext | RumXhrCompleteContext) => void;
clearTracingIfNeeded: (context: RumFetchResolveContext | RumXhrCompleteContext) => void;
}

@@ -27,3 +27,3 @@ /**

* */
export declare function clearTracingIfNeeded(context: RumFetchCompleteContext | RumXhrCompleteContext): void;
export declare function clearTracingIfNeeded(context: RumFetchResolveContext | RumXhrCompleteContext): void;
export declare function startTracer(configuration: RumConfiguration, sessionManager: RumSessionManager): Tracer;

@@ -30,0 +30,0 @@ export declare function isTracingSupported(): boolean;

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

import type { RumActionEvent, RumErrorEvent, RumLongTaskEvent, RumResourceEvent } from '../rumEvent.types';
import type { LifeCycle } from './lifeCycle';

@@ -9,5 +10,9 @@ export interface EventCounts {

}
export declare function trackEventCounts(lifeCycle: LifeCycle, callback?: (eventCounts: EventCounts) => void): {
export declare function trackEventCounts({ lifeCycle, isChildEvent, callback, }: {
lifeCycle: LifeCycle;
isChildEvent: (event: RumActionEvent | RumErrorEvent | RumLongTaskEvent | RumResourceEvent) => boolean;
callback?: (eventCounts: EventCounts) => void;
}): {
stop: () => void;
eventCounts: EventCounts;
};
import { noop } from '@datadog/browser-core';
export function trackEventCounts(lifeCycle, callback) {
if (callback === void 0) { callback = noop; }
export function trackEventCounts(_a) {
var lifeCycle = _a.lifeCycle, isChildEvent = _a.isChildEvent, _b = _a.callback, callback = _b === void 0 ? noop : _b;
var eventCounts = {

@@ -12,2 +12,5 @@ errorCount: 0,

var subscription = lifeCycle.subscribe(11 /* RUM_EVENT_COLLECTED */, function (event) {
if (event.type === 'view' || !isChildEvent(event)) {
return;
}
switch (event.type) {

@@ -14,0 +17,0 @@ case "error" /* ERROR */:

@@ -33,2 +33,5 @@ import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause, User } from '@datadog/browser-core';

discarded: boolean;
resolveDuration?: ServerDuration;
durationDiff?: ServerDuration;
durationPercentageDiff?: number;
};

@@ -35,0 +38,0 @@ }

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

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

"dependencies": {
"@datadog/browser-core": "4.25.0"
"@datadog/browser-core": "4.26.0"
},

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

},
"gitHead": "f66e5c81ad28c86a74ecd319cc10290e875442e9"
"gitHead": "d00b17d0484fee1a1e880987aa314a113dff0da6"
}

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

import { isIE, RequestType } from '@datadog/browser-core'
import { isIE, RequestType, updateExperimentalFeatures, resetExperimentalFeatures } from '@datadog/browser-core'
import type { FetchStub, FetchStubManager } from '../../../core/test/specHelper'

@@ -94,3 +94,3 @@ import { SPEC_ENDPOINTS, stubFetch, stubXhr, withXhr } from '../../../core/test/specHelper'

it('should ignore intake requests', (done) => {
fetchStub(SPEC_ENDPOINTS.rumEndpointBuilder.build()).resolveWith({ status: 200, responseText: 'foo' })
fetchStub(SPEC_ENDPOINTS.rumEndpointBuilder.build('xhr')).resolveWith({ status: 200, responseText: 'foo' })

@@ -104,2 +104,29 @@ fetchStubManager.whenAllComplete(() => {

describe('with feature flag fetch_duration', () => {
beforeEach(() => updateExperimentalFeatures(['fetch_duration']))
afterEach(() => resetExperimentalFeatures())
it('should notify when response is defined', (done) => {
fetchStub(FAKE_URL).resolveWith({ status: 200, responseText: 'ok' })
fetchStubManager.whenAllComplete(() => {
expect(startSpy).toHaveBeenCalled()
expect(completeSpy).toHaveBeenCalled()
done()
})
})
it('should notify when response is undefined', (done) => {
updateExperimentalFeatures(['fetch_duration'])
fetchStub(FAKE_URL).rejectWith(new Error('some fetch error'))
fetchStubManager.whenAllComplete(() => {
expect(startSpy).toHaveBeenCalled()
expect(completeSpy).toHaveBeenCalled()
done()
})
})
})
describe('tracing', () => {

@@ -235,3 +262,3 @@ it('should trace requests by default', (done) => {

setup(xhr) {
xhr.open('GET', SPEC_ENDPOINTS.rumEndpointBuilder.build())
xhr.open('GET', SPEC_ENDPOINTS.rumEndpointBuilder.build('xhr'))
xhr.send()

@@ -238,0 +265,0 @@ xhr.complete(200)

@@ -7,5 +7,13 @@ import type {

FetchStartContext,
FetchCompleteContext,
FetchResolveContext,
} from '@datadog/browser-core'
import { RequestType, initFetchObservable, initXhrObservable } from '@datadog/browser-core'
import {
RequestType,
initFetchObservable,
initXhrObservable,
readBytesFromStream,
elapsed,
timeStampNow,
isExperimentalFeatureEnabled,
} from '@datadog/browser-core'
import type { RumSessionManager } from '..'

@@ -26,3 +34,3 @@ import type { RumConfiguration } from './configuration'

export interface RumFetchStartContext extends FetchStartContext, CustomContext {}
export interface RumFetchCompleteContext extends FetchCompleteContext, CustomContext {}
export interface RumFetchResolveContext extends FetchResolveContext, CustomContext {}
export interface RumXhrStartContext extends XhrStartContext, CustomContext {}

@@ -35,3 +43,2 @@ export interface RumXhrCompleteContext extends XhrCompleteContext, CustomContext {}

}
export interface RequestCompleteEvent {

@@ -45,2 +52,3 @@ requestIndex: number

startClocks: ClocksState
resolveDuration?: Duration
duration: Duration

@@ -110,3 +118,3 @@ spanId?: TraceIdentifier

const subscription = initFetchObservable().subscribe((rawContext) => {
const context = rawContext as RumFetchCompleteContext | RumFetchStartContext
const context = rawContext as RumFetchResolveContext | RumFetchStartContext
if (!isAllowedRequestUrl(configuration, context.url)) {

@@ -126,20 +134,22 @@ return

break
case 'complete':
tracer.clearTracingIfNeeded(context)
lifeCycle.notify(LifeCycleEventType.REQUEST_COMPLETED, {
duration: context.duration,
method: context.method,
requestIndex: context.requestIndex,
responseType: context.responseType,
spanId: context.spanId,
startClocks: context.startClocks,
status: context.status,
traceId: context.traceId,
traceSampled: context.traceSampled,
type: RequestType.FETCH,
url: context.url,
response: context.response,
init: context.init,
input: context.input,
case 'resolve':
waitForResponseToComplete(context, (duration: Duration) => {
tracer.clearTracingIfNeeded(context)
lifeCycle.notify(LifeCycleEventType.REQUEST_COMPLETED, {
resolveDuration: context.resolveDuration,
duration,
method: context.method,
requestIndex: context.requestIndex,
responseType: context.responseType,
spanId: context.spanId,
startClocks: context.startClocks,
status: context.status,
traceId: context.traceId,
traceSampled: context.traceSampled,
type: RequestType.FETCH,
url: context.url,
response: context.response,
init: context.init,
input: context.input,
})
})

@@ -157,1 +167,21 @@ break

}
function waitForResponseToComplete(context: RumFetchResolveContext, callback: (duration: Duration) => void) {
if (context.response && isExperimentalFeatureEnabled('fetch_duration')) {
const responseClone = context.response.clone()
if (responseClone.body) {
readBytesFromStream(
responseClone.body,
() => {
callback(elapsed(context.startClocks.timeStamp, timeStampNow()))
},
{
bytesLimit: Number.POSITIVE_INFINITY,
collectStreamBody: false,
}
)
return
}
}
callback(elapsed(context.startClocks.timeStamp, timeStampNow()))
}

@@ -44,4 +44,2 @@ import type { Context, Observable, Duration } from '@datadog/browser-core'

const RAW_ERROR_EVENT = { type: RumEventType.ERROR } as RumEvent & Context
describe('trackClickActions', () => {

@@ -159,9 +157,9 @@ const { events, pushEvent } = eventsCollector<ClickAction>()

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())
clock.tick(BEFORE_PAGE_ACTIVITY_VALIDATION_DELAY)
domMutationObservable.notify()
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())
clock.tick(EXPIRE_DELAY)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())

@@ -177,2 +175,19 @@ expect(events.length).toBe(1)

it('does not count child events unrelated to the click action', () => {
const { lifeCycle, domMutationObservable, clock } = setupBuilder.build()
emulateClickWithActivity(domMutationObservable, clock)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
action: { id: 'unrelated-action-id' },
} as RumEvent & Context)
clock.tick(EXPIRE_DELAY)
expect(events.length).toBe(1)
const clickAction = events[0]
expect(clickAction.counts.resourceCount).toBe(0)
})
it('should take the name from user-configured attribute', () => {

@@ -250,3 +265,3 @@ const { domMutationObservable, clock } = setupBuilder

emulateClickWithActivity(domMutationObservable, clock)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())

@@ -370,3 +385,3 @@ clock.tick(EXPIRE_DELAY)

emulateClickWithActivity(domMutationObservable, clock)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())
clock.tick(PAGE_ACTIVITY_VALIDATION_DELAY)

@@ -394,3 +409,3 @@

emulateClickWithActivity(domMutationObservable, clock)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())

@@ -406,3 +421,3 @@ clock.tick(EXPIRE_DELAY)

emulateClickWithoutActivity(clock)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, RAW_ERROR_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeErrorEvent())

@@ -459,2 +474,6 @@ clock.tick(EXPIRE_DELAY)

}
function createFakeErrorEvent() {
return { type: RumEventType.ERROR, action: { id: findActionId() } } as RumEvent & Context
}
})

@@ -461,0 +480,0 @@

import type { Duration, ClocksState, RelativeTime, TimeStamp } from '@datadog/browser-core'
import {
includes,
timeStampNow,

@@ -255,3 +256,8 @@ isExperimentalFeatureEnabled,

const historyEntry = history.add(id, startClocks.relative)
const eventCountsSubscription = trackEventCounts(lifeCycle)
const eventCountsSubscription = trackEventCounts({
lifeCycle,
isChildEvent: (event) =>
event.action !== undefined &&
(Array.isArray(event.action.id) ? includes(event.action.id, id) : event.action.id === id),
})
let status = ClickStatus.ONGOING

@@ -258,0 +264,0 @@ let activityEndTime: undefined | TimeStamp

@@ -91,2 +91,5 @@ import type { Duration, RelativeTime, ServerDuration, TimeStamp } from '@datadog/browser-core'

discarded: false,
resolveDuration: undefined,
durationDiff: undefined,
durationPercentageDiff: undefined,
},

@@ -114,2 +117,3 @@ })

duration: 100 as Duration,
resolveDuration: 50 as Duration,
method: 'GET',

@@ -140,2 +144,5 @@ startClocks: { relative: 1234 as RelativeTime, timeStamp: 123456789 as TimeStamp },

discarded: false,
resolveDuration: (50 * 1e6) as ServerDuration,
durationDiff: (50 * 1e6) as ServerDuration,
durationPercentageDiff: 50,
},

@@ -142,0 +149,0 @@ })

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

} from '@datadog/browser-core'
import type { ClocksState } from '@datadog/browser-core'
import type { ClocksState, Duration } from '@datadog/browser-core'
import type { RumConfiguration } from '../../configuration'

@@ -70,2 +70,4 @@ import type { RumPerformanceEntry, RumPerformanceResourceTiming } from '../../../browser/performanceCollection'

const responseDurationInfo = computeResponseDurationInfo(request)
const resourceEvent = combine(

@@ -86,3 +88,4 @@ {

correspondingTimingOverrides,
indexingInfo
indexingInfo,
responseDurationInfo
)

@@ -177,2 +180,18 @@ return {

function computeResponseDurationInfo(request: RequestCompleteEvent) {
let durationDiff
let durationPercentageDiff
if (request.resolveDuration) {
durationDiff = toServerDuration((request.duration - request.resolveDuration) as Duration)
durationPercentageDiff = Math.round((durationDiff / toServerDuration(request.duration)) * 100)
}
return {
_dd: {
resolveDuration: toServerDuration(request.resolveDuration),
durationDiff,
durationPercentageDiff,
},
}
}
// TODO next major: use directly PerformanceEntry type in domain context

@@ -179,0 +198,0 @@ function toPerformanceEntryRepresentation(entry: RumPerformanceEntry): PerformanceEntryRepresentation {

@@ -178,3 +178,3 @@ import type { Context, RelativeTime, Duration } from '@datadog/browser-core'

const { lifeCycle } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest

@@ -184,4 +184,10 @@ expect(getViewUpdateCount()).toEqual(1)

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.ERROR } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.ERROR } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.ERROR,
view: getLatestViewContext(),
} as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.ERROR,
view: getLatestViewContext(),
} as RumEvent & Context)
startView()

@@ -196,3 +202,3 @@

const { lifeCycle } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest

@@ -202,3 +208,6 @@ expect(getViewUpdateCount()).toEqual(1)

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.LONG_TASK } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.LONG_TASK,
view: getLatestViewContext(),
} as RumEvent & Context)
startView()

@@ -213,3 +222,3 @@

const { lifeCycle } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest

@@ -219,3 +228,6 @@ expect(getViewUpdateCount()).toEqual(1)

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
view: getLatestViewContext(),
} as RumEvent & Context)
startView()

@@ -230,3 +242,3 @@

const { lifeCycle } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest

@@ -239,2 +251,3 @@ expect(getViewUpdateCount()).toEqual(1)

action: { type: 'custom' },
view: getLatestViewContext(),
} as RumEvent & Context)

@@ -250,3 +263,3 @@ startView()

const { lifeCycle } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest

@@ -260,2 +273,3 @@ expect(getViewUpdateCount()).toEqual(1)

type: 'click',
id: '123',
frustration: {

@@ -265,2 +279,3 @@ type: [FrustrationType.DEAD_CLICK, FrustrationType.ERROR_CLICK],

},
view: getLatestViewContext(),
} as RumEvent & Context)

@@ -274,5 +289,23 @@ startView()

it('should not count child events unrelated to the view', () => {
const { lifeCycle } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
expect(getViewUpdateCount()).toEqual(1)
expect(getViewUpdate(0).eventCounts.errorCount).toEqual(0)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.ERROR,
view: { id: 'unrelated-view-id' },
} as RumEvent & Context)
startView()
expect(getViewUpdateCount()).toEqual(3)
expect(getViewUpdate(1).eventCounts.errorCount).toEqual(0)
expect(getViewUpdate(2).eventCounts.errorCount).toEqual(0)
})
it('should reset event count when the view changes', () => {
const { lifeCycle, changeLocation } = setupBuilder.build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest

@@ -282,3 +315,6 @@ expect(getViewUpdateCount()).toEqual(1)

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
view: getLatestViewContext(),
} as RumEvent & Context)
startView()

@@ -290,4 +326,10 @@

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
view: getLatestViewContext(),
} as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
view: getLatestViewContext(),
} as RumEvent & Context)
changeLocation('/baz')

@@ -302,3 +344,3 @@

const { lifeCycle, clock } = setupBuilder.withFakeClock().build()
const { getViewUpdate, getViewUpdateCount } = viewTest
const { getViewUpdate, getViewUpdateCount, getLatestViewContext } = viewTest

@@ -314,3 +356,6 @@ expect(getViewUpdateCount()).toEqual(1)

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
view: getLatestViewContext(),
} as RumEvent & Context)

@@ -333,7 +378,10 @@ expect(getViewUpdateCount()).toEqual(1)

const { lifeCycle, clock } = setupBuilder.withFakeClock().build()
const { getViewUpdate, getViewUpdateCount, startView } = viewTest
const { getViewUpdate, getViewUpdateCount, startView, getLatestViewContext } = viewTest
expect(getViewUpdateCount()).toEqual(1)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE } as RumEvent & Context)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, {
type: RumEventType.RESOURCE,
view: getLatestViewContext(),
} as RumEvent & Context)

@@ -340,0 +388,0 @@ expect(getViewUpdateCount()).toEqual(1)

@@ -24,2 +24,3 @@ import type { Duration, RelativeTime, Observable, ClocksState } from '@datadog/browser-core'

scheduleViewUpdate: () => void,
viewId: string,
loadingType: ViewLoadingType,

@@ -37,5 +38,9 @@ viewStart: ClocksState

}
const { stop: stopEventCountsTracking } = trackEventCounts(lifeCycle, (newEventCounts) => {
viewMetrics.eventCounts = newEventCounts
scheduleViewUpdate()
const { stop: stopEventCountsTracking } = trackEventCounts({
lifeCycle,
isChildEvent: (event) => event.view.id === viewId,
callback: (newEventCounts) => {
viewMetrics.eventCounts = newEventCounts
scheduleViewUpdate()
},
})

@@ -42,0 +47,0 @@

@@ -739,6 +739,2 @@ import type { Context, Duration, RelativeTime } from '@datadog/browser-core'

let viewTest: ViewTest
const FAKE_ACTION_EVENT = {
type: RumEventType.ACTION,
action: {},
} as RumEvent & Context

@@ -762,3 +758,3 @@ beforeEach(() => {

lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, FAKE_ACTION_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeActionEvent())

@@ -775,3 +771,3 @@ clock.tick(THROTTLE_VIEW_UPDATE_PERIOD)

lifeCycle.subscribe(LifeCycleEventType.VIEW_ENDED, () => {
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, FAKE_ACTION_EVENT)
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, createFakeActionEvent())
})

@@ -783,2 +779,10 @@

})
function createFakeActionEvent() {
return {
type: RumEventType.ACTION,
action: {},
view: viewTest.getLatestViewContext(),
} as RumEvent & Context
}
})

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

viewMetrics,
} = trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, loadingType, startClocks)
} = trackViewMetrics(
lifeCycle,
domMutationObservable,
configuration,
scheduleViewUpdate,
id,
loadingType,
startClocks
)

@@ -250,0 +258,0 @@ // Initial view update

@@ -6,3 +6,3 @@ import { isIE, objectEntries } from '@datadog/browser-core'

import { createRumSessionManagerMock } from '../../../test/mockRumSessionManager'
import type { RumFetchCompleteContext, RumFetchStartContext, RumXhrStartContext } from '../requestCollection'
import type { RumFetchResolveContext, RumFetchStartContext, RumXhrStartContext } from '../requestCollection'
import type { RumConfiguration } from '../configuration'

@@ -361,3 +361,3 @@ import { validateAndBuildRumConfiguration } from '../configuration'

const tracer = startTracer(configuration, sessionManager)
const context: RumFetchCompleteContext = {
const context: RumFetchResolveContext = {
status: 0,

@@ -376,3 +376,3 @@

const tracer = startTracer(configuration, sessionManager)
const context: RumFetchCompleteContext = {
const context: RumFetchResolveContext = {
status: 200,

@@ -379,0 +379,0 @@

import { getOrigin, matchList, objectEntries, shallowClone, performDraw, isNumber } from '@datadog/browser-core'
import type { RumConfiguration } from '../configuration'
import type {
RumFetchCompleteContext,
RumFetchResolveContext,
RumFetchStartContext,

@@ -14,3 +14,3 @@ RumXhrCompleteContext,

traceXhr: (context: Partial<RumXhrStartContext>, xhr: XMLHttpRequest) => void
clearTracingIfNeeded: (context: RumFetchCompleteContext | RumXhrCompleteContext) => void
clearTracingIfNeeded: (context: RumFetchResolveContext | RumXhrCompleteContext) => void
}

@@ -39,3 +39,3 @@

* */
export function clearTracingIfNeeded(context: RumFetchCompleteContext | RumXhrCompleteContext) {
export function clearTracingIfNeeded(context: RumFetchResolveContext | RumXhrCompleteContext) {
if (context.status === 0 && !context.isAborted) {

@@ -42,0 +42,0 @@ context.traceId = undefined

@@ -21,3 +21,3 @@ import type { Context } from '@datadog/browser-core'

it('tracks errors', () => {
const { eventCounts } = trackEventCounts(lifeCycle)
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({ type: RumEventType.ERROR })

@@ -28,3 +28,3 @@ expect(eventCounts.errorCount).toBe(1)

it('tracks long tasks', () => {
const { eventCounts } = trackEventCounts(lifeCycle)
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({ type: RumEventType.LONG_TASK })

@@ -35,3 +35,3 @@ expect(eventCounts.longTaskCount).toBe(1)

it("doesn't track views", () => {
const { eventCounts } = trackEventCounts(lifeCycle)
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({ type: RumEventType.VIEW })

@@ -42,3 +42,3 @@ expect(objectValues(eventCounts as unknown as { [key: string]: number }).every((value) => value === 0)).toBe(true)

it('tracks actions', () => {
const { eventCounts } = trackEventCounts(lifeCycle)
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({ type: RumEventType.ACTION, action: { type: 'custom' } })

@@ -49,3 +49,3 @@ expect(eventCounts.actionCount).toBe(1)

it('tracks resources', () => {
const { eventCounts } = trackEventCounts(lifeCycle)
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({ type: RumEventType.RESOURCE })

@@ -56,3 +56,3 @@ expect(eventCounts.resourceCount).toBe(1)

it('tracks frustration counts', () => {
const { eventCounts } = trackEventCounts(lifeCycle)
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({

@@ -71,3 +71,3 @@ type: RumEventType.ACTION,

it('stops tracking when stop is called', () => {
const { eventCounts, stop } = trackEventCounts(lifeCycle)
const { eventCounts, stop } = trackEventCounts({ lifeCycle, isChildEvent: () => true })
notifyCollectedRawRumEvent({ type: RumEventType.RESOURCE })

@@ -82,3 +82,3 @@ expect(eventCounts.resourceCount).toBe(1)

const spy = jasmine.createSpy<(eventCounts: EventCounts) => void>()
trackEventCounts(lifeCycle, spy)
trackEventCounts({ lifeCycle, isChildEvent: () => true, callback: spy })

@@ -93,2 +93,8 @@ notifyCollectedRawRumEvent({ type: RumEventType.RESOURCE })

})
it('does not take into account events that are not child events', () => {
const { eventCounts } = trackEventCounts({ lifeCycle, isChildEvent: () => false })
notifyCollectedRawRumEvent({ type: RumEventType.RESOURCE })
expect(eventCounts.resourceCount).toBe(0)
})
})
import { noop } from '@datadog/browser-core'
import { RumEventType } from '../rawRumEvent.types'
import type { RumActionEvent, RumErrorEvent, RumLongTaskEvent, RumResourceEvent } from '../rumEvent.types'
import type { LifeCycle } from './lifeCycle'

@@ -14,3 +15,11 @@ import { LifeCycleEventType } from './lifeCycle'

export function trackEventCounts(lifeCycle: LifeCycle, callback: (eventCounts: EventCounts) => void = noop) {
export function trackEventCounts({
lifeCycle,
isChildEvent,
callback = noop,
}: {
lifeCycle: LifeCycle
isChildEvent: (event: RumActionEvent | RumErrorEvent | RumLongTaskEvent | RumResourceEvent) => boolean
callback?: (eventCounts: EventCounts) => void
}) {
const eventCounts: EventCounts = {

@@ -25,2 +34,5 @@ errorCount: 0,

const subscription = lifeCycle.subscribe(LifeCycleEventType.RUM_EVENT_COLLECTED, (event): void => {
if (event.type === 'view' || !isChildEvent(event)) {
return
}
switch (event.type) {

@@ -27,0 +39,0 @@ case RumEventType.ERROR:

@@ -45,2 +45,5 @@ import type {

discarded: boolean
resolveDuration?: ServerDuration
durationDiff?: ServerDuration
durationPercentageDiff?: number
}

@@ -47,0 +50,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

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