diff --git a/src/js/tracing/reactnavigation.ts b/src/js/tracing/reactnavigation.ts index 00efde39f..6991939d6 100644 --- a/src/js/tracing/reactnavigation.ts +++ b/src/js/tracing/reactnavigation.ts @@ -4,7 +4,8 @@ import type { Span, Transaction as TransactionType, TransactionContext } from '@ import { logger, timestampInSeconds } from '@sentry/utils'; import type { NewFrameEvent } from '../utils/sentryeventemitter'; -import { type SentryEventEmitter, createSentryEventEmitter, NewFrameEventName } from '../utils/sentryeventemitter'; +import type { SentryEventEmitterFallback } from '../utils/sentryeventemitterfallback'; +import { createSentryFallbackEventEmitter } from '../utils/sentryeventemitterfallback'; import { RN_GLOBAL_OBJ } from '../utils/worldwide'; import { NATIVE } from '../wrapper'; import type { OnConfirmRoute, TransactionCreator } from './routingInstrumentation'; @@ -77,7 +78,7 @@ export class ReactNavigationInstrumentation extends InternalRoutingInstrumentati public readonly name: string = ReactNavigationInstrumentation.instrumentationName; private _navigationContainer: NavigationContainer | null = null; - private _newScreenFrameEventEmitter: SentryEventEmitter | null = null; + private _newScreenFrameEventEmitter: SentryEventEmitterFallback | null = null; private readonly _maxRecentRouteLen: number = 200; private _latestRoute?: NavigationRoute; @@ -85,7 +86,7 @@ export class ReactNavigationInstrumentation extends InternalRoutingInstrumentati private _navigationProcessingSpan?: Span; private _initialStateHandled: boolean = false; - private _stateChangeTimeout?: number | undefined; + private _stateChangeTimeout?: ReturnType | undefined; private _recentRouteKeys: string[] = []; private _options: ReactNavigationOptions; @@ -99,8 +100,8 @@ export class ReactNavigationInstrumentation extends InternalRoutingInstrumentati }; if (this._options.enableTimeToInitialDisplay) { - this._newScreenFrameEventEmitter = createSentryEventEmitter(); - this._newScreenFrameEventEmitter.initAsync(NewFrameEventName); + this._newScreenFrameEventEmitter = createSentryFallbackEventEmitter(); + this._newScreenFrameEventEmitter.initAsync(); NATIVE.initNativeReactNavigationNewFrameTracking().catch((reason: unknown) => { logger.error(`[ReactNavigationInstrumentation] Failed to initialize native new frame tracking: ${reason}`); }); @@ -247,8 +248,7 @@ export class ReactNavigationInstrumentation extends InternalRoutingInstrumentati }); if (!routeHasBeenSeen && latestTtidSpan) { - this._newScreenFrameEventEmitter?.once( - NewFrameEventName, + this._newScreenFrameEventEmitter?.onceNewFrame( ({ newFrameTimestampInSeconds }: NewFrameEvent) => { const activeSpan = getActiveSpan(); if (activeSpan && manualInitialDisplaySpans.has(activeSpan)) { diff --git a/src/js/utils/sentryeventemitter.ts b/src/js/utils/sentryeventemitter.ts index d231c787a..63146f30c 100644 --- a/src/js/utils/sentryeventemitter.ts +++ b/src/js/utils/sentryeventemitter.ts @@ -3,7 +3,6 @@ import type { EmitterSubscription, NativeModule } from 'react-native'; import { NativeEventEmitter } from 'react-native'; import { getRNSentryModule } from '../wrapper'; -import { createSentryFallbackEventEmitter } from './sentryeventemitterfallback'; export const NewFrameEventName = 'rn_sentry_new_frame'; export type NewFrameEventName = typeof NewFrameEventName; @@ -33,7 +32,6 @@ export function createSentryEventEmitter( if (!sentryNativeModule) { return createNoopSentryEventEmitter(); } - const fallbackEventEmitter = createSentryFallbackEventEmitter(); const openNativeListeners = new Map(); const listenersMap = new Map void, true>>(); @@ -72,8 +70,6 @@ export function createSentryEventEmitter( openNativeListeners.set(eventType, nativeListener); listenersMap.set(eventType, new Map()); - - fallbackEventEmitter.initAsync(); }, closeAllAsync() { openNativeListeners.forEach(subscription => { @@ -85,8 +81,6 @@ export function createSentryEventEmitter( addListener, removeListener, once(eventType: NewFrameEventName, listener: (event: NewFrameEvent) => void) { - fallbackEventEmitter?.onceNewFrame(); - const tmpListener = (event: NewFrameEvent): void => { listener(event); removeListener(eventType, tmpListener); diff --git a/src/js/utils/sentryeventemitterfallback.ts b/src/js/utils/sentryeventemitterfallback.ts index 8bc82c900..60fe8928a 100644 --- a/src/js/utils/sentryeventemitterfallback.ts +++ b/src/js/utils/sentryeventemitterfallback.ts @@ -23,7 +23,7 @@ export function createSentryFallbackEventEmitter( emitter: SentryEventEmitter = createSentryEventEmitter(), fallbackTimeoutMs = FALLBACK_TIMEOUT_MS, ): SentryEventEmitterFallback { - let fallbackTimeout: ReturnType | undefined; + let fallbackTimeout: ReturnType | undefined; let animationFrameTimestampSeconds: number | undefined; let nativeNewFrameTimestampSeconds: number | undefined; @@ -63,8 +63,10 @@ export function createSentryFallbackEventEmitter( nativeNewFrameTimestampSeconds = undefined; const internalListener = (event: NewFrameEvent): void => { - clearTimeout(fallbackTimeout); - fallbackTimeout = undefined; + if (fallbackTimeout !== undefined) { + clearTimeout(fallbackTimeout); + fallbackTimeout = undefined; + } animationFrameTimestampSeconds = undefined; nativeNewFrameTimestampSeconds = undefined; listener(event);