@sentry/react-native
Version:
Official Sentry SDK for react-native
78 lines • 3.6 kB
JavaScript
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