Socket
Socket
Sign inDemoInstall

@datadog/browser-rum-core

Package Overview
Dependencies
Maintainers
1
Versions
177
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

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

Comparing version 3.1.3 to 3.2.0

2

cjs/boot/buildEnv.js

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

buildMode: 'release',
sdkVersion: '3.1.3',
sdkVersion: '3.2.0',
};
//# sourceMappingURL=buildEnv.js.map

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

import { Context, InitConfiguration, Configuration, InternalMonitoring } from '@datadog/browser-core';
import { Context, InitConfiguration, Configuration, InternalMonitoring, InitialPrivacyLevel } from '@datadog/browser-core';
import { LifeCycle } from '../domain/lifeCycle';

@@ -12,2 +12,3 @@ import { ParentContexts } from '../domain/parentContexts';

beforeSend?: (event: RumEvent, context: RumEventDomainContext) => void | boolean;
initialPrivacyLevel?: InitialPrivacyLevel;
}

@@ -14,0 +15,0 @@ export declare type RumPublicApi = ReturnType<typeof makeRumPublicApi>;

@@ -7,4 +7,5 @@ import { Configuration } from '@datadog/browser-core';

export interface BrowserWindow extends Window {
_DATADOG_SYNTHETICS_BROWSER?: unknown;
_DATADOG_SYNTHETICS_PUBLIC_ID?: string;
_DATADOG_SYNTHETICS_RESULT_ID?: string;
}
export declare function startRumAssembly(applicationId: string, configuration: Configuration, lifeCycle: LifeCycle, session: RumSession, parentContexts: ParentContexts, getCommonContext: () => CommonContext): void;

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

},
synthetics: getSyntheticsContext(),
};

@@ -110,7 +111,16 @@ var serverRumEvent = (needToAssembleWithAction(rawRumEvent)

function getSessionType() {
return navigator.userAgent.indexOf('DatadogSynthetics') === -1 &&
window._DATADOG_SYNTHETICS_BROWSER === undefined
return navigator.userAgent.indexOf('DatadogSynthetics') === -1 && !getSyntheticsContext()
? SessionType.USER
: SessionType.SYNTHETICS;
}
function getSyntheticsContext() {
var testId = window._DATADOG_SYNTHETICS_PUBLIC_ID;
var resultId = window._DATADOG_SYNTHETICS_RESULT_ID;
if (typeof testId === 'string' && typeof resultId === 'string') {
return {
test_id: testId,
result_id: resultId,
};
}
}
//# sourceMappingURL=assembly.js.map

@@ -19,7 +19,8 @@ import { Context, RawError, RelativeTime, Subscription } from '@datadog/browser-core';

REQUEST_COMPLETED = 8,
SESSION_RENEWED = 9,
BEFORE_UNLOAD = 10,
RAW_RUM_EVENT_COLLECTED = 11,
RUM_EVENT_COLLECTED = 12,
RAW_ERROR_COLLECTED = 13
SESSION_EXPIRED = 9,
SESSION_RENEWED = 10,
BEFORE_UNLOAD = 11,
RAW_RUM_EVENT_COLLECTED = 12,
RUM_EVENT_COLLECTED = 13,
RAW_ERROR_COLLECTED = 14
}

@@ -41,3 +42,3 @@ export declare class LifeCycle {

}): void;
notify(eventType: LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED): void;
notify(eventType: LifeCycleEventType.SESSION_EXPIRED | LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED): void;
notify(eventType: LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, data: RawRumEventCollectedData): void;

@@ -58,3 +59,3 @@ notify(eventType: LifeCycleEventType.RUM_EVENT_COLLECTED, data: RumEvent & Context): void;

}) => void): Subscription;
subscribe(eventType: LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED, callback: () => void): Subscription;
subscribe(eventType: LifeCycleEventType.SESSION_EXPIRED | LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED, callback: () => void): Subscription;
subscribe(eventType: LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, callback: (data: RawRumEventCollectedData) => void): Subscription;

@@ -61,0 +62,0 @@ subscribe(eventType: LifeCycleEventType.RUM_EVENT_COLLECTED, callback: (data: RumEvent & Context) => void): Subscription;

@@ -15,7 +15,18 @@ "use strict";

LifeCycleEventType[LifeCycleEventType["REQUEST_COMPLETED"] = 8] = "REQUEST_COMPLETED";
LifeCycleEventType[LifeCycleEventType["SESSION_RENEWED"] = 9] = "SESSION_RENEWED";
LifeCycleEventType[LifeCycleEventType["BEFORE_UNLOAD"] = 10] = "BEFORE_UNLOAD";
LifeCycleEventType[LifeCycleEventType["RAW_RUM_EVENT_COLLECTED"] = 11] = "RAW_RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RUM_EVENT_COLLECTED"] = 12] = "RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RAW_ERROR_COLLECTED"] = 13] = "RAW_ERROR_COLLECTED";
// The SESSION_EXPIRED lifecycle event has been introduced to represent when a session has expired
// and trigger cleanup tasks related to this, prior to renewing the session. Its implementation is
// slightly naive: it is not triggered as soon as the session is expired, but rather just before
// notifying that the session is renewed. Thus, the session id is already set to the newly renewed
// session.
//
// This implementation is "good enough" for our use-cases. Improving this is not trivial,
// primarily because multiple instances of the SDK may be managing the same session cookie at
// the same time, for example when using Logs and RUM on the same page, or opening multiple tabs
// on the same domain.
LifeCycleEventType[LifeCycleEventType["SESSION_EXPIRED"] = 9] = "SESSION_EXPIRED";
LifeCycleEventType[LifeCycleEventType["SESSION_RENEWED"] = 10] = "SESSION_RENEWED";
LifeCycleEventType[LifeCycleEventType["BEFORE_UNLOAD"] = 11] = "BEFORE_UNLOAD";
LifeCycleEventType[LifeCycleEventType["RAW_RUM_EVENT_COLLECTED"] = 12] = "RAW_RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RUM_EVENT_COLLECTED"] = 13] = "RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RAW_ERROR_COLLECTED"] = 14] = "RAW_ERROR_COLLECTED";
})(LifeCycleEventType = exports.LifeCycleEventType || (exports.LifeCycleEventType = {}));

@@ -22,0 +33,0 @@ var LifeCycle = /** @class */ (function () {

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

session.renewObservable.subscribe(function () {
lifeCycle.notify(lifeCycle_1.LifeCycleEventType.SESSION_EXPIRED);
lifeCycle.notify(lifeCycle_1.LifeCycleEventType.SESSION_RENEWED);

@@ -28,0 +29,0 @@ });

@@ -154,2 +154,6 @@ import { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp } from '@datadog/browser-core';

};
synthetics?: {
test_id: string;
result_id: string;
};
_dd: {

@@ -156,0 +160,0 @@ format_version: 2;

@@ -15,3 +15,3 @@ /**

*/
readonly type: string;
readonly type: 'action';
/**

@@ -104,3 +104,3 @@ * Action properties

*/
readonly type: string;
readonly type: 'error';
/**

@@ -209,3 +209,3 @@ * Error properties

*/
readonly type: string;
readonly type: 'long_task';
/**

@@ -223,2 +223,6 @@ * Long Task properties

readonly duration: number;
/**
* Whether this long task is considered a frozen frame
*/
readonly is_frozen_frame?: boolean;
[k: string]: unknown;

@@ -245,3 +249,3 @@ };

*/
readonly type: string;
readonly type: 'resource';
/**

@@ -416,3 +420,3 @@ * Resource properties

*/
readonly type: string;
readonly type: 'view';
/**

@@ -481,2 +485,6 @@ * View properties

/**
* Whether the View had a low average refresh rate
*/
readonly is_slow_rendered?: boolean;
/**
* Properties of the actions of the view

@@ -522,2 +530,12 @@ */

/**
* Properties of the frozen frames of the view
*/
readonly frozen_frame?: {
/**
* Number of frozen frames that occurred on the view
*/
readonly count: number;
[k: string]: unknown;
};
/**
* Properties of the resources of the view

@@ -693,2 +711,16 @@ */

/**
* Synthetics properties
*/
readonly synthetics?: {
/**
* The identifier of the current Synthetics test
*/
readonly test_id: string;
/**
* The identifier of the current Synthetics test results
*/
readonly result_id: string;
[k: string]: unknown;
};
/**
* Internal properties

@@ -700,3 +732,13 @@ */

*/
readonly format_version: number;
readonly format_version: 2;
/**
* Session-related internal properties
*/
session?: {
/**
* Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan
*/
plan: 1 | 2;
[k: string]: unknown;
};
[k: string]: unknown;

@@ -703,0 +745,0 @@ };

export var buildEnv = {
buildMode: 'release',
sdkVersion: '3.1.3',
sdkVersion: '3.2.0',
};
//# sourceMappingURL=buildEnv.js.map

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

import { Context, InitConfiguration, Configuration, InternalMonitoring } from '@datadog/browser-core';
import { Context, InitConfiguration, Configuration, InternalMonitoring, InitialPrivacyLevel } from '@datadog/browser-core';
import { LifeCycle } from '../domain/lifeCycle';

@@ -12,2 +12,3 @@ import { ParentContexts } from '../domain/parentContexts';

beforeSend?: (event: RumEvent, context: RumEventDomainContext) => void | boolean;
initialPrivacyLevel?: InitialPrivacyLevel;
}

@@ -14,0 +15,0 @@ export declare type RumPublicApi = ReturnType<typeof makeRumPublicApi>;

@@ -7,4 +7,5 @@ import { Configuration } from '@datadog/browser-core';

export interface BrowserWindow extends Window {
_DATADOG_SYNTHETICS_BROWSER?: unknown;
_DATADOG_SYNTHETICS_PUBLIC_ID?: string;
_DATADOG_SYNTHETICS_RESULT_ID?: string;
}
export declare function startRumAssembly(applicationId: string, configuration: Configuration, lifeCycle: LifeCycle, session: RumSession, parentContexts: ParentContexts, getCommonContext: () => CommonContext): void;

@@ -52,2 +52,3 @@ import { __spreadArrays } from "tslib";

},
synthetics: getSyntheticsContext(),
};

@@ -106,7 +107,16 @@ var serverRumEvent = (needToAssembleWithAction(rawRumEvent)

function getSessionType() {
return navigator.userAgent.indexOf('DatadogSynthetics') === -1 &&
window._DATADOG_SYNTHETICS_BROWSER === undefined
return navigator.userAgent.indexOf('DatadogSynthetics') === -1 && !getSyntheticsContext()
? SessionType.USER
: SessionType.SYNTHETICS;
}
function getSyntheticsContext() {
var testId = window._DATADOG_SYNTHETICS_PUBLIC_ID;
var resultId = window._DATADOG_SYNTHETICS_RESULT_ID;
if (typeof testId === 'string' && typeof resultId === 'string') {
return {
test_id: testId,
result_id: resultId,
};
}
}
//# sourceMappingURL=assembly.js.map

@@ -19,7 +19,8 @@ import { Context, RawError, RelativeTime, Subscription } from '@datadog/browser-core';

REQUEST_COMPLETED = 8,
SESSION_RENEWED = 9,
BEFORE_UNLOAD = 10,
RAW_RUM_EVENT_COLLECTED = 11,
RUM_EVENT_COLLECTED = 12,
RAW_ERROR_COLLECTED = 13
SESSION_EXPIRED = 9,
SESSION_RENEWED = 10,
BEFORE_UNLOAD = 11,
RAW_RUM_EVENT_COLLECTED = 12,
RUM_EVENT_COLLECTED = 13,
RAW_ERROR_COLLECTED = 14
}

@@ -41,3 +42,3 @@ export declare class LifeCycle {

}): void;
notify(eventType: LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED): void;
notify(eventType: LifeCycleEventType.SESSION_EXPIRED | LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED): void;
notify(eventType: LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, data: RawRumEventCollectedData): void;

@@ -58,3 +59,3 @@ notify(eventType: LifeCycleEventType.RUM_EVENT_COLLECTED, data: RumEvent & Context): void;

}) => void): Subscription;
subscribe(eventType: LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED, callback: () => void): Subscription;
subscribe(eventType: LifeCycleEventType.SESSION_EXPIRED | LifeCycleEventType.SESSION_RENEWED | LifeCycleEventType.BEFORE_UNLOAD | LifeCycleEventType.AUTO_ACTION_DISCARDED, callback: () => void): Subscription;
subscribe(eventType: LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, callback: (data: RawRumEventCollectedData) => void): Subscription;

@@ -61,0 +62,0 @@ subscribe(eventType: LifeCycleEventType.RUM_EVENT_COLLECTED, callback: (data: RumEvent & Context) => void): Subscription;

@@ -12,7 +12,18 @@ export var LifeCycleEventType;

LifeCycleEventType[LifeCycleEventType["REQUEST_COMPLETED"] = 8] = "REQUEST_COMPLETED";
LifeCycleEventType[LifeCycleEventType["SESSION_RENEWED"] = 9] = "SESSION_RENEWED";
LifeCycleEventType[LifeCycleEventType["BEFORE_UNLOAD"] = 10] = "BEFORE_UNLOAD";
LifeCycleEventType[LifeCycleEventType["RAW_RUM_EVENT_COLLECTED"] = 11] = "RAW_RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RUM_EVENT_COLLECTED"] = 12] = "RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RAW_ERROR_COLLECTED"] = 13] = "RAW_ERROR_COLLECTED";
// The SESSION_EXPIRED lifecycle event has been introduced to represent when a session has expired
// and trigger cleanup tasks related to this, prior to renewing the session. Its implementation is
// slightly naive: it is not triggered as soon as the session is expired, but rather just before
// notifying that the session is renewed. Thus, the session id is already set to the newly renewed
// session.
//
// This implementation is "good enough" for our use-cases. Improving this is not trivial,
// primarily because multiple instances of the SDK may be managing the same session cookie at
// the same time, for example when using Logs and RUM on the same page, or opening multiple tabs
// on the same domain.
LifeCycleEventType[LifeCycleEventType["SESSION_EXPIRED"] = 9] = "SESSION_EXPIRED";
LifeCycleEventType[LifeCycleEventType["SESSION_RENEWED"] = 10] = "SESSION_RENEWED";
LifeCycleEventType[LifeCycleEventType["BEFORE_UNLOAD"] = 11] = "BEFORE_UNLOAD";
LifeCycleEventType[LifeCycleEventType["RAW_RUM_EVENT_COLLECTED"] = 12] = "RAW_RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RUM_EVENT_COLLECTED"] = 13] = "RUM_EVENT_COLLECTED";
LifeCycleEventType[LifeCycleEventType["RAW_ERROR_COLLECTED"] = 14] = "RAW_ERROR_COLLECTED";
})(LifeCycleEventType || (LifeCycleEventType = {}));

@@ -19,0 +30,0 @@ var LifeCycle = /** @class */ (function () {

@@ -23,2 +23,3 @@ import { performDraw, startSessionManagement } from '@datadog/browser-core';

session.renewObservable.subscribe(function () {
lifeCycle.notify(LifeCycleEventType.SESSION_EXPIRED);
lifeCycle.notify(LifeCycleEventType.SESSION_RENEWED);

@@ -25,0 +26,0 @@ });

@@ -154,2 +154,6 @@ import { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp } from '@datadog/browser-core';

};
synthetics?: {
test_id: string;
result_id: string;
};
_dd: {

@@ -156,0 +160,0 @@ format_version: 2;

@@ -15,3 +15,3 @@ /**

*/
readonly type: string;
readonly type: 'action';
/**

@@ -104,3 +104,3 @@ * Action properties

*/
readonly type: string;
readonly type: 'error';
/**

@@ -209,3 +209,3 @@ * Error properties

*/
readonly type: string;
readonly type: 'long_task';
/**

@@ -223,2 +223,6 @@ * Long Task properties

readonly duration: number;
/**
* Whether this long task is considered a frozen frame
*/
readonly is_frozen_frame?: boolean;
[k: string]: unknown;

@@ -245,3 +249,3 @@ };

*/
readonly type: string;
readonly type: 'resource';
/**

@@ -416,3 +420,3 @@ * Resource properties

*/
readonly type: string;
readonly type: 'view';
/**

@@ -481,2 +485,6 @@ * View properties

/**
* Whether the View had a low average refresh rate
*/
readonly is_slow_rendered?: boolean;
/**
* Properties of the actions of the view

@@ -522,2 +530,12 @@ */

/**
* Properties of the frozen frames of the view
*/
readonly frozen_frame?: {
/**
* Number of frozen frames that occurred on the view
*/
readonly count: number;
[k: string]: unknown;
};
/**
* Properties of the resources of the view

@@ -693,2 +711,16 @@ */

/**
* Synthetics properties
*/
readonly synthetics?: {
/**
* The identifier of the current Synthetics test
*/
readonly test_id: string;
/**
* The identifier of the current Synthetics test results
*/
readonly result_id: string;
[k: string]: unknown;
};
/**
* Internal properties

@@ -700,3 +732,13 @@ */

*/
readonly format_version: number;
readonly format_version: 2;
/**
* Session-related internal properties
*/
session?: {
/**
* Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan
*/
plan: 1 | 2;
[k: string]: unknown;
};
[k: string]: unknown;

@@ -703,0 +745,0 @@ };

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

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

"dependencies": {
"@datadog/browser-core": "3.1.3",
"@datadog/browser-core": "3.2.0",
"tslib": "^1.10.0"

@@ -27,3 +27,3 @@ },

},
"gitHead": "73e642ca3d9fa22c33ecd81fc1e982894ed750e1"
"gitHead": "28c6c1f2c3a74bf603c795a10713ab5420968004"
}

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

import { ONE_SECOND, RelativeTime, getTimeStamp, display, TimeStamp } from '@datadog/browser-core'
import { ONE_SECOND, RelativeTime, getTimeStamp, display, TimeStamp, InitialPrivacyLevel } from '@datadog/browser-core'
import { noopRecorderApi, setup, TestSetupBuilder } from '../../test/specHelper'
import { ActionType } from '../rawRumEvent.types'
import { makeRumPublicApi, RumPublicApi, RumInitConfiguration, StartRum } from './rumPublicApi'
import { makeRumPublicApi, RumPublicApi, RumInitConfiguration, StartRum, RecorderApi } from './rumPublicApi'

@@ -655,2 +655,44 @@ const noopStartRum = (): ReturnType<StartRum> => ({

})
describe('recording', () => {
let recorderApiOnRumStartSpy: jasmine.Spy<RecorderApi['onRumStart']>
let setupBuilder: TestSetupBuilder
let rumPublicApi: RumPublicApi
beforeEach(() => {
recorderApiOnRumStartSpy = jasmine.createSpy('recorderApiOnRumStart')
rumPublicApi = makeRumPublicApi(noopStartRum, { ...noopRecorderApi, onRumStart: recorderApiOnRumStartSpy })
setupBuilder = setup()
})
afterEach(() => {
setupBuilder.cleanup()
})
it('recording is started with the default initialPrivacyLevel', () => {
rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)
expect(recorderApiOnRumStartSpy.calls.mostRecent().args[2].initialPrivacyLevel).toBe(InitialPrivacyLevel.ALLOW)
})
describe('initial-privacy-level-option feature enabled', () => {
it('recording is started with the configured initialPrivacyLevel', () => {
rumPublicApi.init({
...DEFAULT_INIT_CONFIGURATION,
initialPrivacyLevel: InitialPrivacyLevel.MASK,
enableExperimentalFeatures: ['initial-privacy-level-option'],
})
expect(recorderApiOnRumStartSpy.calls.mostRecent().args[2].initialPrivacyLevel).toBe(InitialPrivacyLevel.MASK)
})
})
describe('initial-privacy-level-option feature disabled', () => {
it('recording ignores the configured initialPrivacyLevel', () => {
rumPublicApi.init({
...DEFAULT_INIT_CONFIGURATION,
initialPrivacyLevel: InitialPrivacyLevel.MASK,
})
expect(recorderApiOnRumStartSpy.calls.mostRecent().args[2].initialPrivacyLevel).toBe(InitialPrivacyLevel.ALLOW)
})
})
})
})

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

createHandlingStack,
InitialPrivacyLevel,
} from '@datadog/browser-core'

@@ -35,2 +36,3 @@ import { LifeCycle } from '../domain/lifeCycle'

beforeSend?: (event: RumEvent, context: RumEventDomainContext) => void | boolean
initialPrivacyLevel?: InitialPrivacyLevel
}

@@ -37,0 +39,0 @@

@@ -54,2 +54,3 @@ import { ErrorSource, ONE_MINUTE, RawError, RelativeTime, display } from '@datadog/browser-core'

setupBuilder.cleanup()
cleanupSyntheticsGlobals()
})

@@ -520,3 +521,3 @@

it('should detect synthetics sessions from global', () => {
;(window as BrowserWindow)._DATADOG_SYNTHETICS_BROWSER = true
setSyntheticsGlobals('foo', 'bar')

@@ -529,4 +530,2 @@ const { lifeCycle } = setupBuilder.build()

expect(serverRumEvents[0].session.type).toEqual('synthetics')
delete (window as BrowserWindow)._DATADOG_SYNTHETICS_BROWSER
})

@@ -555,2 +554,40 @@

describe('synthetics context', () => {
it('sets the synthetics context defined by global variables', () => {
setSyntheticsGlobals('foo', 'bar')
const { lifeCycle } = setupBuilder.build()
notifyRawRumEvent(lifeCycle, {
rawRumEvent: createRawRumEvent(RumEventType.VIEW),
})
expect(serverRumEvents[0].synthetics).toEqual({
test_id: 'foo',
result_id: 'bar',
})
})
it('does not set synthetics context if one global variable is undefined', () => {
setSyntheticsGlobals('foo')
const { lifeCycle } = setupBuilder.build()
notifyRawRumEvent(lifeCycle, {
rawRumEvent: createRawRumEvent(RumEventType.VIEW),
})
expect(serverRumEvents[0].synthetics).toBeUndefined()
})
it('does not set synthetics context if global variables are not strings', () => {
setSyntheticsGlobals(1, 2)
const { lifeCycle } = setupBuilder.build()
notifyRawRumEvent(lifeCycle, {
rawRumEvent: createRawRumEvent(RumEventType.VIEW),
})
expect(serverRumEvents[0].synthetics).toBeUndefined()
})
})
describe('error events limitation', () => {

@@ -636,1 +673,11 @@ const notifiedRawErrors: RawError[] = []

}
function setSyntheticsGlobals(publicId: any, resultId?: any) {
;(window as BrowserWindow)._DATADOG_SYNTHETICS_PUBLIC_ID = publicId
;(window as BrowserWindow)._DATADOG_SYNTHETICS_RESULT_ID = resultId
}
function cleanupSyntheticsGlobals() {
delete (window as BrowserWindow)._DATADOG_SYNTHETICS_PUBLIC_ID
delete (window as BrowserWindow)._DATADOG_SYNTHETICS_RESULT_ID
}

@@ -33,3 +33,4 @@ import {

export interface BrowserWindow extends Window {
_DATADOG_SYNTHETICS_BROWSER?: unknown
_DATADOG_SYNTHETICS_PUBLIC_ID?: string
_DATADOG_SYNTHETICS_RESULT_ID?: string
}

@@ -97,2 +98,3 @@

},
synthetics: getSyntheticsContext(),
}

@@ -167,6 +169,17 @@ const serverRumEvent = (needToAssembleWithAction(rawRumEvent)

function getSessionType() {
return navigator.userAgent.indexOf('DatadogSynthetics') === -1 &&
(window as BrowserWindow)._DATADOG_SYNTHETICS_BROWSER === undefined
return navigator.userAgent.indexOf('DatadogSynthetics') === -1 && !getSyntheticsContext()
? SessionType.USER
: SessionType.SYNTHETICS
}
function getSyntheticsContext() {
const testId = (window as BrowserWindow)._DATADOG_SYNTHETICS_PUBLIC_ID
const resultId = (window as BrowserWindow)._DATADOG_SYNTHETICS_RESULT_ID
if (typeof testId === 'string' && typeof resultId === 'string') {
return {
test_id: testId,
result_id: resultId,
}
}
}

@@ -20,2 +20,15 @@ import { Context, RawError, RelativeTime, Subscription } from '@datadog/browser-core'

REQUEST_COMPLETED,
// The SESSION_EXPIRED lifecycle event has been introduced to represent when a session has expired
// and trigger cleanup tasks related to this, prior to renewing the session. Its implementation is
// slightly naive: it is not triggered as soon as the session is expired, but rather just before
// notifying that the session is renewed. Thus, the session id is already set to the newly renewed
// session.
//
// This implementation is "good enough" for our use-cases. Improving this is not trivial,
// primarily because multiple instances of the SDK may be managing the same session cookie at
// the same time, for example when using Logs and RUM on the same page, or opening multiple tabs
// on the same domain.
SESSION_EXPIRED,
SESSION_RENEWED,

@@ -45,2 +58,3 @@ BEFORE_UNLOAD,

eventType:
| LifeCycleEventType.SESSION_EXPIRED
| LifeCycleEventType.SESSION_RENEWED

@@ -82,2 +96,3 @@ | LifeCycleEventType.BEFORE_UNLOAD

eventType:
| LifeCycleEventType.SESSION_EXPIRED
| LifeCycleEventType.SESSION_RENEWED

@@ -84,0 +99,0 @@ | LifeCycleEventType.BEFORE_UNLOAD

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

let lifeCycle: LifeCycle
let expireSessionSpy: jasmine.Spy
let renewSessionSpy: jasmine.Spy

@@ -37,4 +38,6 @@ let clock: Clock

clock = mockClock()
expireSessionSpy = jasmine.createSpy('expireSessionSpy')
renewSessionSpy = jasmine.createSpy('renewSessionSpy')
lifeCycle = new LifeCycle()
lifeCycle.subscribe(LifeCycleEventType.SESSION_EXPIRED, expireSessionSpy)
lifeCycle.subscribe(LifeCycleEventType.SESSION_RENEWED, renewSessionSpy)

@@ -57,2 +60,3 @@ })

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()

@@ -68,2 +72,3 @@ expect(getCookie(SESSION_COOKIE_NAME)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_REPLAY}`)

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()

@@ -79,2 +84,3 @@ expect(getCookie(SESSION_COOKIE_NAME)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_LITE}`)

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()

@@ -90,2 +96,3 @@ expect(getCookie(SESSION_COOKIE_NAME)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.NOT_TRACKED}`)

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()

@@ -101,2 +108,3 @@ expect(getCookie(SESSION_COOKIE_NAME)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_REPLAY}`)

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()

@@ -111,2 +119,3 @@ expect(getCookie(SESSION_COOKIE_NAME)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.NOT_TRACKED}`)

expect(getCookie(SESSION_COOKIE_NAME)).toBeUndefined()
expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()

@@ -118,2 +127,3 @@ clock.tick(COOKIE_ACCESS_DELAY)

expect(expireSessionSpy).toHaveBeenCalled()
expect(renewSessionSpy).toHaveBeenCalled()

@@ -120,0 +130,0 @@ expect(getCookie(SESSION_COOKIE_NAME)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_REPLAY}`)

@@ -33,2 +33,3 @@ import { Configuration, performDraw, Session, startSessionManagement } from '@datadog/browser-core'

session.renewObservable.subscribe(() => {
lifeCycle.notify(LifeCycleEventType.SESSION_EXPIRED)
lifeCycle.notify(LifeCycleEventType.SESSION_RENEWED)

@@ -35,0 +36,0 @@ })

@@ -182,2 +182,6 @@ import {

}
synthetics?: {
test_id: string
result_id: string
}
_dd: {

@@ -184,0 +188,0 @@ format_version: 2

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

*/
readonly type: string
readonly type: 'action'
/**

@@ -106,3 +106,3 @@ * Action properties

*/
readonly type: string
readonly type: 'error'
/**

@@ -225,3 +225,3 @@ * Error properties

*/
readonly type: string
readonly type: 'long_task'
/**

@@ -239,2 +239,6 @@ * Long Task properties

readonly duration: number
/**
* Whether this long task is considered a frozen frame
*/
readonly is_frozen_frame?: boolean
[k: string]: unknown

@@ -261,3 +265,3 @@ }

*/
readonly type: string
readonly type: 'resource'
/**

@@ -446,3 +450,3 @@ * Resource properties

*/
readonly type: string
readonly type: 'view'
/**

@@ -519,2 +523,6 @@ * View properties

/**
* Whether the View had a low average refresh rate
*/
readonly is_slow_rendered?: boolean
/**
* Properties of the actions of the view

@@ -560,2 +568,12 @@ */

/**
* Properties of the frozen frames of the view
*/
readonly frozen_frame?: {
/**
* Number of frozen frames that occurred on the view
*/
readonly count: number
[k: string]: unknown
}
/**
* Properties of the resources of the view

@@ -742,2 +760,16 @@ */

/**
* Synthetics properties
*/
readonly synthetics?: {
/**
* The identifier of the current Synthetics test
*/
readonly test_id: string
/**
* The identifier of the current Synthetics test results
*/
readonly result_id: string
[k: string]: unknown
}
/**
* Internal properties

@@ -749,3 +781,13 @@ */

*/
readonly format_version: number
readonly format_version: 2
/**
* Session-related internal properties
*/
session?: {
/**
* Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan
*/
plan: 1 | 2
[k: string]: unknown
}
[k: string]: unknown

@@ -752,0 +794,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

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