diff --git a/packages/core/src/browser/cookie.ts b/packages/core/src/browser/cookie.ts index ec080c7798..f7c049a244 100644 --- a/packages/core/src/browser/cookie.ts +++ b/packages/core/src/browser/cookie.ts @@ -5,6 +5,7 @@ import { findCommaSeparatedValue, findCommaSeparatedValues, generateUUID } from export interface CookieOptions { secure?: boolean crossSite?: boolean + partitioned?: boolean domain?: string } @@ -15,7 +16,8 @@ export function setCookie(name: string, value: string, expireDelay: number, opti const sameSite = options && options.crossSite ? 'none' : 'strict' const domain = options && options.domain ? `;domain=${options.domain}` : '' const secure = options && options.secure ? ';secure' : '' - document.cookie = `${name}=${value};${expires};path=/;samesite=${sameSite}${domain}${secure}` + const partitioned = options && options.partitioned ? ';partitioned' : '' + document.cookie = `${name}=${value};${expires};path=/;samesite=${sameSite}${domain}${secure}${partitioned}` } export function getCookie(name: string) { diff --git a/packages/core/src/domain/configuration/configuration.spec.ts b/packages/core/src/domain/configuration/configuration.spec.ts index 39eeeb46a3..c77d381be7 100644 --- a/packages/core/src/domain/configuration/configuration.spec.ts +++ b/packages/core/src/domain/configuration/configuration.spec.ts @@ -111,7 +111,7 @@ describe('validateAndBuildConfiguration', () => { const configuration = validateAndBuildConfiguration({ clientToken, allowFallbackToLocalStorage: false }) expect(configuration?.sessionStoreStrategyType).toEqual({ type: 'Cookie', - cookieOptions: { secure: false, crossSite: false }, + cookieOptions: { secure: false, crossSite: false, partitioned: false }, }) }) @@ -119,7 +119,7 @@ describe('validateAndBuildConfiguration', () => { const configuration = validateAndBuildConfiguration({ clientToken, allowFallbackToLocalStorage: true }) expect(configuration?.sessionStoreStrategyType).toEqual({ type: 'Cookie', - cookieOptions: { secure: false, crossSite: false }, + cookieOptions: { secure: false, crossSite: false, partitioned: false }, }) }) diff --git a/packages/core/src/domain/configuration/configuration.ts b/packages/core/src/domain/configuration/configuration.ts index 0c83250673..574b4afe5e 100644 --- a/packages/core/src/domain/configuration/configuration.ts +++ b/packages/core/src/domain/configuration/configuration.ts @@ -41,7 +41,11 @@ export interface InitConfiguration { version?: string | undefined // cookie options + /** + * @deprecated use usePartitionedCrossSiteSessionCookie instead + */ useCrossSiteSessionCookie?: boolean | undefined + usePartitionedCrossSiteSessionCookie?: boolean | undefined useSecureSessionCookie?: boolean | undefined trackSessionAcrossSubdomains?: boolean | undefined @@ -169,6 +173,7 @@ export function serializeConfiguration(initConfiguration: InitConfiguration): Pa telemetry_configuration_sample_rate: initConfiguration.telemetryConfigurationSampleRate, use_before_send: !!initConfiguration.beforeSend, use_cross_site_session_cookie: initConfiguration.useCrossSiteSessionCookie, + use_partitioned_cross_site_session_cookie: initConfiguration.usePartitionedCrossSiteSessionCookie, use_secure_session_cookie: initConfiguration.useSecureSessionCookie, use_proxy: !!initConfiguration.proxy, silent_multiple_init: initConfiguration.silentMultipleInit, diff --git a/packages/core/src/domain/session/storeStrategies/sessionInCookie.spec.ts b/packages/core/src/domain/session/storeStrategies/sessionInCookie.spec.ts index ce5b91cfda..b17cb5075e 100644 --- a/packages/core/src/domain/session/storeStrategies/sessionInCookie.spec.ts +++ b/packages/core/src/domain/session/storeStrategies/sessionInCookie.spec.ts @@ -42,22 +42,32 @@ describe('session in cookie strategy', () => { it('should not be secure nor crossSite by default', () => { const cookieOptions = buildCookieOptions({ clientToken })! - expect(cookieOptions).toEqual({ secure: false, crossSite: false }) + expect(cookieOptions).toEqual({ secure: false, crossSite: false, partitioned: false }) }) it('should be secure when `useSecureSessionCookie` is truthy', () => { const cookieOptions = buildCookieOptions({ clientToken, useSecureSessionCookie: true })! - expect(cookieOptions).toEqual({ secure: true, crossSite: false }) + expect(cookieOptions).toEqual({ secure: true, crossSite: false, partitioned: false }) }) it('should be secure and crossSite when `useCrossSiteSessionCookie` is truthy', () => { const cookieOptions = buildCookieOptions({ clientToken, useCrossSiteSessionCookie: true })! - expect(cookieOptions).toEqual({ secure: true, crossSite: true }) + expect(cookieOptions).toEqual({ secure: true, crossSite: true, partitioned: false }) + }) + + it('should be secure, crossSite and partitioned when `usePartitionedCrossSiteSessionCookie` is truthy', () => { + const cookieOptions = buildCookieOptions({ clientToken, usePartitionedCrossSiteSessionCookie: true })! + expect(cookieOptions).toEqual({ secure: true, crossSite: true, partitioned: true }) }) it('should have domain when `trackSessionAcrossSubdomains` is truthy', () => { const cookieOptions = buildCookieOptions({ clientToken, trackSessionAcrossSubdomains: true })! - expect(cookieOptions).toEqual({ secure: false, crossSite: false, domain: jasmine.any(String) }) + expect(cookieOptions).toEqual({ + secure: false, + crossSite: false, + partitioned: false, + domain: jasmine.any(String), + }) }) }) diff --git a/packages/core/src/domain/session/storeStrategies/sessionInCookie.ts b/packages/core/src/domain/session/storeStrategies/sessionInCookie.ts index ba6bfff36c..059be2c4e6 100644 --- a/packages/core/src/domain/session/storeStrategies/sessionInCookie.ts +++ b/packages/core/src/domain/session/storeStrategies/sessionInCookie.ts @@ -51,8 +51,13 @@ function deleteSessionCookie(options: CookieOptions) { export function buildCookieOptions(initConfiguration: InitConfiguration) { const cookieOptions: CookieOptions = {} - cookieOptions.secure = !!initConfiguration.useSecureSessionCookie || !!initConfiguration.useCrossSiteSessionCookie - cookieOptions.crossSite = !!initConfiguration.useCrossSiteSessionCookie + cookieOptions.secure = + !!initConfiguration.useSecureSessionCookie || + !!initConfiguration.usePartitionedCrossSiteSessionCookie || + !!initConfiguration.useCrossSiteSessionCookie + cookieOptions.crossSite = + !!initConfiguration.usePartitionedCrossSiteSessionCookie || !!initConfiguration.useCrossSiteSessionCookie + cookieOptions.partitioned = !!initConfiguration.usePartitionedCrossSiteSessionCookie if (initConfiguration.trackSessionAcrossSubdomains) { cookieOptions.domain = getCurrentSite() diff --git a/packages/core/src/domain/telemetry/telemetryEvent.types.ts b/packages/core/src/domain/telemetry/telemetryEvent.types.ts index 03c7200cd7..906df0bd3b 100644 --- a/packages/core/src/domain/telemetry/telemetryEvent.types.ts +++ b/packages/core/src/domain/telemetry/telemetryEvent.types.ts @@ -142,9 +142,13 @@ export type TelemetryConfigurationEvent = CommonTelemetryProperties & { */ track_long_task?: boolean /** - * Whether a secure cross-site session cookie is used + * Whether a secure cross-site session cookie is used (deprecated) */ use_cross_site_session_cookie?: boolean + /** + * Whether a partitioned secure cross-site session cookie is used + */ + use_partitioned_cross_site_session_cookie?: boolean /** * Whether a secure session cookie is used */ @@ -285,6 +289,14 @@ export type TelemetryConfigurationEvent = CommonTelemetryProperties & { * The upload frequency of batches (in milliseconds) */ batch_upload_frequency?: number + /** + * Maximum number of batches processed sequencially without a delay + */ + batch_processing_level?: number + /** + * Whether UIApplication background tasks are enabled + */ + background_tasks_enabled?: boolean /** * The version of React used in a ReactNative application */ diff --git a/packages/rum-core/src/rumEvent.types.ts b/packages/rum-core/src/rumEvent.types.ts index 67701bd75d..91d9d80fe1 100644 --- a/packages/rum-core/src/rumEvent.types.ts +++ b/packages/rum-core/src/rumEvent.types.ts @@ -10,150 +10,152 @@ export type RumEvent = RumActionEvent | RumErrorEvent | RumLongTaskEvent | RumRe /** * Schema of all properties of an Action event */ -export type RumActionEvent = CommonProperties & { - /** - * RUM event type - */ - readonly type: 'action' - /** - * Action properties - */ - readonly action: { - /** - * Type of the action - */ - readonly type: 'custom' | 'click' | 'tap' | 'scroll' | 'swipe' | 'application_start' | 'back' +export type RumActionEvent = CommonProperties & + ViewContainerSchema & { /** - * UUID of the action - */ - readonly id?: string - /** - * Duration in ns to the action is considered loaded + * RUM event type */ - readonly loading_time?: number + readonly type: 'action' /** - * Action target properties + * Action properties */ - readonly target?: { + readonly action: { /** - * Target name + * Type of the action */ - name: string - [k: string]: unknown - } - /** - * Action frustration properties - */ - readonly frustration?: { + readonly type: 'custom' | 'click' | 'tap' | 'scroll' | 'swipe' | 'application_start' | 'back' /** - * Action frustration types + * UUID of the action */ - readonly type: ('rage_click' | 'dead_click' | 'error_click' | 'rage_tap' | 'error_tap')[] - [k: string]: unknown - } - /** - * Properties of the errors of the action - */ - readonly error?: { + readonly id?: string /** - * Number of errors that occurred on the action + * Duration in ns to the action is considered loaded */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the crashes of the action - */ - readonly crash?: { + readonly loading_time?: number /** - * Number of crashes that occurred on the action + * Action target properties */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the long tasks of the action - */ - readonly long_task?: { + readonly target?: { + /** + * Target name + */ + name: string + [k: string]: unknown + } /** - * Number of long tasks that occurred on the action + * Action frustration properties */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the resources of the action - */ - readonly resource?: { + readonly frustration?: { + /** + * Action frustration types + */ + readonly type: ('rage_click' | 'dead_click' | 'error_click' | 'rage_tap' | 'error_tap')[] + [k: string]: unknown + } /** - * Number of resources that occurred on the action + * Properties of the errors of the action */ - readonly count: number - [k: string]: unknown - } - [k: string]: unknown - } - /** - * View properties - */ - readonly view?: { - /** - * Is the action starting in the foreground (focus in browser) - */ - readonly in_foreground?: boolean - [k: string]: unknown - } - /** - * Internal properties - */ - _dd?: { - /** - * Action properties - */ - readonly action?: { + readonly error?: { + /** + * Number of errors that occurred on the action + */ + readonly count: number + [k: string]: unknown + } /** - * Action position properties + * Properties of the crashes of the action */ - readonly position?: { + readonly crash?: { /** - * X coordinate relative to the target element of the action (in pixels) + * Number of crashes that occurred on the action */ - readonly x: number + readonly count: number + [k: string]: unknown + } + /** + * Properties of the long tasks of the action + */ + readonly long_task?: { /** - * Y coordinate relative to the target element of the action (in pixels) + * Number of long tasks that occurred on the action */ - readonly y: number + readonly count: number [k: string]: unknown } /** - * Target properties + * Properties of the resources of the action */ - target?: { + readonly resource?: { /** - * CSS selector path of the target element + * Number of resources that occurred on the action */ - readonly selector?: string + readonly count: number + [k: string]: unknown + } + [k: string]: unknown + } + /** + * View properties + */ + readonly view?: { + /** + * Is the action starting in the foreground (focus in browser) + */ + readonly in_foreground?: boolean + [k: string]: unknown + } + /** + * Internal properties + */ + _dd?: { + /** + * Action properties + */ + readonly action?: { /** - * Width of the target element (in pixels) + * Action position properties */ - readonly width?: number + readonly position?: { + /** + * X coordinate relative to the target element of the action (in pixels) + */ + readonly x: number + /** + * Y coordinate relative to the target element of the action (in pixels) + */ + readonly y: number + [k: string]: unknown + } /** - * Height of the target element (in pixels) + * Target properties */ - readonly height?: number + target?: { + /** + * CSS selector path of the target element + */ + readonly selector?: string + /** + * Width of the target element (in pixels) + */ + readonly width?: number + /** + * Height of the target element (in pixels) + */ + readonly height?: number + [k: string]: unknown + } [k: string]: unknown } [k: string]: unknown } [k: string]: unknown } - [k: string]: unknown -} /** * Schema of all properties of an Error event */ export type RumErrorEvent = CommonProperties & - ActionChildProperties & { + ActionChildProperties & + ViewContainerSchema & { /** * RUM event type */ @@ -298,7 +300,8 @@ export type RumErrorEvent = CommonProperties & * Schema of all properties of a Long Task event */ export type RumLongTaskEvent = CommonProperties & - ActionChildProperties & { + ActionChildProperties & + ViewContainerSchema & { /** * RUM event type */ @@ -337,7 +340,8 @@ export type RumLongTaskEvent = CommonProperties & * Schema of all properties of a Resource event */ export type RumResourceEvent = CommonProperties & - ActionChildProperties & { + ActionChildProperties & + ViewContainerSchema & { /** * RUM event type */ @@ -552,352 +556,344 @@ export type RumResourceEvent = CommonProperties & /** * Schema of all properties of a View event */ -export type RumViewEvent = CommonProperties & { - /** - * RUM event type - */ - readonly type: 'view' - /** - * View properties - */ - readonly view: { - /** - * Duration in ns to the view is considered loaded - */ - readonly loading_time?: number - /** - * Type of the loading of the view - */ - readonly loading_type?: - | 'initial_load' - | 'route_change' - | 'activity_display' - | 'activity_redisplay' - | 'fragment_display' - | 'fragment_redisplay' - | 'view_controller_display' - | 'view_controller_redisplay' - /** - * Time spent on the view in ns - */ - readonly time_spent: number - /** - * Duration in ns to the first rendering - */ - readonly first_contentful_paint?: number - /** - * Duration in ns to the largest contentful paint - */ - readonly largest_contentful_paint?: number - /** - * CSS selector path of the largest contentful paint element - */ - readonly largest_contentful_paint_target_selector?: string - /** - * Duration in ns of the first input event delay - */ - readonly first_input_delay?: number - /** - * Duration in ns to the first input - */ - readonly first_input_time?: number - /** - * CSS selector path of the first input target element - */ - readonly first_input_target_selector?: string - /** - * Longest duration in ns between an interaction and the next paint - */ - readonly interaction_to_next_paint?: number - /** - * CSS selector path of the interacted element corresponding to INP - */ - readonly interaction_to_next_paint_target_selector?: string - /** - * Total layout shift score that occurred on the view - */ - readonly cumulative_layout_shift?: number - /** - * CSS selector path of the first element (in document order) of the largest layout shift contributing to CLS - */ - readonly cumulative_layout_shift_target_selector?: string - /** - * Duration in ns to the complete parsing and loading of the document and its sub resources - */ - readonly dom_complete?: number - /** - * Duration in ns to the complete parsing and loading of the document without its sub resources - */ - readonly dom_content_loaded?: number - /** - * Duration in ns to the end of the parsing of the document - */ - readonly dom_interactive?: number - /** - * Duration in ns to the end of the load event handler execution - */ - readonly load_event?: number - /** - * Duration in ns to the response start of the document request - */ - readonly first_byte?: number - /** - * User custom timings of the view. As timing name is used as facet path, it must contain only letters, digits, or the characters - _ . @ $ - */ - readonly custom_timings?: { - [k: string]: number - } - /** - * Whether the View corresponding to this event is considered active - */ - readonly is_active?: boolean +export type RumViewEvent = CommonProperties & + ViewContainerSchema & { /** - * Whether the View had a low average refresh rate + * RUM event type */ - readonly is_slow_rendered?: boolean + readonly type: 'view' /** - * Properties of the actions of the view + * View properties */ - readonly action: { + readonly view: { /** - * Number of actions that occurred on the view + * Duration in ns to the view is considered loaded */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the errors of the view - */ - readonly error: { + readonly loading_time?: number /** - * Number of errors that occurred on the view + * Type of the loading of the view */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the crashes of the view - */ - readonly crash?: { + readonly loading_type?: + | 'initial_load' + | 'route_change' + | 'activity_display' + | 'activity_redisplay' + | 'fragment_display' + | 'fragment_redisplay' + | 'view_controller_display' + | 'view_controller_redisplay' /** - * Number of crashes that occurred on the view + * Time spent on the view in ns */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the long tasks of the view - */ - readonly long_task?: { + readonly time_spent: number /** - * Number of long tasks that occurred on the view + * Duration in ns to the first rendering */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the frozen frames of the view - */ - readonly frozen_frame?: { + readonly first_contentful_paint?: number /** - * Number of frozen frames that occurred on the view + * Duration in ns to the largest contentful paint */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the resources of the view - */ - readonly resource: { + readonly largest_contentful_paint?: number /** - * Number of resources that occurred on the view + * CSS selector path of the largest contentful paint element */ - readonly count: number - [k: string]: unknown - } - /** - * Properties of the frustrations of the view - */ - readonly frustration?: { + readonly largest_contentful_paint_target_selector?: string /** - * Number of frustrations that occurred on the view + * Duration in ns of the first input event delay */ - readonly count: number - [k: string]: unknown - } - /** - * List of the periods of time the user had the view in foreground (focused in the browser) - */ - readonly in_foreground_periods?: { + readonly first_input_delay?: number /** - * Duration in ns between start of the view and start of foreground period + * Duration in ns to the first input */ - readonly start: number + readonly first_input_time?: number /** - * Duration in ns of the view foreground period + * CSS selector path of the first input target element */ - readonly duration: number - [k: string]: unknown - }[] - /** - * Average memory used during the view lifetime (in bytes) - */ - readonly memory_average?: number - /** - * Peak memory used during the view lifetime (in bytes) - */ - readonly memory_max?: number - /** - * Total number of cpu ticks during the view’s lifetime - */ - readonly cpu_ticks_count?: number - /** - * Average number of cpu ticks per second during the view’s lifetime - */ - readonly cpu_ticks_per_second?: number - /** - * Average refresh rate during the view’s lifetime (in frames per second) - */ - readonly refresh_rate_average?: number - /** - * Minimum refresh rate during the view’s lifetime (in frames per second) - */ - readonly refresh_rate_min?: number - /** - * Time taken for Flutter 'build' methods. - */ - flutter_build_time?: RumPerfMetric - /** - * Time taken for Flutter to rasterize the view. - */ - flutter_raster_time?: RumPerfMetric - /** - * The JavaScript refresh rate for React Native - */ - js_refresh_rate?: RumPerfMetric - [k: string]: unknown - } - /** - * Session properties - */ - readonly session?: { - /** - * The precondition that led to the creation of the session - */ - readonly start_precondition?: - | 'app_launch' - | 'inactivity_timeout' - | 'max_duration' - | 'explicit_stop' - | 'background_event' - /** - * Whether this session is currently active. Set to false to manually stop a session - */ - readonly is_active?: boolean - /** - * Whether this session has been sampled for replay - */ - readonly sampled_for_replay?: boolean - [k: string]: unknown - } - /** - * Feature flags properties - */ - readonly feature_flags?: { - [k: string]: unknown - } - /** - * Privacy properties - */ - readonly privacy?: { - /** - * The replay privacy level - */ - readonly replay_level: 'allow' | 'mask' | 'mask-user-input' - [k: string]: unknown - } - /** - * Internal properties - */ - readonly _dd: { - /** - * Version of the update of the view event - */ - readonly document_version: number - /** - * List of the page states during the view - */ - readonly page_states?: { + readonly first_input_target_selector?: string + /** + * Longest duration in ns between an interaction and the next paint + */ + readonly interaction_to_next_paint?: number + /** + * CSS selector path of the interacted element corresponding to INP + */ + readonly interaction_to_next_paint_target_selector?: string + /** + * Total layout shift score that occurred on the view + */ + readonly cumulative_layout_shift?: number + /** + * CSS selector path of the first element (in document order) of the largest layout shift contributing to CLS + */ + readonly cumulative_layout_shift_target_selector?: string + /** + * Duration in ns to the complete parsing and loading of the document and its sub resources + */ + readonly dom_complete?: number + /** + * Duration in ns to the complete parsing and loading of the document without its sub resources + */ + readonly dom_content_loaded?: number + /** + * Duration in ns to the end of the parsing of the document + */ + readonly dom_interactive?: number + /** + * Duration in ns to the end of the load event handler execution + */ + readonly load_event?: number /** - * Page state name + * Duration in ns to the response start of the document request */ - readonly state: 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated' + readonly first_byte?: number /** - * Duration in ns between start of the view and start of the page state + * User custom timings of the view. As timing name is used as facet path, it must contain only letters, digits, or the characters - _ . @ $ */ - readonly start: number + readonly custom_timings?: { + [k: string]: number + } + /** + * Whether the View corresponding to this event is considered active + */ + readonly is_active?: boolean + /** + * Whether the View had a low average refresh rate + */ + readonly is_slow_rendered?: boolean + /** + * Properties of the actions of the view + */ + readonly action: { + /** + * Number of actions that occurred on the view + */ + readonly count: number + [k: string]: unknown + } + /** + * Properties of the errors of the view + */ + readonly error: { + /** + * Number of errors that occurred on the view + */ + readonly count: number + [k: string]: unknown + } + /** + * Properties of the crashes of the view + */ + readonly crash?: { + /** + * Number of crashes that occurred on the view + */ + readonly count: number + [k: string]: unknown + } + /** + * Properties of the long tasks of the view + */ + readonly long_task?: { + /** + * Number of long tasks that occurred on the view + */ + readonly count: number + [k: string]: unknown + } + /** + * 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 + */ + readonly resource: { + /** + * Number of resources that occurred on the view + */ + readonly count: number + [k: string]: unknown + } + /** + * Properties of the frustrations of the view + */ + readonly frustration?: { + /** + * Number of frustrations that occurred on the view + */ + readonly count: number + [k: string]: unknown + } + /** + * List of the periods of time the user had the view in foreground (focused in the browser) + */ + readonly in_foreground_periods?: { + /** + * Duration in ns between start of the view and start of foreground period + */ + readonly start: number + /** + * Duration in ns of the view foreground period + */ + readonly duration: number + [k: string]: unknown + }[] + /** + * Average memory used during the view lifetime (in bytes) + */ + readonly memory_average?: number + /** + * Peak memory used during the view lifetime (in bytes) + */ + readonly memory_max?: number + /** + * Total number of cpu ticks during the view’s lifetime + */ + readonly cpu_ticks_count?: number + /** + * Average number of cpu ticks per second during the view’s lifetime + */ + readonly cpu_ticks_per_second?: number + /** + * Average refresh rate during the view’s lifetime (in frames per second) + */ + readonly refresh_rate_average?: number + /** + * Minimum refresh rate during the view’s lifetime (in frames per second) + */ + readonly refresh_rate_min?: number + /** + * Time taken for Flutter 'build' methods. + */ + flutter_build_time?: RumPerfMetric + /** + * Time taken for Flutter to rasterize the view. + */ + flutter_raster_time?: RumPerfMetric + /** + * The JavaScript refresh rate for React Native + */ + js_refresh_rate?: RumPerfMetric [k: string]: unknown - }[] + } /** - * Debug metadata for Replay Sessions + * Session properties */ - replay_stats?: { - /** - * The number of records produced during this view lifetime - */ - records_count?: number + readonly session?: { /** - * The number of segments sent during this view lifetime + * Whether this session is currently active. Set to false to manually stop a session */ - segments_count?: number + readonly is_active?: boolean /** - * The total size in bytes of the segments sent during this view lifetime + * Whether this session has been sampled for replay */ - segments_total_raw_size?: number + readonly sampled_for_replay?: boolean [k: string]: unknown } /** - * Subset of the SDK configuration options in use during its execution + * Feature flags properties */ - readonly configuration?: { + readonly feature_flags?: { + [k: string]: unknown + } + /** + * Privacy properties + */ + readonly privacy?: { /** - * Whether session replay recording configured to start manually + * The replay privacy level */ - readonly start_session_replay_recording_manually?: boolean + readonly replay_level: 'allow' | 'mask' | 'mask-user-input' [k: string]: unknown } - [k: string]: unknown - } - /** - * Display properties - */ - readonly display?: { /** - * Scroll properties + * Internal properties */ - readonly scroll?: { + readonly _dd: { /** - * Distance between the top and the lowest point reached on this view (in pixels) + * Version of the update of the view event */ - readonly max_depth: number + readonly document_version: number /** - * Page scroll top (scrolled distance) when the maximum scroll depth was reached for this view (in pixels) + * List of the page states during the view */ - readonly max_depth_scroll_top: number + readonly page_states?: { + /** + * Page state name + */ + readonly state: 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated' + /** + * Duration in ns between start of the view and start of the page state + */ + readonly start: number + [k: string]: unknown + }[] /** - * Maximum page scroll height (total height) for this view (in pixels) + * Debug metadata for Replay Sessions */ - readonly max_scroll_height: number + replay_stats?: { + /** + * The number of records produced during this view lifetime + */ + records_count?: number + /** + * The number of segments sent during this view lifetime + */ + segments_count?: number + /** + * The total size in bytes of the segments sent during this view lifetime + */ + segments_total_raw_size?: number + [k: string]: unknown + } /** - * Duration between the view start and the time the max scroll height was reached for this view (in nanoseconds) + * Subset of the SDK configuration options in use during its execution */ - readonly max_scroll_height_time: number + readonly configuration?: { + /** + * Whether session replay recording configured to start manually + */ + readonly start_session_replay_recording_manually?: boolean + [k: string]: unknown + } + [k: string]: unknown + } + /** + * Display properties + */ + readonly display?: { + /** + * Scroll properties + */ + readonly scroll?: { + /** + * Distance between the top and the lowest point reached on this view (in pixels) + */ + readonly max_depth: number + /** + * Page scroll top (scrolled distance) when the maximum scroll depth was reached for this view (in pixels) + */ + readonly max_depth_scroll_top: number + /** + * Maximum page scroll height (total height) for this view (in pixels) + */ + readonly max_scroll_height: number + /** + * Duration between the view start and the time the max scroll height was reached for this view (in nanoseconds) + */ + readonly max_scroll_height_time: number + [k: string]: unknown + } [k: string]: unknown } [k: string]: unknown } - [k: string]: unknown -} /** * Schema of common properties of RUM events @@ -929,6 +925,10 @@ export interface CommonProperties { * The build version for this application */ readonly build_version?: string + /** + * Generated unique ID of the application build. Unlike version or build_version this field is not meant to be coming from the user, but rather generated by the tooling for each build. + */ + readonly build_id?: string /** * Session properties */ @@ -1141,6 +1141,17 @@ export interface CommonProperties { * Session plan: 1 is the plan without replay, 2 is the plan with replay (deprecated) */ plan?: 1 | 2 + /** + * The precondition that led to the creation of the session + */ + readonly session_precondition?: + | 'user_app_launch' + | 'inactivity_timeout' + | 'max_duration' + | 'background_launch' + | 'prewarm' + | 'from_non_interactive_session' + | 'explicit_stop' [k: string]: unknown } /** @@ -1171,6 +1182,32 @@ export interface CommonProperties { } [k: string]: unknown } +/** + * View Container schema for views that are nested (webviews in mobile) + */ +export interface ViewContainerSchema { + /** + * View Container properties (view wrapping the current view) + */ + readonly container?: { + /** + * Attributes of the view's container + */ + readonly view: { + /** + * ID of the parent view + */ + readonly id: string + [k: string]: unknown + } + /** + * Source of the parent view + */ + readonly source: 'android' | 'ios' | 'browser' | 'flutter' | 'react-native' | 'roku' + [k: string]: unknown + } + [k: string]: unknown +} /** * Schema of all properties of events that can have parent actions */ diff --git a/packages/rum/src/types/sessionReplay.ts b/packages/rum/src/types/sessionReplay.ts index cc3060ac41..368b06dc3b 100644 --- a/packages/rum/src/types/sessionReplay.ts +++ b/packages/rum/src/types/sessionReplay.ts @@ -48,7 +48,7 @@ export type BrowserRecord = /** * Browser-specific. Schema of a Record type which contains the full snapshot of a screen. */ -export type BrowserFullSnapshotRecord = WebviewSupportedCommonRecordSchema & { +export type BrowserFullSnapshotRecord = SlotSupportedCommonRecordSchema & { /** * The type of this Record. */ @@ -56,13 +56,13 @@ export type BrowserFullSnapshotRecord = WebviewSupportedCommonRecordSchema & { data: BrowserNode } /** - * Schema of common properties for a Record event type that is supported by webviews. + * Schema of common properties for a Record event type that is supported by slots. */ -export type WebviewSupportedCommonRecordSchema = CommonRecordSchema & { +export type SlotSupportedCommonRecordSchema = CommonRecordSchema & { /** - * Defines the unique ID of the nested replay environment that generated this record. + * Unique ID of the slot that generated this record. */ - readonly nestedEnvId?: number + readonly slotId?: string } /** * Serialized node contained by this Record. @@ -77,7 +77,7 @@ export type SerializedNode = DocumentNode | DocumentFragmentNode | DocumentTypeN /** * Browser-specific. Schema of a Record type which contains mutations of a screen. */ -export type BrowserIncrementalSnapshotRecord = WebviewSupportedCommonRecordSchema & { +export type BrowserIncrementalSnapshotRecord = SlotSupportedCommonRecordSchema & { /** * The type of this Record. */ @@ -246,7 +246,7 @@ export type PointerInteractionData = { /** * Schema of a Record which contains the screen properties. */ -export type MetaRecord = WebviewSupportedCommonRecordSchema & { +export type MetaRecord = SlotSupportedCommonRecordSchema & { /** * The type of this Record. */ @@ -272,7 +272,7 @@ export type MetaRecord = WebviewSupportedCommonRecordSchema & { /** * Schema of a Record type which contains focus information. */ -export type FocusRecord = WebviewSupportedCommonRecordSchema & { +export type FocusRecord = SlotSupportedCommonRecordSchema & { /** * The type of this Record. */ @@ -287,7 +287,7 @@ export type FocusRecord = WebviewSupportedCommonRecordSchema & { /** * Schema of a Record which signifies that view lifecycle ended. */ -export type ViewEndRecord = WebviewSupportedCommonRecordSchema & { +export type ViewEndRecord = SlotSupportedCommonRecordSchema & { /** * The type of this Record. */ @@ -296,7 +296,7 @@ export type ViewEndRecord = WebviewSupportedCommonRecordSchema & { /** * Schema of a Record which signifies that the viewport properties have changed. */ -export type VisualViewportRecord = WebviewSupportedCommonRecordSchema & { +export type VisualViewportRecord = SlotSupportedCommonRecordSchema & { data: { height: number offsetLeft: number @@ -314,7 +314,7 @@ export type VisualViewportRecord = WebviewSupportedCommonRecordSchema & { /** * Schema of a Record which signifies a collection of frustration signals. */ -export type FrustrationRecord = WebviewSupportedCommonRecordSchema & { +export type FrustrationRecord = SlotSupportedCommonRecordSchema & { /** * The type of this Record. */ diff --git a/rum-events-format b/rum-events-format index e29a828faf..e792ad1d75 160000 --- a/rum-events-format +++ b/rum-events-format @@ -1 +1 @@ -Subproject commit e29a828fafdab77525429198b731f176e16957f7 +Subproject commit e792ad1d75bd4a375729f37764cd44a3f9233fb0