@sentry/react-native 7.7.0 → 7.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +1 -1
- package/android/libs/replay-stubs.jar +0 -0
- package/android/replay-stubs/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -1
- package/dist/js/feedback/integration.d.ts.map +1 -1
- package/dist/js/feedback/integration.js.map +1 -1
- package/dist/js/index.d.ts +2 -2
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +1 -1
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/replay/mobilereplay.d.ts.map +1 -1
- package/dist/js/replay/mobilereplay.js +29 -7
- package/dist/js/replay/mobilereplay.js.map +1 -1
- package/dist/js/tracing/integrations/nativeFrames.d.ts +2 -1
- package/dist/js/tracing/integrations/nativeFrames.d.ts.map +1 -1
- package/dist/js/tracing/integrations/nativeFrames.js +68 -25
- package/dist/js/tracing/integrations/nativeFrames.js.map +1 -1
- package/dist/js/tracing/reactnavigation.d.ts +12 -1
- package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
- package/dist/js/tracing/reactnavigation.js +41 -8
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/tracing/timetodisplay.d.ts.map +1 -1
- package/dist/js/tracing/timetodisplay.js +206 -21
- package/dist/js/tracing/timetodisplay.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +2 -2
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +12 -12
- package/ts3.8/dist/js/index.d.ts +2 -2
- package/ts3.8/dist/js/tracing/integrations/nativeFrames.d.ts +2 -1
- package/ts3.8/dist/js/tracing/reactnavigation.d.ts +12 -1
- package/ts3.8/dist/js/version.d.ts +1 -1
package/android/build.gradle
CHANGED
|
Binary file
|
|
@@ -2,7 +2,7 @@ package io.sentry.react;
|
|
|
2
2
|
|
|
3
3
|
class RNSentryVersion {
|
|
4
4
|
static final String REACT_NATIVE_SDK_PACKAGE_NAME = "npm:@sentry/react-native";
|
|
5
|
-
static final String REACT_NATIVE_SDK_PACKAGE_VERSION = "7.
|
|
5
|
+
static final String REACT_NATIVE_SDK_PACKAGE_VERSION = "7.8.0";
|
|
6
6
|
static final String NATIVE_SDK_NAME = "sentry.native.android.react-native";
|
|
7
7
|
static final String ANDROID_SDK_NAME = "sentry.java.android.react-native";
|
|
8
8
|
static final String REACT_NATIVE_SDK_NAME = "sentry.javascript.react-native";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidgetProvider.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,
|
|
1
|
+
{"version":3,"file":"FeedbackWidgetProvider.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAmK,MAAM,cAAc,CAAC;AAMzM,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAenE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC1C,eAAe,EAAE,OAAO,CAAC;IACzB,yBAAyB,EAAE,OAAO,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC;IAClC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC;IAC/E,KAAK,EAAE,2BAA2B,CAOvC;IAEF,OAAO,CAAC,cAAc,CAAsC;IAE5D,OAAO,CAAC,aAAa,CA8BlB;gBAEgB,KAAK,EAAE,2BAA2B;IAOrD;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAMhC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAMnC;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,2BAA2B,GAAG,IAAI;IAuBxF;;OAEG;IACI,MAAM,IAAI,KAAK,CAAC,SAAS;IAwDhC,OAAO,CAAC,aAAa,CAEnB;IAEF,OAAO,CAAC,sBAAsB,CA0B5B;IAEF,OAAO,CAAC,4BAA4B,CAElC;IAEF,OAAO,CAAC,sCAAsC,CAE5C;IAEF,OAAO,CAAC,YAAY,CAElB;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackWidgetProvider.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { debug } from '@sentry/core';\nimport * as React from 'react';\nimport { type NativeEventSubscription, type NativeScrollEvent,type NativeSyntheticEvent, Animated, Appearance, Dimensions, Easing, Modal, PanResponder, Platform, ScrollView, View } from 'react-native';\nimport { notWeb } from '../utils/environment';\nimport { FeedbackButton } from './FeedbackButton';\nimport { FeedbackWidget } from './FeedbackWidget';\nimport { modalSheetContainer,modalWrapper, topSpacer } from './FeedbackWidget.styles';\nimport { getTheme } from './FeedbackWidget.theme';\nimport type { FeedbackWidgetStyles } from './FeedbackWidget.types';\nimport {\n BACKGROUND_ANIMATION_DURATION,\n FeedbackButtonManager,\n FeedbackWidgetManager,\n PULL_DOWN_CLOSE_THRESHOLD,\n ScreenshotButtonManager,\n SLIDE_ANIMATION_DURATION,\n} from './FeedbackWidgetManager';\nimport { getFeedbackButtonOptions, getFeedbackOptions, getScreenshotButtonOptions } from './integration';\nimport { ScreenshotButton } from './ScreenshotButton';\nimport { isModalSupported, isNativeDriverSupportedForColorAnimations } from './utils';\n\nconst useNativeDriverForColorAnimations = isNativeDriverSupportedForColorAnimations();\n\nexport interface FeedbackWidgetProviderProps {\n children: React.ReactNode;\n styles?: FeedbackWidgetStyles;\n}\n\nexport interface FeedbackWidgetProviderState {\n isButtonVisible: boolean;\n isScreenshotButtonVisible: boolean;\n isVisible: boolean;\n backgroundOpacity: Animated.Value;\n panY: Animated.Value;\n isScrollAtTop: boolean;\n}\n\n/**\n * FeedbackWidgetProvider is a component that wraps the feedback widget and provides\n * functionality to show and hide the widget. It also manages the visibility of the\n * feedback button and screenshot button.\n */\nexport class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {\n public state: FeedbackWidgetProviderState = {\n isButtonVisible: false,\n isScreenshotButtonVisible: false,\n isVisible: false,\n backgroundOpacity: new Animated.Value(0),\n panY: new Animated.Value(Dimensions.get('screen').height),\n isScrollAtTop: true,\n };\n\n private _themeListener: NativeEventSubscription | undefined;\n\n private _panResponder = PanResponder.create({\n onStartShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onMoveShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onPanResponderMove: (_, gestureState) => {\n if (gestureState.dy > 0) {\n this.state.panY.setValue(gestureState.dy);\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {\n // Close on swipe below a certain threshold\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n }).start(() => {\n this._handleClose();\n });\n } else {\n // Animate it back to the original position\n Animated.spring(this.state.panY, {\n toValue: 0,\n useNativeDriver: true,\n }).start();\n }\n },\n });\n\n public constructor(props: FeedbackWidgetProviderProps) {\n super(props);\n FeedbackButtonManager.initialize(this._setButtonVisibilityFunction);\n ScreenshotButtonManager.initialize(this._setScreenshotButtonVisibilityFunction);\n FeedbackWidgetManager.initialize(this._setVisibilityFunction);\n }\n\n /**\n * Add a listener to the theme change event.\n */\n public componentDidMount(): void {\n this._themeListener = Appearance.addChangeListener(() => {\n this.forceUpdate();\n });\n }\n\n /**\n * Clean up the theme listener.\n */\n public componentWillUnmount(): void {\n if (this._themeListener) {\n this._themeListener.remove();\n }\n }\n\n /**\n * Animates the background opacity when the modal is shown.\n */\n public componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void {\n if (!prevState.isVisible && this.state.isVisible) {\n Animated.parallel([\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 1,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.in(Easing.quad),\n }),\n Animated.timing(this.state.panY, {\n toValue: 0,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.in(Easing.quad),\n }),\n ]).start(() => {\n debug.log('FeedbackWidgetProvider componentDidUpdate');\n });\n } else if (prevState.isVisible && !this.state.isVisible) {\n this.state.backgroundOpacity.setValue(0);\n }\n }\n\n /**\n * Renders the feedback form modal.\n */\n public render(): React.ReactNode {\n if (!isModalSupported()) {\n debug.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');\n return <>{this.props.children}</>;\n }\n\n const theme = getTheme();\n\n const { isButtonVisible, isScreenshotButtonVisible, isVisible, backgroundOpacity } = this.state;\n\n const backgroundColor = backgroundOpacity.interpolate({\n inputRange: [0, 1],\n outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],\n });\n\n // Wrapping the `Modal` component in a `View` component is necessary to avoid\n // issues like https://github.com/software-mansion/react-native-reanimated/issues/6035\n return (\n <>\n {this.props.children}\n {isButtonVisible && <FeedbackButton {...getFeedbackButtonOptions()} />}\n {isScreenshotButtonVisible && <ScreenshotButton {...getScreenshotButtonOptions()} />}\n {isVisible && (\n <Animated.View style={[modalWrapper, { backgroundColor }]}>\n <Modal\n visible={isVisible}\n transparent\n animationType=\"none\"\n onRequestClose={this._handleClose}\n testID=\"feedback-form-modal\"\n >\n <View style={topSpacer} />\n <Animated.View\n style={[modalSheetContainer(theme), { transform: [{ translateY: this.state.panY }] }]}\n {...this._panResponder.panHandlers}\n >\n <ScrollView\n bounces={false}\n keyboardShouldPersistTaps=\"handled\"\n automaticallyAdjustKeyboardInsets={Platform.OS === 'ios'}\n onScroll={this._handleScroll}\n >\n <FeedbackWidget\n {...getFeedbackOptions()}\n onFormClose={this._handleClose}\n onFormSubmitted={this._handleClose}\n />\n </ScrollView>\n </Animated.View>\n </Modal>\n </Animated.View>\n )}\n </>\n );\n }\n\n private _handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>): void => {\n this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });\n };\n\n private _setVisibilityFunction = (visible: boolean): void => {\n const updateState = (): void => {\n this.setState({ isVisible: visible });\n };\n if (!visible) {\n Animated.parallel([\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.out(Easing.quad),\n }),\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 0,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.out(Easing.quad),\n }),\n ]).start(() => {\n // Change of the state unmount the component\n // which would cancel the animation\n updateState();\n });\n } else {\n updateState();\n }\n };\n\n private _setButtonVisibilityFunction = (visible: boolean): void => {\n this.setState({ isButtonVisible: visible });\n };\n\n private _setScreenshotButtonVisibilityFunction = (visible: boolean): void => {\n this.setState({ isScreenshotButtonVisible: visible });\n };\n\n private _handleClose = (): void => {\n FeedbackWidgetManager.hide();\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FeedbackWidgetProvider.js","sourceRoot":"","sources":["../../../src/js/feedback/FeedbackWidgetProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { debug } from '@sentry/core';\nimport * as React from 'react';\nimport { Animated, Appearance, Dimensions, Easing, Modal, type NativeEventSubscription, type NativeScrollEvent,type NativeSyntheticEvent, PanResponder, Platform, ScrollView, View } from 'react-native';\nimport { notWeb } from '../utils/environment';\nimport { FeedbackButton } from './FeedbackButton';\nimport { FeedbackWidget } from './FeedbackWidget';\nimport { modalSheetContainer,modalWrapper, topSpacer } from './FeedbackWidget.styles';\nimport { getTheme } from './FeedbackWidget.theme';\nimport type { FeedbackWidgetStyles } from './FeedbackWidget.types';\nimport {\n BACKGROUND_ANIMATION_DURATION,\n FeedbackButtonManager,\n FeedbackWidgetManager,\n PULL_DOWN_CLOSE_THRESHOLD,\n ScreenshotButtonManager,\n SLIDE_ANIMATION_DURATION,\n} from './FeedbackWidgetManager';\nimport { getFeedbackButtonOptions, getFeedbackOptions, getScreenshotButtonOptions } from './integration';\nimport { ScreenshotButton } from './ScreenshotButton';\nimport { isModalSupported, isNativeDriverSupportedForColorAnimations } from './utils';\n\nconst useNativeDriverForColorAnimations = isNativeDriverSupportedForColorAnimations();\n\nexport interface FeedbackWidgetProviderProps {\n children: React.ReactNode;\n styles?: FeedbackWidgetStyles;\n}\n\nexport interface FeedbackWidgetProviderState {\n isButtonVisible: boolean;\n isScreenshotButtonVisible: boolean;\n isVisible: boolean;\n backgroundOpacity: Animated.Value;\n panY: Animated.Value;\n isScrollAtTop: boolean;\n}\n\n/**\n * FeedbackWidgetProvider is a component that wraps the feedback widget and provides\n * functionality to show and hide the widget. It also manages the visibility of the\n * feedback button and screenshot button.\n */\nexport class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {\n public state: FeedbackWidgetProviderState = {\n isButtonVisible: false,\n isScreenshotButtonVisible: false,\n isVisible: false,\n backgroundOpacity: new Animated.Value(0),\n panY: new Animated.Value(Dimensions.get('screen').height),\n isScrollAtTop: true,\n };\n\n private _themeListener: NativeEventSubscription | undefined;\n\n private _panResponder = PanResponder.create({\n onStartShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onMoveShouldSetPanResponder: (_, gestureState) => {\n return notWeb() && this.state.isScrollAtTop && gestureState.dy > 0;\n },\n onPanResponderMove: (_, gestureState) => {\n if (gestureState.dy > 0) {\n this.state.panY.setValue(gestureState.dy);\n }\n },\n onPanResponderRelease: (_, gestureState) => {\n if (gestureState.dy > PULL_DOWN_CLOSE_THRESHOLD) {\n // Close on swipe below a certain threshold\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n }).start(() => {\n this._handleClose();\n });\n } else {\n // Animate it back to the original position\n Animated.spring(this.state.panY, {\n toValue: 0,\n useNativeDriver: true,\n }).start();\n }\n },\n });\n\n public constructor(props: FeedbackWidgetProviderProps) {\n super(props);\n FeedbackButtonManager.initialize(this._setButtonVisibilityFunction);\n ScreenshotButtonManager.initialize(this._setScreenshotButtonVisibilityFunction);\n FeedbackWidgetManager.initialize(this._setVisibilityFunction);\n }\n\n /**\n * Add a listener to the theme change event.\n */\n public componentDidMount(): void {\n this._themeListener = Appearance.addChangeListener(() => {\n this.forceUpdate();\n });\n }\n\n /**\n * Clean up the theme listener.\n */\n public componentWillUnmount(): void {\n if (this._themeListener) {\n this._themeListener.remove();\n }\n }\n\n /**\n * Animates the background opacity when the modal is shown.\n */\n public componentDidUpdate(_prevProps: any, prevState: FeedbackWidgetProviderState): void {\n if (!prevState.isVisible && this.state.isVisible) {\n Animated.parallel([\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 1,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.in(Easing.quad),\n }),\n Animated.timing(this.state.panY, {\n toValue: 0,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.in(Easing.quad),\n }),\n ]).start(() => {\n debug.log('FeedbackWidgetProvider componentDidUpdate');\n });\n } else if (prevState.isVisible && !this.state.isVisible) {\n this.state.backgroundOpacity.setValue(0);\n }\n }\n\n /**\n * Renders the feedback form modal.\n */\n public render(): React.ReactNode {\n if (!isModalSupported()) {\n debug.error('FeedbackWidget Modal is not supported in React Native < 0.71 with Fabric renderer.');\n return <>{this.props.children}</>;\n }\n\n const theme = getTheme();\n\n const { isButtonVisible, isScreenshotButtonVisible, isVisible, backgroundOpacity } = this.state;\n\n const backgroundColor = backgroundOpacity.interpolate({\n inputRange: [0, 1],\n outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.9)'],\n });\n\n // Wrapping the `Modal` component in a `View` component is necessary to avoid\n // issues like https://github.com/software-mansion/react-native-reanimated/issues/6035\n return (\n <>\n {this.props.children}\n {isButtonVisible && <FeedbackButton {...getFeedbackButtonOptions()} />}\n {isScreenshotButtonVisible && <ScreenshotButton {...getScreenshotButtonOptions()} />}\n {isVisible && (\n <Animated.View style={[modalWrapper, { backgroundColor }]}>\n <Modal\n visible={isVisible}\n transparent\n animationType=\"none\"\n onRequestClose={this._handleClose}\n testID=\"feedback-form-modal\"\n >\n <View style={topSpacer} />\n <Animated.View\n style={[modalSheetContainer(theme), { transform: [{ translateY: this.state.panY }] }]}\n {...this._panResponder.panHandlers}\n >\n <ScrollView\n bounces={false}\n keyboardShouldPersistTaps=\"handled\"\n automaticallyAdjustKeyboardInsets={Platform.OS === 'ios'}\n onScroll={this._handleScroll}\n >\n <FeedbackWidget\n {...getFeedbackOptions()}\n onFormClose={this._handleClose}\n onFormSubmitted={this._handleClose}\n />\n </ScrollView>\n </Animated.View>\n </Modal>\n </Animated.View>\n )}\n </>\n );\n }\n\n private _handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>): void => {\n this.setState({ isScrollAtTop: event.nativeEvent.contentOffset.y <= 0 });\n };\n\n private _setVisibilityFunction = (visible: boolean): void => {\n const updateState = (): void => {\n this.setState({ isVisible: visible });\n };\n if (!visible) {\n Animated.parallel([\n Animated.timing(this.state.panY, {\n toValue: Dimensions.get('screen').height,\n duration: SLIDE_ANIMATION_DURATION,\n useNativeDriver: true,\n easing: Easing.out(Easing.quad),\n }),\n Animated.timing(this.state.backgroundOpacity, {\n toValue: 0,\n duration: BACKGROUND_ANIMATION_DURATION,\n useNativeDriver: useNativeDriverForColorAnimations,\n easing: Easing.out(Easing.quad),\n }),\n ]).start(() => {\n // Change of the state unmount the component\n // which would cancel the animation\n updateState();\n });\n } else {\n updateState();\n }\n };\n\n private _setButtonVisibilityFunction = (visible: boolean): void => {\n this.setState({ isButtonVisible: visible });\n };\n\n private _setScreenshotButtonVisibilityFunction = (visible: boolean): void => {\n this.setState({ isScreenshotButtonVisible: visible });\n };\n\n private _handleClose = (): void => {\n FeedbackWidgetManager.hide();\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/integration.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/js/feedback/integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE9G,eAAO,MAAM,gCAAgC,mBAAmB,CAAC;AAEjE,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtC,aAAa,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC5C,uBAAuB,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACxD,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC1C,UAAU,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,mBAAmB,iBACjB,QAAQ,mBAAmB,CAAC,GAAG;IAC1C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,uBAAuB,CAAC,EAAE,qBAAqB,CAAC;IAChD,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC1C,UAAU,CAAC,EAAE,QAAQ,mBAAmB,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,mBAAmB,CAAC,CAAC;CAC1C,KACA,mBAmBF,CAAC;AAMF,eAAO,MAAM,kBAAkB,QAAO,QAAQ,mBAAmB,CAOhE,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAO,QAAQ,mBAAmB,CAOtE,CAAC;AAEF,eAAO,MAAM,0BAA0B,QAAO,QAAQ,qBAAqB,CAO1E,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,QAAQ,GAAG,OAAO,GAAG,MAOtD,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAO,QAAQ,mBAAmB,CAOnE,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,QAAQ,mBAAmB,CAOlE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/js/feedback/integration.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/js/feedback/integration.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAC;AAI3D,MAAM,CAAC,MAAM,gCAAgC,GAAG,gBAAgB,CAAC;AAWjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,cAMI,EAAE,EACe,EAAE;IACvB,MAAM,EACJ,aAAa,EACb,uBAAuB,EACvB,WAAW,EACX,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,KAElB,WAAW,EADV,aAAa,UACd,WAAW,EAPT,sFAOL,CAAc,CAAC;IAEhB,OAAO;QACL,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,aAAa;QACtB,aAAa,EAAE,aAAa,IAAI,EAAE;QAClC,uBAAuB,EAAE,uBAAuB,IAAI,EAAE;QACtD,WAAW,EAAE,WAAW,IAAI,QAAQ;QACpC,UAAU,EAAE,UAAU,IAAI,EAAE;QAC5B,SAAS,EAAE,SAAS,IAAI,EAAE;KAC3B,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,GAAoC,EAAE;;IAClE,OAAO,MAAA,SAAS,EAAE,0CAAE,oBAAoB,CAAyC,gCAAgC,CAAC,CAAC;AACrH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAiC,EAAE;IACnE,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,EAAE,CAAC;KACX;IAED,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAiC,EAAE;IACzE,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,EAAE,CAAC;KACX;IAED,OAAO,WAAW,CAAC,aAAa,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAmC,EAAE;IAC7E,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,EAAE,CAAC;KACX;IAED,OAAO,WAAW,CAAC,uBAAuB,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAgC,EAAE;IAC9D,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,WAAW,CAAA,EAAE;QAC7B,OAAO,QAAQ,CAAC;KACjB;IAED,OAAO,WAAW,CAAC,WAAW,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAiC,EAAE;IACtE,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,EAAE,CAAC;KACX;IAED,OAAO,WAAW,CAAC,UAAU,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAiC,EAAE;IACrE,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,EAAE,CAAC;KACX;IAED,OAAO,WAAW,CAAC,SAAS,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["import { getClient, type Integration } from '@sentry/core';\nimport type { FeedbackWidgetTheme } from './FeedbackWidget.theme';\nimport type { FeedbackButtonProps, FeedbackWidgetProps, ScreenshotButtonProps } from './FeedbackWidget.types';\n\nexport const MOBILE_FEEDBACK_INTEGRATION_NAME = 'MobileFeedback';\n\ntype FeedbackIntegration = Integration & {\n options: Partial<FeedbackWidgetProps>;\n buttonOptions: Partial<FeedbackButtonProps>;\n screenshotButtonOptions: Partial<ScreenshotButtonProps>;\n colorScheme?: 'system' | 'light' | 'dark';\n themeLight: Partial<FeedbackWidgetTheme>;\n themeDark: Partial<FeedbackWidgetTheme>;\n};\n\nexport const feedbackIntegration = (\n initOptions: Partial<FeedbackWidgetProps> & {\n buttonOptions?: FeedbackButtonProps;\n screenshotButtonOptions?: ScreenshotButtonProps;\n colorScheme?: 'system' | 'light' | 'dark';\n themeLight?: Partial<FeedbackWidgetTheme>;\n themeDark?: Partial<FeedbackWidgetTheme>;\n } = {},\n): FeedbackIntegration => {\n const {\n buttonOptions,\n screenshotButtonOptions,\n colorScheme,\n themeLight: lightTheme,\n themeDark: darkTheme,\n ...widgetOptions\n } = initOptions;\n\n return {\n name: MOBILE_FEEDBACK_INTEGRATION_NAME,\n options: widgetOptions,\n buttonOptions: buttonOptions || {},\n screenshotButtonOptions: screenshotButtonOptions || {},\n colorScheme: colorScheme || 'system',\n themeLight: lightTheme || {},\n themeDark: darkTheme || {},\n };\n};\n\nconst _getClientIntegration = (): FeedbackIntegration | undefined => {\n return getClient()?.getIntegrationByName<ReturnType<typeof feedbackIntegration>>(MOBILE_FEEDBACK_INTEGRATION_NAME);\n};\n\nexport const getFeedbackOptions = (): Partial<FeedbackWidgetProps> => {\n const integration = _getClientIntegration();\n if (!integration) {\n return {};\n }\n\n return integration.options;\n};\n\nexport const getFeedbackButtonOptions = (): Partial<FeedbackButtonProps> => {\n const integration = _getClientIntegration();\n if (!integration) {\n return {};\n }\n\n return integration.buttonOptions;\n};\n\nexport const getScreenshotButtonOptions = (): Partial<ScreenshotButtonProps> => {\n const integration = _getClientIntegration();\n if (!integration) {\n return {};\n }\n\n return integration.screenshotButtonOptions;\n};\n\nexport const getColorScheme = (): 'system' | 'light' | 'dark' => {\n const integration = _getClientIntegration();\n if (!integration?.colorScheme) {\n return 'system';\n }\n\n return integration.colorScheme;\n};\n\nexport const getFeedbackLightTheme = (): Partial<FeedbackWidgetTheme> => {\n const integration = _getClientIntegration();\n if (!integration) {\n return {};\n }\n\n return integration.themeLight;\n};\n\nexport const getFeedbackDarkTheme = (): Partial<FeedbackWidgetTheme> => {\n const integration = _getClientIntegration();\n if (!integration) {\n return {};\n }\n\n return integration.themeDark;\n};\n"]}
|
package/dist/js/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type { Breadcrumb, SdkInfo, Event, Exception, SendFeedbackParams, SeverityLevel, Span, StackFrame, Stacktrace, Thread, User, UserFeedback, ErrorEvent, TransactionEvent, } from '@sentry/core';
|
|
1
|
+
export type { Breadcrumb, SdkInfo, Event, Exception, SendFeedbackParams, SeverityLevel, Span, StackFrame, Stacktrace, Thread, User, UserFeedback, ErrorEvent, TransactionEvent, Metric, } from '@sentry/core';
|
|
2
2
|
export { addBreadcrumb, addIntegration, captureException, captureEvent, captureFeedback, captureMessage, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startInactiveSpan, startSpan, startSpanManual, getActiveSpan, getRootSpan, withActiveSpan, suppressTracing, spanToJSON, spanIsSampled, setMeasurement, getCurrentScope, getGlobalScope, getIsolationScope, getClient, setCurrentClient, addEventProcessor, lastEventId, } from '@sentry/core';
|
|
3
3
|
export { ErrorBoundary, withErrorBoundary, createReduxEnhancer, Profiler, useProfiler, withProfiler, } from '@sentry/react';
|
|
4
|
-
export { logger, consoleLoggingIntegration, featureFlagsIntegration, type FeatureFlagsIntegration, } from '@sentry/browser';
|
|
4
|
+
export { logger, consoleLoggingIntegration, featureFlagsIntegration, type FeatureFlagsIntegration, metrics, } from '@sentry/browser';
|
|
5
5
|
export * from './integrations/exports';
|
|
6
6
|
export { SDK_NAME, SDK_VERSION } from './version';
|
|
7
7
|
export type { ReactNativeOptions } from './options';
|
package/dist/js/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/js/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,IAAI,EACJ,UAAU,EACV,UAAU,EACV,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/js/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,IAAI,EACJ,UAAU,EACV,UAAU,EACV,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,MAAM,GACP,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,KAAK,EACL,UAAU,EACV,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,aAAa,EACb,WAAW,EACX,cAAc,EACd,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,MAAM,EACN,yBAAyB,EACzB,uBAAuB,EACvB,KAAK,uBAAuB,EAC5B,OAAO,GACR,MAAM,iBAAiB,CAAC;AAEzB,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EACL,6BAA6B,EAC7B,uCAAuC,EACvC,gCAAgC,EAChC,0BAA0B,EAC1B,gCAAgC,EAChC,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,EACb,mCAAmC,EACnC,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AAEnB,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE9G,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/js/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { addBreadcrumb, addIntegration, captureException, captureEvent, captureFeedback, captureMessage, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startInactiveSpan, startSpan, startSpanManual, getActiveSpan, getRootSpan, withActiveSpan, suppressTracing, spanToJSON, spanIsSampled, setMeasurement, getCurrentScope, getGlobalScope, getIsolationScope, getClient, setCurrentClient, addEventProcessor, lastEventId, } from '@sentry/core';
|
|
2
2
|
export { ErrorBoundary, withErrorBoundary, createReduxEnhancer, Profiler, useProfiler, withProfiler, } from '@sentry/react';
|
|
3
|
-
export { logger, consoleLoggingIntegration, featureFlagsIntegration, } from '@sentry/browser';
|
|
3
|
+
export { logger, consoleLoggingIntegration, featureFlagsIntegration, metrics, } from '@sentry/browser';
|
|
4
4
|
export * from './integrations/exports';
|
|
5
5
|
export { SDK_NAME, SDK_VERSION } from './version';
|
|
6
6
|
export { ReactNativeClient } from './client';
|
package/dist/js/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/js/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/js/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,KAAK,EACL,UAAU,EACV,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,aAAa,EACb,WAAW,EACX,cAAc,EACd,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,MAAM,EACN,yBAAyB,EACzB,uBAAuB,EAEvB,OAAO,GACR,MAAM,iBAAiB,CAAC;AAEzB,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EACL,6BAA6B,EAC7B,uCAAuC,EACvC,gCAAgC,EAChC,0BAA0B,EAC1B,gCAAgC,EAChC,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,EACb,mCAAmC,EACnC,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE9G,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export type {\n Breadcrumb,\n SdkInfo,\n Event,\n Exception,\n SendFeedbackParams,\n SeverityLevel,\n Span,\n StackFrame,\n Stacktrace,\n Thread,\n User,\n UserFeedback,\n ErrorEvent,\n TransactionEvent,\n Metric,\n} from '@sentry/core';\n\nexport {\n addBreadcrumb,\n addIntegration,\n captureException,\n captureEvent,\n captureFeedback,\n captureMessage,\n Scope,\n setContext,\n setExtra,\n setExtras,\n setTag,\n setTags,\n setUser,\n startInactiveSpan,\n startSpan,\n startSpanManual,\n getActiveSpan,\n getRootSpan,\n withActiveSpan,\n suppressTracing,\n spanToJSON,\n spanIsSampled,\n setMeasurement,\n getCurrentScope,\n getGlobalScope,\n getIsolationScope,\n getClient,\n setCurrentClient,\n addEventProcessor,\n lastEventId,\n} from '@sentry/core';\n\nexport {\n ErrorBoundary,\n withErrorBoundary,\n createReduxEnhancer,\n Profiler,\n useProfiler,\n withProfiler,\n} from '@sentry/react';\n\nexport {\n logger,\n consoleLoggingIntegration,\n featureFlagsIntegration,\n type FeatureFlagsIntegration,\n metrics,\n} from '@sentry/browser';\n\nexport * from './integrations/exports';\n\nexport { SDK_NAME, SDK_VERSION } from './version';\nexport type { ReactNativeOptions } from './options';\nexport { ReactNativeClient } from './client';\n\nexport { init, wrap, nativeCrash, flush, close, withScope, crashedLastRun } from './sdk';\nexport { TouchEventBoundary, withTouchEventBoundary } from './touchevents';\n\nexport {\n reactNativeTracingIntegration,\n getCurrentReactNativeTracingIntegration,\n getReactNativeTracingIntegration,\n reactNavigationIntegration,\n reactNativeNavigationIntegration,\n sentryTraceGesture,\n TimeToInitialDisplay,\n TimeToFullDisplay,\n startTimeToInitialDisplaySpan,\n startTimeToFullDisplaySpan,\n startIdleNavigationSpan,\n startIdleSpan,\n getDefaultIdleNavigationSpanOptions,\n createTimeToFullDisplay,\n createTimeToInitialDisplay,\n} from './tracing';\n\nexport type { TimeToDisplayProps } from './tracing';\n\nexport { Mask, Unmask } from './replay/CustomMask';\n\nexport { FeedbackButton } from './feedback/FeedbackButton';\nexport { FeedbackWidget } from './feedback/FeedbackWidget';\nexport { showFeedbackWidget, showFeedbackButton, hideFeedbackButton } from './feedback/FeedbackWidgetManager';\n\nexport { getDataFromUri } from './wrapper';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expocontext.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/expocontext.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"expocontext.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/expocontext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,WAAW,EAAkB,MAAM,cAAc,CAAC;AAQvG,eAAO,MAAM,uBAAuB,gBAAgB,CAAC;AAErD,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,QAAO,WA0DzC,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAqC1D;AAwDD,KAAK,kBAAkB,GAAG,OAAO,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expocontext.js","sourceRoot":"","sources":["../../../src/js/integrations/expocontext.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"expocontext.js","sourceRoot":"","sources":["../../../src/js/integrations/expocontext.ts"],"names":[],"mappings":"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","sourcesContent":["import { debug, type DeviceContext, type Event, type Integration, type OsContext } from '@sentry/core';\nimport type { ReactNativeClient } from '../client';\nimport { isExpo, isExpoGo } from '../utils/environment';\nimport { getExpoDevice, getExpoUpdates } from '../utils/expomodules';\nimport { NATIVE } from '../wrapper';\n\nconst INTEGRATION_NAME = 'ExpoContext';\n\nexport const OTA_UPDATES_CONTEXT_KEY = 'ota_updates';\n\n/** Load device context from expo modules. */\nexport const expoContextIntegration = (): Integration => {\n let _expoUpdatesContextCached: ExpoUpdatesContext | undefined;\n\n function setup(client: ReactNativeClient): void {\n client.on('afterInit', () => {\n if (!client.getOptions().enableNative) {\n return;\n }\n\n setExpoUpdatesNativeContext();\n });\n }\n\n function setExpoUpdatesNativeContext(): void {\n if (!isExpo() || isExpoGo()) {\n return;\n }\n\n const expoUpdates = getExpoUpdatesContextCached();\n\n try {\n // Ensures native errors and crashes have the same context as JS errors\n NATIVE.setContext(OTA_UPDATES_CONTEXT_KEY, expoUpdates);\n } catch (error) {\n debug.error('Error setting Expo updates context:', error);\n }\n }\n\n function processEvent(event: Event): Event {\n if (!isExpo()) {\n return event;\n }\n\n addExpoGoContext(event);\n addExpoUpdatesContext(event);\n return event;\n }\n\n function addExpoUpdatesContext(event: Event): void {\n event.contexts = event.contexts || {};\n event.contexts[OTA_UPDATES_CONTEXT_KEY] = {\n ...getExpoUpdatesContextCached(),\n };\n }\n\n function getExpoUpdatesContextCached(): ExpoUpdatesContext {\n if (_expoUpdatesContextCached) {\n return _expoUpdatesContextCached;\n }\n\n return (_expoUpdatesContextCached = getExpoUpdatesContext());\n }\n\n return {\n name: INTEGRATION_NAME,\n setup,\n processEvent,\n };\n};\n\n/**\n * @internal Exposed for testing purposes\n */\nexport function getExpoUpdatesContext(): ExpoUpdatesContext {\n const expoUpdates = getExpoUpdates();\n if (!expoUpdates) {\n return {\n is_enabled: false,\n };\n }\n\n const updatesContext: ExpoUpdatesContext = {\n is_enabled: !!expoUpdates.isEnabled,\n is_embedded_launch: !!expoUpdates.isEmbeddedLaunch,\n is_emergency_launch: !!expoUpdates.isEmergencyLaunch,\n is_using_embedded_assets: !!expoUpdates.isUsingEmbeddedAssets,\n };\n\n if (typeof expoUpdates.updateId === 'string' && expoUpdates.updateId) {\n updatesContext.update_id = expoUpdates.updateId.toLowerCase();\n }\n if (typeof expoUpdates.channel === 'string' && expoUpdates.channel) {\n updatesContext.channel = expoUpdates.channel.toLowerCase();\n }\n if (typeof expoUpdates.runtimeVersion === 'string' && expoUpdates.runtimeVersion) {\n updatesContext.runtime_version = expoUpdates.runtimeVersion.toLowerCase();\n }\n if (typeof expoUpdates.checkAutomatically === 'string' && expoUpdates.checkAutomatically) {\n updatesContext.check_automatically = expoUpdates.checkAutomatically.toLowerCase();\n }\n if (typeof expoUpdates.emergencyLaunchReason === 'string' && expoUpdates.emergencyLaunchReason) {\n updatesContext.emergency_launch_reason = expoUpdates.emergencyLaunchReason;\n }\n if (typeof expoUpdates.launchDuration === 'number') {\n updatesContext.launch_duration = expoUpdates.launchDuration;\n }\n if (expoUpdates.createdAt instanceof Date) {\n updatesContext.created_at = expoUpdates.createdAt.toISOString();\n }\n return updatesContext;\n}\n\nfunction addExpoGoContext(event: Event): void {\n if (!isExpoGo()) {\n return;\n }\n\n const expoDeviceContext = getExpoDeviceContext();\n if (expoDeviceContext) {\n event.contexts = event.contexts || {};\n event.contexts.device = { ...expoDeviceContext, ...event.contexts.device };\n }\n\n const expoOsContext = getExpoOsContext();\n if (expoOsContext) {\n event.contexts = event.contexts || {};\n event.contexts.os = { ...expoOsContext, ...event.contexts.os };\n }\n}\n\n/**\n * Returns the Expo Device context if present\n */\nfunction getExpoDeviceContext(): DeviceContext | undefined {\n const expoDevice = getExpoDevice();\n\n if (!expoDevice) {\n return undefined;\n }\n\n return {\n name: expoDevice.deviceName,\n simulator: !expoDevice?.isDevice,\n model: expoDevice.modelName,\n manufacturer: expoDevice.manufacturer,\n memory_size: expoDevice.totalMemory,\n };\n}\n\n/**\n * Returns the Expo OS context if present\n */\nfunction getExpoOsContext(): OsContext | undefined {\n const expoDevice = getExpoDevice();\n\n if (!expoDevice) {\n return undefined;\n }\n\n return {\n build: expoDevice.osBuildId,\n version: expoDevice.osVersion,\n name: expoDevice.osName,\n };\n}\n\ntype ExpoUpdatesContext = Partial<{\n is_enabled: boolean;\n is_embedded_launch: boolean;\n is_emergency_launch: boolean;\n is_using_embedded_assets: boolean;\n update_id: string;\n channel: string;\n runtime_version: string;\n check_automatically: string;\n emergency_launch_reason: string;\n launch_duration: number;\n created_at: string;\n}>;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobilereplay.d.ts","sourceRoot":"","sources":["../../../src/js/replay/mobilereplay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAQlG,eAAO,MAAM,8BAA8B,iBAAiB,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;;OAWG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;CAClE;AAyBD,KAAK,uBAAuB,GAAG,WAAW,GAAG;IAC3C,OAAO,EAAE,mBAAmB,CAAC;IAC7B,WAAW,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,mBAAmB,KAAoB,
|
|
1
|
+
{"version":3,"file":"mobilereplay.d.ts","sourceRoot":"","sources":["../../../src/js/replay/mobilereplay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAQlG,eAAO,MAAM,8BAA8B,iBAAiB,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;;OAWG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;CAClE;AAyBD,KAAK,uBAAuB,GAAG,WAAW,GAAG;IAC3C,OAAO,EAAE,mBAAmB,CAAC;IAC7B,WAAW,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,mBAAmB,KAAoB,uBAuH3F,CAAC"}
|
|
@@ -57,6 +57,22 @@ export const mobileReplayIntegration = (initOptions = defaultOptions) => {
|
|
|
57
57
|
return mobileReplayIntegrationNoop();
|
|
58
58
|
}
|
|
59
59
|
const options = mergeOptions(initOptions);
|
|
60
|
+
// Cache the replay ID in JavaScript to avoid excessive bridge calls
|
|
61
|
+
// This will be updated when we know the replay ID changes (e.g., after captureReplay)
|
|
62
|
+
let cachedReplayId = null;
|
|
63
|
+
function updateCachedReplayId(replayId) {
|
|
64
|
+
cachedReplayId = replayId;
|
|
65
|
+
}
|
|
66
|
+
function getCachedReplayId() {
|
|
67
|
+
if (cachedReplayId !== null) {
|
|
68
|
+
return cachedReplayId;
|
|
69
|
+
}
|
|
70
|
+
const nativeReplayId = NATIVE.getCurrentReplayId();
|
|
71
|
+
if (nativeReplayId) {
|
|
72
|
+
cachedReplayId = nativeReplayId;
|
|
73
|
+
}
|
|
74
|
+
return nativeReplayId;
|
|
75
|
+
}
|
|
60
76
|
function processEvent(event, hint) {
|
|
61
77
|
var _a;
|
|
62
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -79,18 +95,22 @@ export const mobileReplayIntegration = (initOptions = defaultOptions) => {
|
|
|
79
95
|
}
|
|
80
96
|
}
|
|
81
97
|
const replayId = yield NATIVE.captureReplay(isHardCrash(event));
|
|
82
|
-
if (
|
|
98
|
+
if (replayId) {
|
|
99
|
+
updateCachedReplayId(replayId);
|
|
100
|
+
debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} Captured recording replay ${replayId} for event ${event.event_id}.`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Check if there's an ongoing recording and update cache if found
|
|
83
104
|
const recordingReplayId = NATIVE.getCurrentReplayId();
|
|
84
105
|
if (recordingReplayId) {
|
|
106
|
+
updateCachedReplayId(recordingReplayId);
|
|
85
107
|
debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} assign already recording replay ${recordingReplayId} for event ${event.event_id}.`);
|
|
86
108
|
}
|
|
87
109
|
else {
|
|
110
|
+
updateCachedReplayId(null);
|
|
88
111
|
debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sampled for event ${event.event_id}.`);
|
|
89
112
|
}
|
|
90
113
|
}
|
|
91
|
-
else {
|
|
92
|
-
debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} Captured recording replay ${replayId} for event ${event.event_id}.`);
|
|
93
|
-
}
|
|
94
114
|
return event;
|
|
95
115
|
});
|
|
96
116
|
}
|
|
@@ -98,12 +118,14 @@ export const mobileReplayIntegration = (initOptions = defaultOptions) => {
|
|
|
98
118
|
if (!hasHooks(client)) {
|
|
99
119
|
return;
|
|
100
120
|
}
|
|
121
|
+
// Initialize the cached replay ID on setup
|
|
122
|
+
cachedReplayId = NATIVE.getCurrentReplayId();
|
|
101
123
|
client.on('createDsc', (dsc) => {
|
|
102
124
|
if (dsc.replay_id) {
|
|
103
125
|
return;
|
|
104
126
|
}
|
|
105
|
-
//
|
|
106
|
-
const currentReplayId =
|
|
127
|
+
// Use cached replay ID to avoid bridge calls
|
|
128
|
+
const currentReplayId = getCachedReplayId();
|
|
107
129
|
if (currentReplayId) {
|
|
108
130
|
dsc.replay_id = currentReplayId;
|
|
109
131
|
}
|
|
@@ -111,7 +133,7 @@ export const mobileReplayIntegration = (initOptions = defaultOptions) => {
|
|
|
111
133
|
client.on('beforeAddBreadcrumb', enrichXhrBreadcrumbsForMobileReplay);
|
|
112
134
|
}
|
|
113
135
|
function getReplayId() {
|
|
114
|
-
return
|
|
136
|
+
return getCachedReplayId();
|
|
115
137
|
}
|
|
116
138
|
// TODO: When adding manual API, ensure overlap with the web replay so users can use the same API interchangeably
|
|
117
139
|
// https://github.com/getsentry/sentry-javascript/blob/develop/packages/replay-internal/src/integration.ts#L45
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobilereplay.js","sourceRoot":"","sources":["../../../src/js/replay/mobilereplay.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,CAAC,MAAM,8BAA8B,GAAG,cAAc,CAAC;AAoG7D,MAAM,cAAc,GAAwB;IAC1C,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,IAAI;IACpB,8BAA8B,EAAE,KAAK;IACrC,oBAAoB,EAAE,IAAI;IAC1B,uBAAuB,EAAE,KAAK;IAC9B,kBAAkB,EAAE,WAAW;CAChC,CAAC;AAEF,SAAS,YAAY,CAAC,WAAyC;IAC7D,MAAM,MAAM,mCACP,cAAc,GACd,WAAW,CACf,CAAC;IAEF,IAAI,WAAW,CAAC,oBAAoB,KAAK,SAAS,IAAI,WAAW,CAAC,8BAA8B,KAAK,SAAS,EAAE;QAC9G,MAAM,CAAC,oBAAoB,GAAG,WAAW,CAAC,8BAA8B,CAAC;KAC1E;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAOD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,cAAmC,cAAc,EAA2B,EAAE;IACpH,IAAI,QAAQ,EAAE,EAAE;QACd,KAAK,CAAC,IAAI,CACR,YAAY,8BAA8B,gFAAgF,CAC3H,CAAC;KACH;IACD,IAAI,WAAW,EAAE,EAAE;QACjB,KAAK,CAAC,IAAI,CAAC,YAAY,8BAA8B,qCAAqC,CAAC,CAAC;KAC7F;IAED,IAAI,QAAQ,EAAE,IAAI,WAAW,EAAE,EAAE;QAC/B,OAAO,2BAA2B,EAAE,CAAC;KACtC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAE1C,SAAe,YAAY,CAAC,KAAY,EAAE,IAAe;;;YACvD,MAAM,YAAY,GAAG,CAAA,MAAA,KAAK,CAAC,SAAS,0CAAE,MAAM,KAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAClF,IAAI,CAAC,YAAY,EAAE;gBACjB,iDAAiD;gBACjD,OAAO,KAAK,CAAC;aACd;YAED,+DAA+D;YAC/D,IAAI,WAAW,CAAC,mBAAmB,EAAE;gBACnC,IAAI;oBACF,IAAI,WAAW,CAAC,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE;wBAC1D,KAAK,CAAC,GAAG,CACP,YAAY,8BAA8B,+DAA+D,KAAK,CAAC,QAAQ,GAAG,CAC3H,CAAC;wBACF,OAAO,KAAK,CAAC;qBACd;iBACF;gBAAC,OAAO,KAAK,EAAE;oBACd,KAAK,CAAC,KAAK,CACT,YAAY,8BAA8B,8EAA8E,EACxH,KAAK,CACN,CAAC;oBACF,kDAAkD;iBACnD;aACF;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,iBAAiB,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBACtD,IAAI,iBAAiB,EAAE;oBACrB,KAAK,CAAC,GAAG,CACP,YAAY,8BAA8B,oCAAoC,iBAAiB,cAAc,KAAK,CAAC,QAAQ,GAAG,CAC/H,CAAC;iBACH;qBAAM;oBACL,KAAK,CAAC,GAAG,CAAC,YAAY,8BAA8B,0BAA0B,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;iBAClG;aACF;iBAAM;gBACL,KAAK,CAAC,GAAG,CACP,YAAY,8BAA8B,8BAA8B,QAAQ,cAAc,KAAK,CAAC,QAAQ,GAAG,CAChH,CAAC;aACH;YAED,OAAO,KAAK,CAAC;;KACd;IAED,SAAS,KAAK,CAAC,MAAc;QAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;YACrB,OAAO;SACR;QAED,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,GAA2B,EAAE,EAAE;YACrD,IAAI,GAAG,CAAC,SAAS,EAAE;gBACjB,OAAO;aACR;YAED,6GAA6G;YAC7G,MAAM,eAAe,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;YACpD,IAAI,eAAe,EAAE;gBACnB,GAAG,CAAC,SAAS,GAAG,eAAe,CAAC;aACjC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,mCAAmC,CAAC,CAAC;IACxE,CAAC;IAED,SAAS,WAAW;QAClB,OAAO,MAAM,CAAC,kBAAkB,EAAE,CAAC;IACrC,CAAC;IAED,iHAAiH;IACjH,8GAA8G;IAC9G,OAAO;QACL,IAAI,EAAE,8BAA8B;QACpC,KAAK;QACL,YAAY;QACZ,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,WAAW;KACzB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,GAA4B,EAAE;IAChE,OAAO;QACL,IAAI,EAAE,8BAA8B;QACpC,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,uCAAuC;KACjE,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type { Client, DynamicSamplingContext, Event, EventHint, Integration } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { isHardCrash } from '../misc';\nimport { hasHooks } from '../utils/clientutils';\nimport { isExpoGo, notMobileOs } from '../utils/environment';\nimport { NATIVE } from '../wrapper';\nimport { enrichXhrBreadcrumbsForMobileReplay } from './xhrUtils';\n\nexport const MOBILE_REPLAY_INTEGRATION_NAME = 'MobileReplay';\n\n/**\n * Screenshot strategy type for Android Session Replay.\n *\n * - `'canvas'`: Canvas-based screenshot strategy. This strategy does **not** support any masking options, it always masks text and images. Use this if your application has strict PII requirements.\n * - `'pixelCopy'`: Pixel copy screenshot strategy (default). Supports all masking options.\n */\nexport type ScreenshotStrategy = 'canvas' | 'pixelCopy';\n\nexport interface MobileReplayOptions {\n /**\n * Mask all text in recordings\n *\n * @default true\n */\n maskAllText?: boolean;\n\n /**\n * Mask all images in recordings\n *\n * @default true\n */\n maskAllImages?: boolean;\n\n /**\n * Mask all vector graphics in recordings\n * Supports `react-native-svg`\n *\n * @default true\n */\n maskAllVectors?: boolean;\n\n /**\n * Enables the up to 5x faster experimental view renderer used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag.\n *\n * - Experiment: This is an experimental feature and is therefore disabled by default.\n *\n * @deprecated Use `enableViewRendererV2` instead.\n * @platform ios\n */\n enableExperimentalViewRenderer?: boolean;\n\n /**\n * Enables up to 5x faster new view renderer used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag. [Our benchmarks](https://github.com/getsentry/sentry-cocoa/pull/4940) have shown a significant improvement of\n * **up to 4-5x faster rendering** (reducing `~160ms` to `~36ms` per frame) on older devices.\n *\n * - Experiment: In case you are noticing issues with the new view renderer, please report the issue on [GitHub](https://github.com/getsentry/sentry-cocoa).\n * Eventually, we will remove this feature flag and use the new view renderer by default.\n *\n * @default true\n * @platform ios\n */\n enableViewRendererV2?: boolean;\n\n /**\n * Enables up to 5x faster but incomplete view rendering used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag.\n *\n * - Note: This flag can only be used together with `enableExperimentalViewRenderer` with up to 20% faster render times.\n * - Experiment: This is an experimental feature and is therefore disabled by default.\n *\n * @default false\n * @platform ios\n */\n enableFastViewRendering?: boolean;\n\n /**\n * Sets the screenshot strategy used by the Session Replay integration on Android.\n *\n * If your application has strict PII requirements we recommend using `'canvas'`.\n * This strategy does **not** support any masking options, it always masks text and images.\n *\n * - Experiment: In case you are noticing issues with the canvas screenshot strategy, please report the issue on [GitHub](https://github.com/getsentry/sentry-java).\n *\n * @default 'pixelCopy'\n * @platform android\n */\n screenshotStrategy?: ScreenshotStrategy;\n\n /**\n * Callback to determine if a replay should be captured for a specific error.\n * When this callback returns `false`, no replay will be captured for the error.\n * This callback is only called when an error occurs and `replaysOnErrorSampleRate` is set.\n *\n * @param event The error event\n * @param hint Additional event information\n * @returns `false` to skip capturing a replay for this error, `true` or `undefined` to proceed with sampling\n */\n beforeErrorSampling?: (event: Event, hint: EventHint) => boolean;\n}\n\nconst defaultOptions: MobileReplayOptions = {\n maskAllText: true,\n maskAllImages: true,\n maskAllVectors: true,\n enableExperimentalViewRenderer: false,\n enableViewRendererV2: true,\n enableFastViewRendering: false,\n screenshotStrategy: 'pixelCopy',\n};\n\nfunction mergeOptions(initOptions: Partial<MobileReplayOptions>): MobileReplayOptions {\n const merged = {\n ...defaultOptions,\n ...initOptions,\n };\n\n if (initOptions.enableViewRendererV2 === undefined && initOptions.enableExperimentalViewRenderer !== undefined) {\n merged.enableViewRendererV2 = initOptions.enableExperimentalViewRenderer;\n }\n\n return merged;\n}\n\ntype MobileReplayIntegration = Integration & {\n options: MobileReplayOptions;\n getReplayId: () => string | null;\n};\n\n/**\n * The Mobile Replay Integration, let's you adjust the default mobile replay options.\n * To be passed to `Sentry.init` with `replaysOnErrorSampleRate` or `replaysSessionSampleRate`.\n *\n * ```javascript\n * Sentry.init({\n * replaysOnErrorSampleRate: 1.0,\n * replaysSessionSampleRate: 1.0,\n * integrations: [mobileReplayIntegration({\n * // Adjust the default options\n * })],\n * });\n * ```\n *\n * @experimental\n */\nexport const mobileReplayIntegration = (initOptions: MobileReplayOptions = defaultOptions): MobileReplayIntegration => {\n if (isExpoGo()) {\n debug.warn(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} is not supported in Expo Go. Use EAS Build or \\`expo prebuild\\` to enable it.`,\n );\n }\n if (notMobileOs()) {\n debug.warn(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} is not supported on this platform.`);\n }\n\n if (isExpoGo() || notMobileOs()) {\n return mobileReplayIntegrationNoop();\n }\n\n const options = mergeOptions(initOptions);\n\n async function processEvent(event: Event, hint: EventHint): Promise<Event> {\n const hasException = event.exception?.values && event.exception.values.length > 0;\n if (!hasException) {\n // Event is not an error, will not capture replay\n return event;\n }\n\n // Check if beforeErrorSampling callback filters out this error\n if (initOptions.beforeErrorSampling) {\n try {\n if (initOptions.beforeErrorSampling(event, hint) === false) {\n debug.log(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sent; beforeErrorSampling conditions not met for event ${event.event_id}.`,\n );\n return event;\n }\n } catch (error) {\n debug.error(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} beforeErrorSampling callback threw an error, proceeding with replay capture`,\n error,\n );\n // Continue with replay capture if callback throws\n }\n }\n\n const replayId = await NATIVE.captureReplay(isHardCrash(event));\n if (!replayId) {\n const recordingReplayId = NATIVE.getCurrentReplayId();\n if (recordingReplayId) {\n debug.log(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} assign already recording replay ${recordingReplayId} for event ${event.event_id}.`,\n );\n } else {\n debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sampled for event ${event.event_id}.`);\n }\n } else {\n debug.log(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} Captured recording replay ${replayId} for event ${event.event_id}.`,\n );\n }\n\n return event;\n }\n\n function setup(client: Client): void {\n if (!hasHooks(client)) {\n return;\n }\n\n client.on('createDsc', (dsc: DynamicSamplingContext) => {\n if (dsc.replay_id) {\n return;\n }\n\n // TODO: For better performance, we should emit replayId changes on native, and hold the replayId value in JS\n const currentReplayId = NATIVE.getCurrentReplayId();\n if (currentReplayId) {\n dsc.replay_id = currentReplayId;\n }\n });\n\n client.on('beforeAddBreadcrumb', enrichXhrBreadcrumbsForMobileReplay);\n }\n\n function getReplayId(): string | null {\n return NATIVE.getCurrentReplayId();\n }\n\n // TODO: When adding manual API, ensure overlap with the web replay so users can use the same API interchangeably\n // https://github.com/getsentry/sentry-javascript/blob/develop/packages/replay-internal/src/integration.ts#L45\n return {\n name: MOBILE_REPLAY_INTEGRATION_NAME,\n setup,\n processEvent,\n options: options,\n getReplayId: getReplayId,\n };\n};\n\nconst mobileReplayIntegrationNoop = (): MobileReplayIntegration => {\n return {\n name: MOBILE_REPLAY_INTEGRATION_NAME,\n options: defaultOptions,\n getReplayId: () => null, // Mock implementation for noop version\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"mobilereplay.js","sourceRoot":"","sources":["../../../src/js/replay/mobilereplay.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, DynamicSamplingContext, Event, EventHint, Integration } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { isHardCrash } from '../misc';\nimport { hasHooks } from '../utils/clientutils';\nimport { isExpoGo, notMobileOs } from '../utils/environment';\nimport { NATIVE } from '../wrapper';\nimport { enrichXhrBreadcrumbsForMobileReplay } from './xhrUtils';\n\nexport const MOBILE_REPLAY_INTEGRATION_NAME = 'MobileReplay';\n\n/**\n * Screenshot strategy type for Android Session Replay.\n *\n * - `'canvas'`: Canvas-based screenshot strategy. This strategy does **not** support any masking options, it always masks text and images. Use this if your application has strict PII requirements.\n * - `'pixelCopy'`: Pixel copy screenshot strategy (default). Supports all masking options.\n */\nexport type ScreenshotStrategy = 'canvas' | 'pixelCopy';\n\nexport interface MobileReplayOptions {\n /**\n * Mask all text in recordings\n *\n * @default true\n */\n maskAllText?: boolean;\n\n /**\n * Mask all images in recordings\n *\n * @default true\n */\n maskAllImages?: boolean;\n\n /**\n * Mask all vector graphics in recordings\n * Supports `react-native-svg`\n *\n * @default true\n */\n maskAllVectors?: boolean;\n\n /**\n * Enables the up to 5x faster experimental view renderer used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag.\n *\n * - Experiment: This is an experimental feature and is therefore disabled by default.\n *\n * @deprecated Use `enableViewRendererV2` instead.\n * @platform ios\n */\n enableExperimentalViewRenderer?: boolean;\n\n /**\n * Enables up to 5x faster new view renderer used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag. [Our benchmarks](https://github.com/getsentry/sentry-cocoa/pull/4940) have shown a significant improvement of\n * **up to 4-5x faster rendering** (reducing `~160ms` to `~36ms` per frame) on older devices.\n *\n * - Experiment: In case you are noticing issues with the new view renderer, please report the issue on [GitHub](https://github.com/getsentry/sentry-cocoa).\n * Eventually, we will remove this feature flag and use the new view renderer by default.\n *\n * @default true\n * @platform ios\n */\n enableViewRendererV2?: boolean;\n\n /**\n * Enables up to 5x faster but incomplete view rendering used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag.\n *\n * - Note: This flag can only be used together with `enableExperimentalViewRenderer` with up to 20% faster render times.\n * - Experiment: This is an experimental feature and is therefore disabled by default.\n *\n * @default false\n * @platform ios\n */\n enableFastViewRendering?: boolean;\n\n /**\n * Sets the screenshot strategy used by the Session Replay integration on Android.\n *\n * If your application has strict PII requirements we recommend using `'canvas'`.\n * This strategy does **not** support any masking options, it always masks text and images.\n *\n * - Experiment: In case you are noticing issues with the canvas screenshot strategy, please report the issue on [GitHub](https://github.com/getsentry/sentry-java).\n *\n * @default 'pixelCopy'\n * @platform android\n */\n screenshotStrategy?: ScreenshotStrategy;\n\n /**\n * Callback to determine if a replay should be captured for a specific error.\n * When this callback returns `false`, no replay will be captured for the error.\n * This callback is only called when an error occurs and `replaysOnErrorSampleRate` is set.\n *\n * @param event The error event\n * @param hint Additional event information\n * @returns `false` to skip capturing a replay for this error, `true` or `undefined` to proceed with sampling\n */\n beforeErrorSampling?: (event: Event, hint: EventHint) => boolean;\n}\n\nconst defaultOptions: MobileReplayOptions = {\n maskAllText: true,\n maskAllImages: true,\n maskAllVectors: true,\n enableExperimentalViewRenderer: false,\n enableViewRendererV2: true,\n enableFastViewRendering: false,\n screenshotStrategy: 'pixelCopy',\n};\n\nfunction mergeOptions(initOptions: Partial<MobileReplayOptions>): MobileReplayOptions {\n const merged = {\n ...defaultOptions,\n ...initOptions,\n };\n\n if (initOptions.enableViewRendererV2 === undefined && initOptions.enableExperimentalViewRenderer !== undefined) {\n merged.enableViewRendererV2 = initOptions.enableExperimentalViewRenderer;\n }\n\n return merged;\n}\n\ntype MobileReplayIntegration = Integration & {\n options: MobileReplayOptions;\n getReplayId: () => string | null;\n};\n\n/**\n * The Mobile Replay Integration, let's you adjust the default mobile replay options.\n * To be passed to `Sentry.init` with `replaysOnErrorSampleRate` or `replaysSessionSampleRate`.\n *\n * ```javascript\n * Sentry.init({\n * replaysOnErrorSampleRate: 1.0,\n * replaysSessionSampleRate: 1.0,\n * integrations: [mobileReplayIntegration({\n * // Adjust the default options\n * })],\n * });\n * ```\n *\n * @experimental\n */\nexport const mobileReplayIntegration = (initOptions: MobileReplayOptions = defaultOptions): MobileReplayIntegration => {\n if (isExpoGo()) {\n debug.warn(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} is not supported in Expo Go. Use EAS Build or \\`expo prebuild\\` to enable it.`,\n );\n }\n if (notMobileOs()) {\n debug.warn(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} is not supported on this platform.`);\n }\n\n if (isExpoGo() || notMobileOs()) {\n return mobileReplayIntegrationNoop();\n }\n\n const options = mergeOptions(initOptions);\n\n // Cache the replay ID in JavaScript to avoid excessive bridge calls\n // This will be updated when we know the replay ID changes (e.g., after captureReplay)\n let cachedReplayId: string | null = null;\n\n function updateCachedReplayId(replayId: string | null): void {\n cachedReplayId = replayId;\n }\n\n function getCachedReplayId(): string | null {\n if (cachedReplayId !== null) {\n return cachedReplayId;\n }\n const nativeReplayId = NATIVE.getCurrentReplayId();\n if (nativeReplayId) {\n cachedReplayId = nativeReplayId;\n }\n return nativeReplayId;\n }\n\n async function processEvent(event: Event, hint: EventHint): Promise<Event> {\n const hasException = event.exception?.values && event.exception.values.length > 0;\n if (!hasException) {\n // Event is not an error, will not capture replay\n return event;\n }\n\n // Check if beforeErrorSampling callback filters out this error\n if (initOptions.beforeErrorSampling) {\n try {\n if (initOptions.beforeErrorSampling(event, hint) === false) {\n debug.log(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sent; beforeErrorSampling conditions not met for event ${event.event_id}.`,\n );\n return event;\n }\n } catch (error) {\n debug.error(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} beforeErrorSampling callback threw an error, proceeding with replay capture`,\n error,\n );\n // Continue with replay capture if callback throws\n }\n }\n\n const replayId = await NATIVE.captureReplay(isHardCrash(event));\n if (replayId) {\n updateCachedReplayId(replayId);\n debug.log(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} Captured recording replay ${replayId} for event ${event.event_id}.`,\n );\n } else {\n // Check if there's an ongoing recording and update cache if found\n const recordingReplayId = NATIVE.getCurrentReplayId();\n if (recordingReplayId) {\n updateCachedReplayId(recordingReplayId);\n debug.log(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} assign already recording replay ${recordingReplayId} for event ${event.event_id}.`,\n );\n } else {\n updateCachedReplayId(null);\n debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sampled for event ${event.event_id}.`);\n }\n }\n\n return event;\n }\n\n function setup(client: Client): void {\n if (!hasHooks(client)) {\n return;\n }\n\n // Initialize the cached replay ID on setup\n cachedReplayId = NATIVE.getCurrentReplayId();\n\n client.on('createDsc', (dsc: DynamicSamplingContext) => {\n if (dsc.replay_id) {\n return;\n }\n\n // Use cached replay ID to avoid bridge calls\n const currentReplayId = getCachedReplayId();\n if (currentReplayId) {\n dsc.replay_id = currentReplayId;\n }\n });\n\n client.on('beforeAddBreadcrumb', enrichXhrBreadcrumbsForMobileReplay);\n }\n\n function getReplayId(): string | null {\n return getCachedReplayId();\n }\n\n // TODO: When adding manual API, ensure overlap with the web replay so users can use the same API interchangeably\n // https://github.com/getsentry/sentry-javascript/blob/develop/packages/replay-internal/src/integration.ts#L45\n return {\n name: MOBILE_REPLAY_INTEGRATION_NAME,\n setup,\n processEvent,\n options: options,\n getReplayId: getReplayId,\n };\n};\n\nconst mobileReplayIntegrationNoop = (): MobileReplayIntegration => {\n return {\n name: MOBILE_REPLAY_INTEGRATION_NAME,\n options: defaultOptions,\n getReplayId: () => null, // Mock implementation for noop version\n };\n};\n"]}
|
|
@@ -15,7 +15,8 @@ export interface FramesMeasurements extends Measurements {
|
|
|
15
15
|
}
|
|
16
16
|
export declare const createNativeFramesIntegrations: (enable: boolean | undefined) => Integration | undefined;
|
|
17
17
|
/**
|
|
18
|
-
* Instrumentation to add native slow/frozen frames measurements onto transactions
|
|
18
|
+
* Instrumentation to add native slow/frozen frames measurements onto transactions
|
|
19
|
+
* and frame data (frames.total, frames.slow, frames.frozen) onto all spans.
|
|
19
20
|
*/
|
|
20
21
|
export declare const nativeFramesIntegration: () => Integration;
|
|
21
22
|
//# sourceMappingURL=nativeFrames.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeFrames.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/nativeFrames.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAE,YAAY,EAAE,eAAe,EAAQ,MAAM,cAAc,CAAC;AAkCpG,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACvD,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACtD,aAAa,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CACzD;AAOD,eAAO,MAAM,8BAA8B,WAAY,OAAO,GAAG,SAAS,KAAG,WAAW,GAAG,SAQ1F,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"nativeFrames.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/nativeFrames.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAE,YAAY,EAAE,eAAe,EAAQ,MAAM,cAAc,CAAC;AAkCpG,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACvD,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACtD,aAAa,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CACzD;AAOD,eAAO,MAAM,8BAA8B,WAAY,OAAO,GAAG,SAAS,KAAG,WAAW,GAAG,SAQ1F,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,QAAO,WAgN1C,CAAC"}
|
|
@@ -42,7 +42,8 @@ export const createNativeFramesIntegrations = (enable) => {
|
|
|
42
42
|
return nativeFramesIntegration();
|
|
43
43
|
};
|
|
44
44
|
/**
|
|
45
|
-
* Instrumentation to add native slow/frozen frames measurements onto transactions
|
|
45
|
+
* Instrumentation to add native slow/frozen frames measurements onto transactions
|
|
46
|
+
* and frame data (frames.total, frames.slow, frames.frozen) onto all spans.
|
|
46
47
|
*/
|
|
47
48
|
export const nativeFramesIntegration = () => {
|
|
48
49
|
/** The native frames at the finish time of the most recent span. */
|
|
@@ -63,12 +64,10 @@ export const nativeFramesIntegration = () => {
|
|
|
63
64
|
client.on('spanStart', fetchStartFramesForSpan);
|
|
64
65
|
client.on('spanEnd', fetchEndFramesForSpan);
|
|
65
66
|
};
|
|
66
|
-
const fetchStartFramesForSpan = (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
const spanId = rootSpan.spanContext().spanId;
|
|
71
|
-
debug.log(`[${INTEGRATION_NAME}] Fetching frames for root span start (${spanId}).`);
|
|
67
|
+
const fetchStartFramesForSpan = (span) => {
|
|
68
|
+
const spanId = span.spanContext().spanId;
|
|
69
|
+
const spanType = isRootSpan(span) ? 'root' : 'child';
|
|
70
|
+
debug.log(`[${INTEGRATION_NAME}] Fetching frames for ${spanType} span start (${spanId}).`);
|
|
72
71
|
_spanToNativeFramesAtStartMap.set(spanId, new Promise(resolve => {
|
|
73
72
|
fetchNativeFrames()
|
|
74
73
|
.then(frames => resolve(frames))
|
|
@@ -78,15 +77,24 @@ export const nativeFramesIntegration = () => {
|
|
|
78
77
|
});
|
|
79
78
|
}));
|
|
80
79
|
};
|
|
81
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Fetches end frames for a span and attaches frame data as span attributes.
|
|
82
|
+
*
|
|
83
|
+
* Note: This makes one native bridge call per span end. While this creates O(n) calls
|
|
84
|
+
* for n spans, it's necessary for accuracy. Frame counts are cumulative and continuously
|
|
85
|
+
* incrementing, so each span needs the exact frame count at its end time. Caching would
|
|
86
|
+
* produce incorrect deltas. The native bridge calls are async and non-blocking.
|
|
87
|
+
*/
|
|
88
|
+
const fetchEndFramesForSpan = (span) => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
89
|
const timestamp = timestampInSeconds();
|
|
83
90
|
const spanId = span.spanContext().spanId;
|
|
91
|
+
const hasStartFrames = _spanToNativeFramesAtStartMap.has(spanId);
|
|
92
|
+
if (!hasStartFrames) {
|
|
93
|
+
// We don't have start frames, won't be able to calculate the difference.
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
84
96
|
if (isRootSpan(span)) {
|
|
85
|
-
|
|
86
|
-
if (!hasStartFrames) {
|
|
87
|
-
// We don't have start frames, won't be able to calculate the difference.
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
97
|
+
// Root spans: Store end frames for transaction measurements (backward compatibility)
|
|
90
98
|
debug.log(`[${INTEGRATION_NAME}] Fetch frames for root span end (${spanId}).`);
|
|
91
99
|
_spanToNativeFramesAtEndMap.set(spanId, new Promise(resolve => {
|
|
92
100
|
fetchNativeFrames()
|
|
@@ -101,20 +109,41 @@ export const nativeFramesIntegration = () => {
|
|
|
101
109
|
resolve(null);
|
|
102
110
|
});
|
|
103
111
|
}));
|
|
104
|
-
return undefined;
|
|
105
112
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
// All spans (root and child): Attach frame data as span attributes
|
|
114
|
+
try {
|
|
115
|
+
const startFrames = yield _spanToNativeFramesAtStartMap.get(spanId);
|
|
116
|
+
if (!startFrames) {
|
|
117
|
+
debug.log(`[${INTEGRATION_NAME}] No start frames found for span ${spanId}, skipping frame data.`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// NOTE: For root spans, this is the second call to fetchNativeFrames() for the same span.
|
|
121
|
+
// The calls are very close together (microseconds apart), so inconsistency is minimal.
|
|
122
|
+
// Future optimization: reuse the first call's promise to avoid redundant native bridge call.
|
|
123
|
+
const endFrames = yield fetchNativeFrames();
|
|
124
|
+
// Calculate deltas
|
|
125
|
+
const totalFrames = endFrames.totalFrames - startFrames.totalFrames;
|
|
126
|
+
const slowFrames = endFrames.slowFrames - startFrames.slowFrames;
|
|
127
|
+
const frozenFrames = endFrames.frozenFrames - startFrames.frozenFrames;
|
|
128
|
+
// Only attach if we have meaningful data
|
|
129
|
+
if (totalFrames > 0 || slowFrames > 0 || frozenFrames > 0) {
|
|
130
|
+
span.setAttribute('frames.total', totalFrames);
|
|
131
|
+
span.setAttribute('frames.slow', slowFrames);
|
|
132
|
+
span.setAttribute('frames.frozen', frozenFrames);
|
|
133
|
+
debug.log(`[${INTEGRATION_NAME}] Attached frame data to span ${spanId}: total=${totalFrames}, slow=${slowFrames}, frozen=${frozenFrames}`);
|
|
134
|
+
}
|
|
135
|
+
// Update last child span end frames for root span fallback logic
|
|
136
|
+
if (!isRootSpan(span)) {
|
|
110
137
|
_lastChildSpanEndFrames = {
|
|
111
138
|
timestamp,
|
|
112
|
-
nativeFrames:
|
|
139
|
+
nativeFrames: endFrames,
|
|
113
140
|
};
|
|
114
|
-
}
|
|
115
|
-
.catch(error => debug.log(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error));
|
|
141
|
+
}
|
|
116
142
|
}
|
|
117
|
-
|
|
143
|
+
catch (error) {
|
|
144
|
+
debug.log(`[${INTEGRATION_NAME}] Error while capturing end frames for span ${spanId}.`, error);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
118
147
|
const processEvent = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
119
148
|
var _a;
|
|
120
149
|
if (event.type !== 'transaction' ||
|
|
@@ -181,8 +210,20 @@ export const nativeFramesIntegration = () => {
|
|
|
181
210
|
};
|
|
182
211
|
function fetchNativeFrames() {
|
|
183
212
|
return new Promise((resolve, reject) => {
|
|
213
|
+
let settled = false;
|
|
214
|
+
const timeoutId = setTimeout(() => {
|
|
215
|
+
if (!settled) {
|
|
216
|
+
settled = true;
|
|
217
|
+
reject('Fetching native frames took too long. Dropping frames.');
|
|
218
|
+
}
|
|
219
|
+
}, FETCH_FRAMES_TIMEOUT_MS);
|
|
184
220
|
NATIVE.fetchNativeFrames()
|
|
185
221
|
.then(value => {
|
|
222
|
+
if (settled) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
clearTimeout(timeoutId);
|
|
226
|
+
settled = true;
|
|
186
227
|
if (!value) {
|
|
187
228
|
reject('Native frames response is null.');
|
|
188
229
|
return;
|
|
@@ -190,11 +231,13 @@ function fetchNativeFrames() {
|
|
|
190
231
|
resolve(value);
|
|
191
232
|
})
|
|
192
233
|
.then(undefined, error => {
|
|
234
|
+
if (settled) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
clearTimeout(timeoutId);
|
|
238
|
+
settled = true;
|
|
193
239
|
reject(error);
|
|
194
240
|
});
|
|
195
|
-
setTimeout(() => {
|
|
196
|
-
reject('Fetching native frames took too long. Dropping frames.');
|
|
197
|
-
}, FETCH_FRAMES_TIMEOUT_MS);
|
|
198
241
|
});
|
|
199
242
|
}
|
|
200
243
|
function isClose(t1, t2) {
|