@@ -52,20 +52,26 @@ interface BrowserWebVitalsStartOptions extends BrowserWebVitalsOptions {
5252 metricRecorder ?: BrowserWebVitalsMetricRecorder
5353}
5454
55+ let startupPromise : Promise < void > | undefined
56+ let currentMetricRecorder : BrowserWebVitalsMetricRecorder | undefined
57+
5558function createHandle ( metricRecorder : BrowserWebVitalsMetricRecorder | undefined ) : BrowserWebVitalsHandle {
59+ let shutdownCalled = false
5660 return {
5761 async shutdown ( ) {
62+ if ( shutdownCalled ) {
63+ return Promise . resolve ( )
64+ }
65+ shutdownCalled = true
5866 metricRecorder ?. shutdown ( )
67+ if ( currentMetricRecorder === metricRecorder ) {
68+ currentMetricRecorder = undefined
69+ }
5970 return Promise . resolve ( )
6071 } ,
6172 }
6273}
6374
64- const noopHandle = createHandle ( undefined )
65-
66- let startupPromise : Promise < BrowserWebVitalsHandle > | undefined
67- let startupHasMetricRecorder = false
68-
6975function setPrimitiveAttribute ( attributes : Attributes , key : string , value : unknown ) : void {
7076 if ( typeof value === 'string' || typeof value === 'boolean' ) {
7177 attributes [ key ] = value
@@ -194,44 +200,36 @@ function reportWebVital(metric: MetricWithAttribution, metricRecorder: BrowserWe
194200 reportWebVitalMetric ( metric , metricRecorder )
195201}
196202
197- function registerWebVitals ( webVitals : WebVitalsAttributionModule , options : BrowserWebVitalsStartOptions = { } ) : BrowserWebVitalsHandle {
203+ function registerWebVitals ( webVitals : WebVitalsAttributionModule , options : BrowserWebVitalsStartOptions = { } ) : void {
198204 const reportOptions = createBaseReportOptions ( options )
199205 const report = ( metric : MetricWithAttribution ) => {
200- reportWebVital ( metric , options . metricRecorder )
206+ reportWebVital ( metric , currentMetricRecorder )
201207 }
202208 webVitals . onLCP ( report , reportOptions )
203209 webVitals . onINP ( report , createInpReportOptions ( options ) )
204210 webVitals . onCLS ( report , reportOptions )
205211 webVitals . onFCP ( report , reportOptions )
206212 webVitals . onTTFB ( report , reportOptions )
207- return createHandle ( options . metricRecorder )
208- }
209-
210- export function assertBrowserWebVitalsMetricsCanStart ( ) : void {
211- if ( startupPromise !== undefined && ! startupHasMetricRecorder ) {
212- throw new Error (
213- 'logfire-browser: Web Vitals were already started without metrics in this page lifecycle; configure rum.webVitals.metrics before the first Web Vitals startup'
214- )
215- }
216213}
217214
218215export async function startBrowserWebVitals ( options : BrowserWebVitalsStartOptions = { } ) : Promise < BrowserWebVitalsHandle > {
219216 if ( options . metricRecorder !== undefined ) {
220- assertBrowserWebVitalsMetricsCanStart ( )
217+ currentMetricRecorder = options . metricRecorder
221218 }
222219
223220 startupPromise ??= import ( 'web-vitals/attribution' )
224- . then ( ( webVitals ) => registerWebVitals ( webVitals , options ) )
221+ . then ( ( webVitals ) => {
222+ registerWebVitals ( webVitals , options )
223+ } )
225224 . catch ( ( error : unknown ) => {
226225 diag . error ( 'logfire-browser: failed to start Web Vitals reporting' , error )
227- return noopHandle
228226 } )
229- startupHasMetricRecorder ||= options . metricRecorder !== undefined
230227
231- return startupPromise
228+ await startupPromise
229+ return createHandle ( options . metricRecorder )
232230}
233231
234232export function resetBrowserWebVitalsForTests ( ) : void {
235233 startupPromise = undefined
236- startupHasMetricRecorder = false
234+ currentMetricRecorder = undefined
237235}
0 commit comments