11
11
*/
12
12
13
13
/* eslint-env browser */
14
-
15
- /**
16
- * log RUM if part of the sample.
17
- * @param {string } checkpoint identifies the checkpoint in funnel
18
- * @param {Object } data additional data for RUM sample
19
- * @param {string } data.source DOM node that is the source of a checkpoint event,
20
- * identified by #id or .classname
21
- * @param {string } data.target subject of the checkpoint event,
22
- * for instance the href of a link, or a search term
23
- */
24
- function sampleRUM ( checkpoint , data = { } ) {
25
- sampleRUM . baseURL = sampleRUM . baseURL || new URL ( window . RUM_BASE == null ? 'https://rum.hlx.page' : window . RUM_BASE , window . location ) ;
26
- sampleRUM . defer = sampleRUM . defer || [ ] ;
27
- const defer = ( fnname ) => {
28
- sampleRUM [ fnname ] = sampleRUM [ fnname ]
29
- || ( ( ...args ) => sampleRUM . defer . push ( { fnname, args } ) ) ;
30
- } ;
31
- sampleRUM . drain = sampleRUM . drain
32
- || ( ( dfnname , fn ) => {
33
- sampleRUM [ dfnname ] = fn ;
34
- sampleRUM . defer
35
- . filter ( ( { fnname } ) => dfnname === fnname )
36
- . forEach ( ( { fnname, args } ) => sampleRUM [ fnname ] ( ...args ) ) ;
37
- } ) ;
38
- sampleRUM . always = sampleRUM . always || [ ] ;
39
- sampleRUM . always . on = ( chkpnt , fn ) => {
40
- sampleRUM . always [ chkpnt ] = fn ;
41
- } ;
42
- sampleRUM . on = ( chkpnt , fn ) => {
43
- sampleRUM . cases [ chkpnt ] = fn ;
44
- } ;
45
- defer ( 'observe' ) ;
46
- defer ( 'cwv' ) ;
14
+ function sampleRUM ( checkpoint , data ) {
15
+ // eslint-disable-next-line max-len
16
+ const timeShift = ( ) => ( window . performance ? window . performance . now ( ) : Date . now ( ) - window . hlx . rum . firstReadTime ) ;
47
17
try {
48
18
window . hlx = window . hlx || { } ;
19
+ sampleRUM . enhance = ( ) => { } ;
49
20
if ( ! window . hlx . rum ) {
50
- const usp = new URLSearchParams ( window . location . search ) ;
51
- const weight = ( usp . get ( 'rum' ) === 'on' ) ? 1 : 100 ; // with parameter, weight is 1. Defaults to 100.
21
+ const weight = new URLSearchParams ( window . location . search ) . get ( 'rum' ) === 'on' ? 1 : 100 ;
52
22
const id = Math . random ( ) . toString ( 36 ) . slice ( - 4 ) ;
53
- const random = Math . random ( ) ;
54
- const isSelected = ( random * weight < 1 ) ;
55
- const firstReadTime = window . performance ? window . performance . timeOrigin : Date . now ( ) ;
56
- const urlSanitizers = {
57
- full : ( ) => window . location . href ,
58
- origin : ( ) => window . location . origin ,
59
- path : ( ) => window . location . href . replace ( / \? .* $ / , '' ) ,
60
- } ;
23
+ const isSelected = Math . random ( ) * weight < 1 ;
61
24
// eslint-disable-next-line object-curly-newline, max-len
62
- window . hlx . rum = { weight, id, random, isSelected, firstReadTime, sampleRUM, sanitizeURL : urlSanitizers [ window . hlx . RUM_MASK_URL || 'path' ] } ;
63
- }
64
-
65
- const { weight, id, firstReadTime } = window . hlx . rum ;
66
- if ( window . hlx && window . hlx . rum && window . hlx . rum . isSelected ) {
67
- const knownProperties = [ 'weight' , 'id' , 'referer' , 'checkpoint' , 't' , 'source' , 'target' , 'cwv' , 'CLS' , 'FID' , 'LCP' , 'INP' , 'TTFB' ] ;
68
- const sendPing = ( pdata = data ) => {
69
- // eslint-disable-next-line max-len
70
- const t = Math . round ( window . performance ? window . performance . now ( ) : ( Date . now ( ) - firstReadTime ) ) ;
71
- // eslint-disable-next-line object-curly-newline, max-len, no-use-before-define
72
- const body = JSON . stringify ( { weight, id, referer : window . hlx . rum . sanitizeURL ( ) , checkpoint, t, ...data } , knownProperties ) ;
25
+ window . hlx . rum = {
26
+ weight,
27
+ id,
28
+ isSelected,
29
+ firstReadTime : window . performance ? window . performance . timeOrigin : Date . now ( ) ,
30
+ sampleRUM,
31
+ queue : [ ] ,
32
+ collector : ( ...args ) => window . hlx . rum . queue . push ( args ) ,
33
+ } ;
34
+ if ( isSelected ) {
35
+ [ 'error' , 'unhandledrejection' ] . forEach ( ( event ) => {
36
+ window . addEventListener ( event , ( { reason, error } ) => {
37
+ const errData = { source : 'undefined error' } ;
38
+ try {
39
+ errData . target = ( reason || error ) . toString ( ) ;
40
+ errData . source = ( reason || error ) . stack
41
+ . split ( '\n' )
42
+ . filter ( ( line ) => line . match ( / h t t p s ? : \/ \/ / ) )
43
+ . shift ( )
44
+ . replace ( / a t ( [ ^ ] + ) \( ( .+ ) \) / , '$1@$2' )
45
+ . trim ( ) ;
46
+ } catch ( err ) {
47
+ /* error structure was not as expected */
48
+ }
49
+ sampleRUM ( 'error' , errData ) ;
50
+ } ) ;
51
+ } ) ;
52
+ sampleRUM . baseURL = sampleRUM . baseURL || new URL ( window . RUM_BASE || '/' , new URL ( 'https://rum.hlx.page' ) ) ;
53
+ sampleRUM . collectBaseURL = sampleRUM . collectBaseURL || sampleRUM . baseURL ;
54
+ // eslint-disable-next-line object-curly-newline, max-len
55
+ const body = JSON . stringify ( {
56
+ weight,
57
+ id,
58
+ referer : window . location . href ,
59
+ checkpoint : 'top' ,
60
+ t : timeShift ( ) ,
61
+ target : document . visibilityState ,
62
+ } ) ;
73
63
const url = new URL ( `.rum/${ weight } ` , sampleRUM . baseURL ) . href ;
74
64
navigator . sendBeacon ( url , body ) ;
75
- // eslint-disable-next-line no-console
76
- console . debug ( `ping:${ checkpoint } ` , pdata ) ;
77
- } ;
78
- sampleRUM . cases = sampleRUM . cases || {
79
- cwv : ( ) => sampleRUM . cwv ( data ) || true ,
80
- lazy : ( ) => {
81
- // use classic script to avoid CORS issues
65
+
66
+ sampleRUM . enhance = ( ) => {
82
67
const script = document . createElement ( 'script' ) ;
83
- script . src = new URL ( '.rum/@adobe/helix-rum-enhancer@^1/src/index.js' , sampleRUM . baseURL ) . href ;
68
+ script . src = new URL (
69
+ '.rum/@adobe/helix-rum-enhancer@^2/src/index.js' ,
70
+ sampleRUM . baseURL ,
71
+ ) . href ;
84
72
document . head . appendChild ( script ) ;
85
- return true ;
86
- } ,
87
- } ;
88
- sendPing ( data ) ;
89
- if ( sampleRUM . cases [ checkpoint ] ) {
90
- sampleRUM . cases [ checkpoint ] ( ) ;
73
+ } ;
74
+ if ( ! window . hlx . RUM_MANUAL_ENHANCE ) {
75
+ sampleRUM . enhance ( ) ;
76
+ }
91
77
}
92
78
}
93
- if ( sampleRUM . always [ checkpoint ] ) {
94
- sampleRUM . always [ checkpoint ] ( data ) ;
79
+ if ( window . hlx . rum && window . hlx . rum . isSelected && checkpoint ) {
80
+ window . hlx . rum . collector ( checkpoint , data , timeShift ( ) ) ;
95
81
}
82
+ document . dispatchEvent ( new CustomEvent ( 'rum' , { detail : { checkpoint, data } } ) ) ;
96
83
} catch ( error ) {
97
84
// something went wrong
98
85
}
@@ -104,6 +91,7 @@ function sampleRUM(checkpoint, data = {}) {
104
91
function setup ( ) {
105
92
window . hlx = window . hlx || { } ;
106
93
window . hlx . RUM_MASK_URL = 'full' ;
94
+ window . hlx . RUM_MANUAL_ENHANCE = true ;
107
95
window . hlx . codeBasePath = '' ;
108
96
window . hlx . lighthouse = new URLSearchParams ( window . location . search ) . get ( 'lighthouse' ) === 'on' ;
109
97
@@ -124,17 +112,8 @@ function setup() {
124
112
125
113
function init ( ) {
126
114
setup ( ) ;
127
- sampleRUM ( 'top' ) ;
128
-
129
- window . addEventListener ( 'load' , ( ) => sampleRUM ( 'load' ) ) ;
130
-
131
- window . addEventListener ( 'unhandledrejection' , ( event ) => {
132
- sampleRUM ( 'error' , { source : event . reason . sourceURL , target : event . reason . line } ) ;
133
- } ) ;
134
-
135
- window . addEventListener ( 'error' , ( event ) => {
136
- sampleRUM ( 'error' , { source : event . filename , target : event . lineno } ) ;
137
- } ) ;
115
+ sampleRUM ( ) ;
116
+ window . addEventListener ( 'hlx:section:loaded' , sampleRUM . enhance , { once : true } ) ;
138
117
}
139
118
140
119
/**
@@ -533,6 +512,7 @@ function updateSectionsStatus(main) {
533
512
} else {
534
513
section . dataset . sectionStatus = 'loaded' ;
535
514
section . style . display = null ;
515
+ window . dispatchEvent ( new CustomEvent ( 'hlx:section:loaded' , { detail : { section } } ) ) ;
536
516
}
537
517
}
538
518
}
0 commit comments