@@ -38,8 +38,8 @@ import {
38
38
EventType ,
39
39
isDeadClick ,
40
40
isDeadRageClick ,
41
- isLCPFrame ,
42
41
isPaintFrame ,
42
+ isWebVitalFrame ,
43
43
} from 'sentry/utils/replays/types' ;
44
44
import type { ReplayError , ReplayRecord } from 'sentry/views/replays/types' ;
45
45
@@ -69,6 +69,11 @@ interface ReplayReaderParams {
69
69
* If provided, the replay will be clipped to this window.
70
70
*/
71
71
clipWindow ?: ClipWindow ;
72
+
73
+ /**
74
+ * The org's feature flags
75
+ */
76
+ featureFlags ?: string [ ] ;
72
77
}
73
78
74
79
type RequiredNotNull < T > = {
@@ -134,13 +139,25 @@ function removeDuplicateNavCrumbs(
134
139
}
135
140
136
141
export default class ReplayReader {
137
- static factory ( { attachments, errors, replayRecord, clipWindow} : ReplayReaderParams ) {
142
+ static factory ( {
143
+ attachments,
144
+ errors,
145
+ replayRecord,
146
+ clipWindow,
147
+ featureFlags,
148
+ } : ReplayReaderParams ) {
138
149
if ( ! attachments || ! replayRecord || ! errors ) {
139
150
return null ;
140
151
}
141
152
142
153
try {
143
- return new ReplayReader ( { attachments, errors, replayRecord, clipWindow} ) ;
154
+ return new ReplayReader ( {
155
+ attachments,
156
+ errors,
157
+ replayRecord,
158
+ featureFlags,
159
+ clipWindow,
160
+ } ) ;
144
161
} catch ( err ) {
145
162
Sentry . captureException ( err ) ;
146
163
@@ -151,6 +168,7 @@ export default class ReplayReader {
151
168
return new ReplayReader ( {
152
169
attachments : [ ] ,
153
170
errors : [ ] ,
171
+ featureFlags,
154
172
replayRecord,
155
173
clipWindow,
156
174
} ) ;
@@ -160,6 +178,7 @@ export default class ReplayReader {
160
178
private constructor ( {
161
179
attachments,
162
180
errors,
181
+ featureFlags,
163
182
replayRecord,
164
183
clipWindow,
165
184
} : RequiredNotNull < ReplayReaderParams > ) {
@@ -205,6 +224,7 @@ export default class ReplayReader {
205
224
206
225
// Hydrate the data we were given
207
226
this . _replayRecord = replayRecord ;
227
+ this . _featureFlags = featureFlags ;
208
228
// Errors don't need to be sorted here, they will be merged with breadcrumbs
209
229
// and spans in the getter and then sorted together.
210
230
const { errorFrames, feedbackFrames} = hydrateErrors ( replayRecord , errors ) ;
@@ -244,6 +264,7 @@ export default class ReplayReader {
244
264
private _cacheKey : string ;
245
265
private _duration : Duration = duration ( 0 ) ;
246
266
private _errors : ErrorFrame [ ] = [ ] ;
267
+ private _featureFlags : string [ ] | undefined = [ ] ;
247
268
private _optionFrame : undefined | OptionFrame ;
248
269
private _replayRecord : ReplayRecord ;
249
270
private _sortedBreadcrumbFrames : BreadcrumbFrame [ ] = [ ] ;
@@ -469,6 +490,7 @@ export default class ReplayReader {
469
490
this . _trimFramesToClipWindow (
470
491
[
471
492
...this . getPerfFrames ( ) ,
493
+ ...this . getWebVitalFrames ( ) ,
472
494
...this . _sortedBreadcrumbFrames . filter ( frame =>
473
495
[
474
496
'replay.hydrate-error' ,
@@ -506,7 +528,12 @@ export default class ReplayReader {
506
528
return [ ...uniqueCrumbs , ...spans ] . sort ( sortFrames ) ;
507
529
} ) ;
508
530
509
- getLPCFrames = memoize ( ( ) => this . _sortedSpanFrames . filter ( isLCPFrame ) ) ;
531
+ getWebVitalFrames = memoize ( ( ) => {
532
+ if ( this . _featureFlags ?. includes ( 'session-replay-web-vitals' ) ) {
533
+ return this . _sortedSpanFrames . filter ( isWebVitalFrame ) ;
534
+ }
535
+ return [ ] ;
536
+ } ) ;
510
537
511
538
getVideoEvents = ( ) => this . _videoEvents ;
512
539
0 commit comments