UNPKG

@sentry/react-native

Version:
78 lines 3.6 kB
import { logger, timestampInSeconds } from '@sentry/core'; import { NATIVE } from '../wrapper'; import { createSentryEventEmitter, NewFrameEventName } from './sentryeventemitter'; export const FALLBACK_TIMEOUT_MS = 10000; /** * Creates emitter that allows to listen to UI Frame events when ready. */ export function createSentryFallbackEventEmitter(emitter = createSentryEventEmitter(), fallbackTimeoutMs = FALLBACK_TIMEOUT_MS) { let fallbackTimeout; let animationFrameTimestampSeconds; let nativeNewFrameTimestampSeconds; function getAnimationFrameTimestampSeconds() { // https://reactnative.dev/docs/timers#timers // NOTE: The current implementation of requestAnimationFrame is the same // as setTimeout(0). This isn't exactly how requestAnimationFrame // is supposed to work on web, so it doesn't get called when UI Frames are rendered.: https://github.com/facebook/react-native/blob/5106933c750fee2ce49fe1945c3e3763eebc92bc/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp#L442-L443 requestAnimationFrame(() => { if (fallbackTimeout === undefined) { return; } animationFrameTimestampSeconds = timestampInSeconds(); }); } function getNativeNewFrameTimestampSeconds() { NATIVE.getNewScreenTimeToDisplay() .then(resolve => { if (fallbackTimeout === undefined) { return; } nativeNewFrameTimestampSeconds = resolve !== null && resolve !== void 0 ? resolve : undefined; }) .catch(reason => { logger.error('Failed to receive Native fallback timestamp.', reason); }); } return { initAsync() { emitter.initAsync(NewFrameEventName); }, onceNewFrame(listener) { animationFrameTimestampSeconds = undefined; nativeNewFrameTimestampSeconds = undefined; const internalListener = (event) => { if (fallbackTimeout !== undefined) { clearTimeout(fallbackTimeout); fallbackTimeout = undefined; } animationFrameTimestampSeconds = undefined; nativeNewFrameTimestampSeconds = undefined; listener(event); }; fallbackTimeout = setTimeout(() => { if (nativeNewFrameTimestampSeconds) { logger.log('Native event emitter did not reply in time'); return listener({ newFrameTimestampInSeconds: nativeNewFrameTimestampSeconds, isFallback: true, }); } else if (animationFrameTimestampSeconds) { logger.log('[Sentry] Native event emitter did not reply in time. Using JavaScript fallback emitter.'); return listener({ newFrameTimestampInSeconds: animationFrameTimestampSeconds, isFallback: true, }); } else { emitter.removeListener(NewFrameEventName, internalListener); logger.error('Failed to receive any fallback timestamp.'); } }, fallbackTimeoutMs); getNativeNewFrameTimestampSeconds(); getAnimationFrameTimestampSeconds(); emitter.once(NewFrameEventName, internalListener); }, }; } //# sourceMappingURL=sentryeventemitterfallback.js.map