@@ -6,13 +6,14 @@ import {
66 createEventRateLimiter ,
77 isExperimentalFeatureEnabled ,
88 ExperimentalFeature ,
9+ BufferedObservable ,
910 HookNames ,
1011 DISCARDED ,
1112} from '@datadog/browser-core'
1213import type { RumEventDomainContext } from '../domainContext.types'
1314import { RumEventType } from '../rawRumEvent.types'
1415import type { RumEvent } from '../rumEvent.types'
15- import type { LifeCycle } from './lifeCycle'
16+ import type { LifeCycle , RawRumEventCollectedData } from './lifeCycle'
1617import { LifeCycleEventType } from './lifeCycle'
1718import type { RumConfiguration } from './configuration'
1819import type { ModifiableFieldPaths } from './limitModification'
@@ -34,6 +35,10 @@ const ROOT_MODIFIABLE_FIELD_PATHS: ModifiableFieldPaths = {
3435 version : 'string' ,
3536}
3637
38+ // The size of the buffer for events that are collected just after starting the assembly. This is a
39+ // bit arbitrary, but should be large enough to avoid dropping events in most cases.
40+ const BUFFERED_EVENT_SIZE = 100
41+
3742let modifiableFieldPathsByEvent : { [ key in RumEventType ] : ModifiableFieldPaths }
3843
3944export function startRumAssembly (
@@ -102,30 +107,32 @@ export function startRumAssembly(
102107 ) ,
103108 }
104109
105- lifeCycle . subscribe (
106- LifeCycleEventType . RAW_RUM_EVENT_COLLECTED ,
107- ( { startTime, duration, rawRumEvent, domainContext, customerContext } ) => {
108- const defaultRumEventAttributes = hooks . triggerHook ( HookNames . Assemble , {
109- eventType : rawRumEvent . type ,
110- startTime,
111- duration,
112- } ) !
110+ const observable = new BufferedObservable < RawRumEventCollectedData > ( BUFFERED_EVENT_SIZE )
113111
114- if ( defaultRumEventAttributes === DISCARDED ) {
115- return
116- }
112+ lifeCycle . subscribe ( LifeCycleEventType . RAW_RUM_EVENT_COLLECTED , ( data ) => observable . notify ( data ) )
113+
114+ observable . subscribe ( ( { startTime, duration, rawRumEvent, domainContext, customerContext } ) => {
115+ const defaultRumEventAttributes = hooks . triggerHook ( HookNames . Assemble , {
116+ eventType : rawRumEvent . type ,
117+ startTime,
118+ duration,
119+ } ) !
120+
121+ if ( defaultRumEventAttributes === DISCARDED ) {
122+ return
123+ }
117124
118- const serverRumEvent = combine ( defaultRumEventAttributes , { context : customerContext } , rawRumEvent ) as RumEvent &
119- Context
125+ const serverRumEvent = combine ( defaultRumEventAttributes , { context : customerContext } , rawRumEvent ) as RumEvent &
126+ Context
120127
121- if ( shouldSend ( serverRumEvent , configuration . beforeSend , domainContext , eventRateLimiters ) ) {
122- if ( isEmptyObject ( serverRumEvent . context ! ) ) {
123- delete serverRumEvent . context
124- }
125- lifeCycle . notify ( LifeCycleEventType . RUM_EVENT_COLLECTED , serverRumEvent )
128+ if ( shouldSend ( serverRumEvent , configuration . beforeSend , domainContext , eventRateLimiters ) ) {
129+ if ( isEmptyObject ( serverRumEvent . context ! ) ) {
130+ delete serverRumEvent . context
126131 }
132+ lifeCycle . notify ( LifeCycleEventType . RUM_EVENT_COLLECTED , serverRumEvent )
127133 }
128- )
134+ } )
135+ observable . unbuffer ( )
129136}
130137
131138function shouldSend (
0 commit comments