@sentry/react-native 6.13.0 → 7.0.0-alpha.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/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +11 -14
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/client.d.ts +12 -0
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +24 -1
- package/dist/js/client.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.d.ts +1 -1
- package/dist/js/feedback/FeedbackWidget.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.js +18 -17
- package/dist/js/feedback/FeedbackWidget.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.types.d.ts +29 -29
- package/dist/js/feedback/FeedbackWidget.types.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.types.js.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.js +10 -6
- package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
- package/dist/js/feedback/defaults.d.ts +1 -1
- package/dist/js/feedback/defaults.d.ts.map +1 -1
- package/dist/js/feedback/defaults.js.map +1 -1
- package/dist/js/feedback/integration.d.ts +1 -1
- package/dist/js/feedback/integration.d.ts.map +1 -1
- package/dist/js/feedback/integration.js.map +1 -1
- package/dist/js/feedback/utils.d.ts +5 -0
- package/dist/js/feedback/utils.d.ts.map +1 -1
- package/dist/js/feedback/utils.js +10 -1
- package/dist/js/feedback/utils.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/debugsymbolicator.js +2 -1
- package/dist/js/integrations/debugsymbolicator.js.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.d.ts.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.js +12 -2
- package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -1
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +9 -5
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/expocontext.d.ts +18 -0
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js +20 -12
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/integrations/nativelinkederrors.js +4 -3
- package/dist/js/integrations/nativelinkederrors.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +2 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/integrations/screenshot.js +3 -3
- package/dist/js/integrations/screenshot.js.map +1 -1
- package/dist/js/integrations/spotlight.d.ts.map +1 -1
- package/dist/js/integrations/spotlight.js +8 -4
- package/dist/js/integrations/spotlight.js.map +1 -1
- package/dist/js/integrations/viewhierarchy.js +2 -1
- package/dist/js/integrations/viewhierarchy.js.map +1 -1
- package/dist/js/options.d.ts +8 -1
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/profiling/cache.d.ts +1 -1
- package/dist/js/profiling/convertHermesProfile.d.ts.map +1 -1
- package/dist/js/profiling/convertHermesProfile.js +18 -5
- package/dist/js/profiling/convertHermesProfile.js.map +1 -1
- package/dist/js/profiling/debugid.d.ts.map +1 -1
- package/dist/js/profiling/debugid.js +9 -1
- package/dist/js/profiling/debugid.js.map +1 -1
- package/dist/js/profiling/hermes.d.ts +1 -1
- package/dist/js/profiling/hermes.d.ts.map +1 -1
- package/dist/js/profiling/integration.js +2 -1
- package/dist/js/profiling/integration.js.map +1 -1
- package/dist/js/profiling/utils.d.ts.map +1 -1
- package/dist/js/profiling/utils.js +15 -17
- package/dist/js/profiling/utils.js.map +1 -1
- package/dist/js/replay/CustomMask.js +1 -1
- package/dist/js/replay/CustomMask.js.map +1 -1
- package/dist/js/replay/mobilereplay.js +2 -1
- package/dist/js/replay/mobilereplay.js.map +1 -1
- package/dist/js/scopeSync.d.ts.map +1 -1
- package/dist/js/scopeSync.js +7 -1
- package/dist/js/scopeSync.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +2 -2
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/ModulesCollector.js +1 -0
- package/dist/js/tools/ModulesCollector.js.map +1 -1
- package/dist/js/tools/collectModules.js +1 -0
- package/dist/js/tools/collectModules.js.map +1 -1
- package/dist/js/tools/enableLogger.js +1 -0
- package/dist/js/tools/enableLogger.js.map +1 -1
- package/dist/js/tools/metroMiddleware.js +2 -1
- package/dist/js/tools/metroMiddleware.js.map +1 -1
- package/dist/js/tools/metroconfig.js +5 -3
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tools/sentryBabelTransformer.js +1 -0
- package/dist/js/tools/sentryBabelTransformer.js.map +1 -1
- package/dist/js/tools/sentryBabelTransformerUtils.js +1 -0
- package/dist/js/tools/sentryBabelTransformerUtils.js.map +1 -1
- package/dist/js/tools/sentryMetroSerializer.js +1 -0
- package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
- package/dist/js/tools/utils.js +1 -0
- package/dist/js/tools/utils.js.map +1 -1
- package/dist/js/tools/vendor/expo/expoconfig.js +1 -0
- package/dist/js/tools/vendor/expo/expoconfig.js.map +1 -1
- package/dist/js/tools/vendor/metro/metroBabelTransformer.js +1 -0
- package/dist/js/tools/vendor/metro/metroBabelTransformer.js.map +1 -1
- package/dist/js/tools/vendor/metro/utils.js +1 -0
- package/dist/js/tools/vendor/metro/utils.js.map +1 -1
- package/dist/js/touchevents.d.ts.map +1 -1
- package/dist/js/touchevents.js +4 -0
- package/dist/js/touchevents.js.map +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
- package/dist/js/tracing/integrations/appStart.js +9 -2
- package/dist/js/tracing/integrations/appStart.js.map +1 -1
- package/dist/js/tracing/integrations/nativeFrames.js.map +1 -1
- package/dist/js/tracing/integrations/stalltracking.d.ts +1 -1
- package/dist/js/tracing/integrations/stalltracking.d.ts.map +1 -1
- package/dist/js/tracing/integrations/timeToDisplayIntegration.d.ts.map +1 -1
- package/dist/js/tracing/integrations/timeToDisplayIntegration.js +14 -10
- package/dist/js/tracing/integrations/timeToDisplayIntegration.js.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.d.ts +1 -1
- package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.js +2 -1
- package/dist/js/tracing/onSpanEndUtils.js.map +1 -1
- package/dist/js/tracing/reactnativenavigation.js +1 -1
- package/dist/js/tracing/reactnativenavigation.js.map +1 -1
- package/dist/js/tracing/reactnativeprofiler.d.ts +3 -1
- package/dist/js/tracing/reactnativeprofiler.d.ts.map +1 -1
- package/dist/js/tracing/reactnativeprofiler.js +2 -1
- package/dist/js/tracing/reactnativeprofiler.js.map +1 -1
- package/dist/js/tracing/reactnativetracing.d.ts +4 -1
- package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
- package/dist/js/tracing/reactnativetracing.js +5 -1
- package/dist/js/tracing/reactnativetracing.js.map +1 -1
- package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
- package/dist/js/tracing/reactnavigation.js +5 -4
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/tracing/span.js +3 -3
- package/dist/js/tracing/span.js.map +1 -1
- package/dist/js/tracing/timeToDisplayFallback.d.ts +1 -1
- package/dist/js/tracing/timeToDisplayFallback.d.ts.map +1 -1
- package/dist/js/tracing/timeToDisplayFallback.js.map +1 -1
- package/dist/js/transports/encodePolyfill.d.ts.map +1 -1
- package/dist/js/transports/encodePolyfill.js +5 -5
- package/dist/js/transports/encodePolyfill.js.map +1 -1
- package/dist/js/utils/AsyncExpiringMap.d.ts.map +1 -1
- package/dist/js/utils/AsyncExpiringMap.js +8 -4
- package/dist/js/utils/AsyncExpiringMap.js.map +1 -1
- package/dist/js/utils/envelope.d.ts.map +1 -1
- package/dist/js/utils/envelope.js +1 -2
- package/dist/js/utils/envelope.js.map +1 -1
- package/dist/js/utils/environment.d.ts.map +1 -1
- package/dist/js/utils/environment.js +5 -6
- package/dist/js/utils/environment.js.map +1 -1
- package/dist/js/utils/rnlibraries.d.ts.map +1 -1
- package/dist/js/utils/rnlibraries.js +24 -0
- package/dist/js/utils/rnlibraries.js.map +1 -1
- package/dist/js/vendor/base64-js/fromByteArray.d.ts.map +1 -1
- package/dist/js/vendor/base64-js/fromByteArray.js +6 -0
- package/dist/js/vendor/base64-js/fromByteArray.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.js +3 -2
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +12 -13
- package/plugin/build/withSentry.js +1 -1
- package/plugin/build/withSentryAndroidGradlePlugin.js +1 -1
- package/ts3.8/dist/js/client.d.ts +12 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.d.ts +1 -1
- package/ts3.8/dist/js/feedback/FeedbackWidget.types.d.ts +29 -29
- package/ts3.8/dist/js/feedback/defaults.d.ts +1 -1
- package/ts3.8/dist/js/feedback/integration.d.ts +1 -1
- package/ts3.8/dist/js/feedback/utils.d.ts +5 -0
- package/ts3.8/dist/js/index.d.ts +2 -2
- package/ts3.8/dist/js/integrations/expocontext.d.ts +18 -0
- package/ts3.8/dist/js/options.d.ts +8 -1
- package/ts3.8/dist/js/profiling/cache.d.ts +1 -1
- package/ts3.8/dist/js/profiling/hermes.d.ts +1 -1
- package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +1 -1
- package/ts3.8/dist/js/tracing/integrations/stalltracking.d.ts +1 -1
- package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +1 -1
- package/ts3.8/dist/js/tracing/reactnativeprofiler.d.ts +3 -1
- package/ts3.8/dist/js/tracing/reactnativetracing.d.ts +4 -1
- package/ts3.8/dist/js/tracing/timeToDisplayFallback.d.ts +1 -1
- package/ts3.8/dist/js/version.d.ts +1 -1
package/dist/js/touchevents.js
CHANGED
|
@@ -47,6 +47,10 @@ class TouchEventBoundary extends React.Component {
|
|
|
47
47
|
_logTouchEvent(touchPath, label) {
|
|
48
48
|
const level = 'info';
|
|
49
49
|
const root = touchPath[0];
|
|
50
|
+
if (!root) {
|
|
51
|
+
logger.warn('[TouchEvents] No root component found in touch path.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
50
54
|
const detail = label ? label : `${root.name}${root.file ? ` (${root.file})` : ''}`;
|
|
51
55
|
const crumb = {
|
|
52
56
|
category: this.props.breadcrumbCategory,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"touchevents.js","sourceRoot":"","sources":["../../src/js/touchevents.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { SeverityLevel } from '@sentry/core';\nimport { addBreadcrumb, dropUndefinedKeys, getClient, logger, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';\nimport * as React from 'react';\nimport type { GestureResponderEvent } from 'react-native';\nimport { StyleSheet, View } from 'react-native';\n\nimport { createIntegration } from './integrations/factory';\nimport { startUserInteractionSpan } from './tracing/integrations/userInteraction';\nimport { UI_ACTION_TOUCH } from './tracing/ops';\nimport { SPAN_ORIGIN_AUTO_INTERACTION } from './tracing/origin';\n\nexport type TouchEventBoundaryProps = {\n /**\n * The category assigned to the breadcrumb that is logged by the touch event.\n */\n breadcrumbCategory?: string;\n /**\n * The type assigned to the breadcrumb that is logged by the touch event.\n */\n breadcrumbType?: string;\n /**\n * The max number of components to display when logging a touch's component tree.\n */\n maxComponentTreeSize?: number;\n /**\n * Component name(s) to ignore when logging the touch event. This prevents unhelpful logs such as\n * \"Touch event within element: View\" where you still can't tell which View it occurred in.\n */\n ignoreNames?: Array<string | RegExp>;\n /**\n * Deprecated, use ignoreNames instead\n * @deprecated\n */\n ignoredDisplayNames?: Array<string | RegExp>;\n /**\n * React Node wrapped by TouchEventBoundary.\n */\n children?: React.ReactNode;\n /**\n * Label Name used to identify the touched element.\n */\n labelName?: string;\n};\n\nconst touchEventStyles = StyleSheet.create({\n wrapperView: {\n flex: 1,\n },\n});\n\nconst DEFAULT_BREADCRUMB_CATEGORY = 'touch';\nconst DEFAULT_BREADCRUMB_TYPE = 'user';\nconst DEFAULT_MAX_COMPONENT_TREE_SIZE = 20;\n\nconst SENTRY_LABEL_PROP_KEY = 'sentry-label';\nconst SENTRY_COMPONENT_PROP_KEY = 'data-sentry-component';\nconst SENTRY_ELEMENT_PROP_KEY = 'data-sentry-element';\nconst SENTRY_FILE_PROP_KEY = 'data-sentry-source-file';\n\ninterface ElementInstance {\n elementType?: {\n displayName?: string;\n name?: string;\n };\n memoizedProps?: Record<string, unknown>;\n return?: ElementInstance;\n}\n\ninterface TouchedComponentInfo {\n name?: string;\n label?: string;\n element?: string;\n file?: string;\n}\n\ninterface PrivateGestureResponderEvent extends GestureResponderEvent {\n _targetInst?: ElementInstance;\n}\n\n/**\n * Boundary to log breadcrumbs for interaction events.\n */\nclass TouchEventBoundary extends React.Component<TouchEventBoundaryProps> {\n public static displayName: string = '__Sentry.TouchEventBoundary';\n public static defaultProps: Partial<TouchEventBoundaryProps> = {\n breadcrumbCategory: DEFAULT_BREADCRUMB_CATEGORY,\n breadcrumbType: DEFAULT_BREADCRUMB_TYPE,\n ignoreNames: [],\n maxComponentTreeSize: DEFAULT_MAX_COMPONENT_TREE_SIZE,\n };\n\n public readonly name: string = 'TouchEventBoundary';\n\n /**\n * Registers the TouchEventBoundary as a Sentry Integration.\n */\n public componentDidMount(): void {\n const client = getClient();\n client?.addIntegration?.(createIntegration(this.name));\n }\n\n /**\n *\n */\n public render(): React.ReactNode {\n return (\n <View\n style={touchEventStyles.wrapperView}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onTouchStart={this._onTouchStart.bind(this) as any}\n >\n {this.props.children}\n </View>\n );\n }\n\n /**\n * Logs the touch event given the component tree names and a label.\n */\n private _logTouchEvent(touchPath: TouchedComponentInfo[], label?: string): void {\n const level = 'info' as SeverityLevel;\n\n const root = touchPath[0];\n const detail = label ? label : `${root.name}${root.file ? ` (${root.file})` : ''}`;\n\n const crumb = {\n category: this.props.breadcrumbCategory,\n data: { path: touchPath },\n level: level,\n message: `Touch event within element: ${detail}`,\n type: this.props.breadcrumbType,\n };\n addBreadcrumb(crumb);\n\n logger.log(`[TouchEvents] ${crumb.message}`);\n }\n\n /**\n * Checks if the name is supposed to be ignored.\n */\n private _isNameIgnored(name: string): boolean {\n let ignoreNames = this.props.ignoreNames || [];\n // eslint-disable-next-line deprecation/deprecation\n if (this.props.ignoredDisplayNames) {\n // This is to make it compatible with prior version.\n // eslint-disable-next-line deprecation/deprecation\n ignoreNames = [...ignoreNames, ...this.props.ignoredDisplayNames];\n }\n\n return ignoreNames.some(\n (ignoreName: string | RegExp) =>\n (typeof ignoreName === 'string' && name === ignoreName) ||\n (ignoreName instanceof RegExp && name.match(ignoreName)),\n );\n }\n\n // Originally was going to clean the names of any HOCs as well but decided that it might hinder debugging effectively. Will leave here in case\n // private readonly _cleanName = (name: string): string =>\n // name.replace(/.*\\(/g, \"\").replace(/\\)/g, \"\");\n\n /**\n * Traverses through the component tree when a touch happens and logs it.\n * @param e\n */\n // eslint-disable-next-line complexity\n private _onTouchStart(e: PrivateGestureResponderEvent): void {\n if (!e._targetInst) {\n return;\n }\n\n let currentInst: ElementInstance | undefined = e._targetInst;\n const touchPath: TouchedComponentInfo[] = [];\n\n while (\n currentInst &&\n // maxComponentTreeSize will always be defined as we have a defaultProps. But ts needs a check so this is here.\n this.props.maxComponentTreeSize &&\n touchPath.length < this.props.maxComponentTreeSize\n ) {\n if (\n // If the loop gets to the boundary itself, break.\n currentInst.elementType?.displayName === TouchEventBoundary.displayName\n ) {\n break;\n }\n\n const info = getTouchedComponentInfo(currentInst, this.props.labelName);\n this._pushIfNotIgnored(touchPath, info);\n\n currentInst = currentInst.return;\n }\n\n const label = touchPath.find(info => info.label)?.label;\n if (touchPath.length > 0) {\n this._logTouchEvent(touchPath, label);\n }\n\n const span = startUserInteractionSpan({\n elementId: label,\n op: UI_ACTION_TOUCH,\n });\n if (span) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_AUTO_INTERACTION);\n }\n }\n\n /**\n * Pushes the name to the componentTreeNames array if it is not ignored.\n */\n private _pushIfNotIgnored(touchPath: TouchedComponentInfo[], value: TouchedComponentInfo | undefined): boolean {\n if (!value) {\n return false;\n }\n\n if (!value.name && !value.label) {\n return false;\n }\n if (value.name && this._isNameIgnored(value.name)) {\n return false;\n }\n if (value.label && this._isNameIgnored(value.label)) {\n return false;\n }\n\n // Deduplicate same subsequent items.\n if (touchPath.length > 0 && JSON.stringify(touchPath[touchPath.length - 1]) === JSON.stringify(value)) {\n return false;\n }\n\n touchPath.push(value);\n return true;\n }\n}\n\nfunction getTouchedComponentInfo(currentInst: ElementInstance, labelKey: string | undefined): TouchedComponentInfo | undefined {\n const displayName = currentInst.elementType?.displayName;\n\n const props = currentInst.memoizedProps;\n if (!props) {\n // Early return if no props are available, as we can't extract any useful information\n if (displayName) {\n return {\n name: displayName,\n };\n }\n return undefined;\n }\n\n return dropUndefinedKeys<TouchedComponentInfo>({\n // provided by @sentry/babel-plugin-component-annotate\n name: getComponentName(props) || displayName,\n element: getElementName(props),\n file: getFileName(props),\n\n // `sentry-label` or user defined label key\n label: getLabelValue(props, labelKey),\n });\n}\n\nfunction getComponentName(props: Record<string, unknown>): string | undefined {\n return typeof props[SENTRY_COMPONENT_PROP_KEY] === 'string' &&\n props[SENTRY_COMPONENT_PROP_KEY].length > 0 &&\n props[SENTRY_COMPONENT_PROP_KEY] !== 'unknown' &&\n props[SENTRY_COMPONENT_PROP_KEY] || undefined;\n}\n\nfunction getElementName(props: Record<string, unknown>): string | undefined {\n return typeof props[SENTRY_ELEMENT_PROP_KEY] === 'string' &&\n props[SENTRY_ELEMENT_PROP_KEY].length > 0 &&\n props[SENTRY_ELEMENT_PROP_KEY] !== 'unknown' &&\n props[SENTRY_ELEMENT_PROP_KEY] || undefined;\n}\n\nfunction getFileName(props: Record<string, unknown>): string | undefined {\n return typeof props[SENTRY_FILE_PROP_KEY] === 'string' &&\n props[SENTRY_FILE_PROP_KEY].length > 0 &&\n props[SENTRY_FILE_PROP_KEY] !== 'unknown' &&\n props[SENTRY_FILE_PROP_KEY] || undefined;\n}\n\nfunction getLabelValue(props: Record<string, unknown>, labelKey: string | undefined): string | undefined {\n return typeof props[SENTRY_LABEL_PROP_KEY] === 'string' && props[SENTRY_LABEL_PROP_KEY].length > 0\n ? props[SENTRY_LABEL_PROP_KEY] as string\n // For some reason type narrowing doesn't work as expected with indexing when checking it all in one go in\n // the \"check-label\" if sentence, so we have to assign it to a variable here first\n : typeof labelKey === 'string' && typeof props[labelKey] == 'string' && (props[labelKey] as string).length > 0\n ? props[labelKey] as string\n : undefined;\n}\n\n/**\n * Convenience Higher-Order-Component for TouchEventBoundary\n * @param WrappedComponent any React Component\n * @param boundaryProps TouchEventBoundaryProps\n */\nconst withTouchEventBoundary = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n InnerComponent: React.ComponentType<any>,\n boundaryProps?: TouchEventBoundaryProps,\n): React.FunctionComponent => {\n const WrappedComponent: React.FunctionComponent = props => (\n <TouchEventBoundary {...(boundaryProps ?? {})}>\n <InnerComponent {...props} />\n </TouchEventBoundary>\n );\n\n WrappedComponent.displayName = 'WithTouchEventBoundary';\n\n return WrappedComponent;\n};\n\nexport { TouchEventBoundary, withTouchEventBoundary };\n"]}
|
|
1
|
+
{"version":3,"file":"touchevents.js","sourceRoot":"","sources":["../../src/js/touchevents.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AACrH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAmChE,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC;IACzC,WAAW,EAAE;QACX,IAAI,EAAE,CAAC;KACR;CACF,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG,OAAO,CAAC;AAC5C,MAAM,uBAAuB,GAAG,MAAM,CAAC;AACvC,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAE3C,MAAM,qBAAqB,GAAG,cAAc,CAAC;AAC7C,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAC1D,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;AACtD,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAsBvD;;GAEG;AACH,MAAM,kBAAmB,SAAQ,KAAK,CAAC,SAAkC;IAAzE;;QASkB,SAAI,GAAW,oBAAoB,CAAC;IAiJtD,CAAC;IA/IC;;OAEG;IACI,iBAAiB;;QACtB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,uDAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACI,MAAM;QACX,OAAO,CACL,oBAAC,IAAI,IACH,KAAK,EAAE,gBAAgB,CAAC,WAAW;YACnC,8DAA8D;YAC9D,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAQ,IAEjD,IAAI,CAAC,KAAK,CAAC,QAAQ,CACf,CACR,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,SAAiC,EAAE,KAAc;QACtE,MAAM,KAAK,GAAG,MAAuB,CAAC;QAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;YACpE,OAAO;SACR;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnF,MAAM,KAAK,GAAG;YACZ,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,kBAAkB;YACvC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;YACzB,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,+BAA+B,MAAM,EAAE;YAChD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc;SAChC,CAAC;QACF,aAAa,CAAC,KAAK,CAAC,CAAC;QAErB,MAAM,CAAC,GAAG,CAAC,iBAAiB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAY;QACjC,IAAI,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;QAC/C,mDAAmD;QACnD,IAAI,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE;YAClC,oDAAoD;YACpD,mDAAmD;YACnD,WAAW,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;SACnE;QAED,OAAO,WAAW,CAAC,IAAI,CACrB,CAAC,UAA2B,EAAE,EAAE,CAC9B,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,IAAI,KAAK,UAAU,CAAC;YACvD,CAAC,UAAU,YAAY,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAC3D,CAAC;IACJ,CAAC;IAED,8IAA8I;IAC9I,0DAA0D;IAC1D,kDAAkD;IAElD;;;OAGG;IACH,sCAAsC;IAC9B,aAAa,CAAC,CAA+B;;QACnD,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;YAClB,OAAO;SACR;QAED,IAAI,WAAW,GAAgC,CAAC,CAAC,WAAW,CAAC;QAC7D,MAAM,SAAS,GAA2B,EAAE,CAAC;QAE7C,OACE,WAAW;YACX,+GAA+G;YAC/G,IAAI,CAAC,KAAK,CAAC,oBAAoB;YAC/B,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAClD;YACA;YACE,kDAAkD;YAClD,CAAA,MAAA,WAAW,CAAC,WAAW,0CAAE,WAAW,MAAK,kBAAkB,CAAC,WAAW,EACvE;gBACA,MAAM;aACP;YAED,MAAM,IAAI,GAAG,uBAAuB,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACxE,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAExC,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;SAClC;QAED,MAAM,KAAK,GAAG,MAAA,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,0CAAE,KAAK,CAAC;QACxD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;SACvC;QAED,MAAM,IAAI,GAAG,wBAAwB,CAAC;YACpC,SAAS,EAAE,KAAK;YAChB,EAAE,EAAE,eAAe;SACpB,CAAC,CAAC;QACH,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,4BAA4B,CAAC,CAAC;SACnF;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,SAAiC,EAAE,KAAuC;QAClG,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YAC/B,OAAO,KAAK,CAAC;SACd;QACD,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACjD,OAAO,KAAK,CAAC;SACd;QACD,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YACnD,OAAO,KAAK,CAAC;SACd;QAED,qCAAqC;QACrC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YACrG,OAAO,KAAK,CAAC;SACd;QAED,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;;AAxJa,8BAAW,GAAW,6BAA6B,CAAC;AACpD,+BAAY,GAAqC;IAC7D,kBAAkB,EAAE,2BAA2B;IAC/C,cAAc,EAAE,uBAAuB;IACvC,WAAW,EAAE,EAAE;IACf,oBAAoB,EAAE,+BAA+B;CACtD,CAAC;AAqJJ,SAAS,uBAAuB,CAAC,WAA4B,EAAE,QAA4B;;IACzF,MAAM,WAAW,GAAG,MAAA,WAAW,CAAC,WAAW,0CAAE,WAAW,CAAC;IAEzD,MAAM,KAAK,GAAG,WAAW,CAAC,aAAa,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE;QACV,qFAAqF;QACrF,IAAI,WAAW,EAAE;YACf,OAAO;gBACL,IAAI,EAAE,WAAW;aAClB,CAAC;SACH;QACD,OAAO,SAAS,CAAC;KAClB;IAED,OAAO,iBAAiB,CAAuB;QAC7C,sDAAsD;QACtD,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,IAAI,WAAW;QAC5C,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC;QAC9B,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC;QAExB,2CAA2C;QAC3C,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC;KACtC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,KAA8B;IACtD,OAAO,OAAO,KAAK,CAAC,yBAAyB,CAAC,KAAK,QAAQ;QACzD,KAAK,CAAC,yBAAyB,CAAC,CAAC,MAAM,GAAG,CAAC;QAC3C,KAAK,CAAC,yBAAyB,CAAC,KAAK,SAAS;QAC9C,KAAK,CAAC,yBAAyB,CAAC,IAAI,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,KAA8B;IACpD,OAAO,OAAO,KAAK,CAAC,uBAAuB,CAAC,KAAK,QAAQ;QACvD,KAAK,CAAC,uBAAuB,CAAC,CAAC,MAAM,GAAG,CAAC;QACzC,KAAK,CAAC,uBAAuB,CAAC,KAAK,SAAS;QAC5C,KAAK,CAAC,uBAAuB,CAAC,IAAI,SAAS,CAAC;AAChD,CAAC;AAED,SAAS,WAAW,CAAC,KAA8B;IACjD,OAAO,OAAO,KAAK,CAAC,oBAAoB,CAAC,KAAK,QAAQ;QACpD,KAAK,CAAC,oBAAoB,CAAC,CAAC,MAAM,GAAG,CAAC;QACtC,KAAK,CAAC,oBAAoB,CAAC,KAAK,SAAS;QACzC,KAAK,CAAC,oBAAoB,CAAC,IAAI,SAAS,CAAC;AAC7C,CAAC;AAED,SAAS,aAAa,CAAC,KAA8B,EAAE,QAA4B;IACjF,OAAO,OAAO,KAAK,CAAC,qBAAqB,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,MAAM,GAAG,CAAC;QAChG,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAW;QACxC,0GAA0G;QAC1G,kFAAkF;QAClF,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAK,KAAK,CAAC,QAAQ,CAAY,CAAC,MAAM,GAAG,CAAC;YAC5G,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAW;YAC3B,CAAC,CAAC,SAAS,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,sBAAsB,GAAG;AAC7B,8DAA8D;AAC9D,cAAwC,EACxC,aAAuC,EACd,EAAE;IAC3B,MAAM,gBAAgB,GAA4B,KAAK,CAAC,EAAE,CAAC,CACzD,oBAAC,kBAAkB,oBAAK,CAAC,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,CAAC;QAC3C,oBAAC,cAAc,oBAAK,KAAK,EAAI,CACV,CACtB,CAAC;IAEF,gBAAgB,CAAC,WAAW,GAAG,wBAAwB,CAAC;IAExD,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,CAAC","sourcesContent":["import type { SeverityLevel } from '@sentry/core';\nimport { addBreadcrumb, dropUndefinedKeys, getClient, logger, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';\nimport * as React from 'react';\nimport type { GestureResponderEvent } from 'react-native';\nimport { StyleSheet, View } from 'react-native';\n\nimport { createIntegration } from './integrations/factory';\nimport { startUserInteractionSpan } from './tracing/integrations/userInteraction';\nimport { UI_ACTION_TOUCH } from './tracing/ops';\nimport { SPAN_ORIGIN_AUTO_INTERACTION } from './tracing/origin';\n\nexport type TouchEventBoundaryProps = {\n /**\n * The category assigned to the breadcrumb that is logged by the touch event.\n */\n breadcrumbCategory?: string;\n /**\n * The type assigned to the breadcrumb that is logged by the touch event.\n */\n breadcrumbType?: string;\n /**\n * The max number of components to display when logging a touch's component tree.\n */\n maxComponentTreeSize?: number;\n /**\n * Component name(s) to ignore when logging the touch event. This prevents unhelpful logs such as\n * \"Touch event within element: View\" where you still can't tell which View it occurred in.\n */\n ignoreNames?: Array<string | RegExp>;\n /**\n * Deprecated, use ignoreNames instead\n * @deprecated\n */\n ignoredDisplayNames?: Array<string | RegExp>;\n /**\n * React Node wrapped by TouchEventBoundary.\n */\n children?: React.ReactNode;\n /**\n * Label Name used to identify the touched element.\n */\n labelName?: string;\n};\n\nconst touchEventStyles = StyleSheet.create({\n wrapperView: {\n flex: 1,\n },\n});\n\nconst DEFAULT_BREADCRUMB_CATEGORY = 'touch';\nconst DEFAULT_BREADCRUMB_TYPE = 'user';\nconst DEFAULT_MAX_COMPONENT_TREE_SIZE = 20;\n\nconst SENTRY_LABEL_PROP_KEY = 'sentry-label';\nconst SENTRY_COMPONENT_PROP_KEY = 'data-sentry-component';\nconst SENTRY_ELEMENT_PROP_KEY = 'data-sentry-element';\nconst SENTRY_FILE_PROP_KEY = 'data-sentry-source-file';\n\ninterface ElementInstance {\n elementType?: {\n displayName?: string;\n name?: string;\n };\n memoizedProps?: Record<string, unknown>;\n return?: ElementInstance;\n}\n\ninterface TouchedComponentInfo {\n name?: string;\n label?: string;\n element?: string;\n file?: string;\n}\n\ninterface PrivateGestureResponderEvent extends GestureResponderEvent {\n _targetInst?: ElementInstance;\n}\n\n/**\n * Boundary to log breadcrumbs for interaction events.\n */\nclass TouchEventBoundary extends React.Component<TouchEventBoundaryProps> {\n public static displayName: string = '__Sentry.TouchEventBoundary';\n public static defaultProps: Partial<TouchEventBoundaryProps> = {\n breadcrumbCategory: DEFAULT_BREADCRUMB_CATEGORY,\n breadcrumbType: DEFAULT_BREADCRUMB_TYPE,\n ignoreNames: [],\n maxComponentTreeSize: DEFAULT_MAX_COMPONENT_TREE_SIZE,\n };\n\n public readonly name: string = 'TouchEventBoundary';\n\n /**\n * Registers the TouchEventBoundary as a Sentry Integration.\n */\n public componentDidMount(): void {\n const client = getClient();\n client?.addIntegration?.(createIntegration(this.name));\n }\n\n /**\n *\n */\n public render(): React.ReactNode {\n return (\n <View\n style={touchEventStyles.wrapperView}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onTouchStart={this._onTouchStart.bind(this) as any}\n >\n {this.props.children}\n </View>\n );\n }\n\n /**\n * Logs the touch event given the component tree names and a label.\n */\n private _logTouchEvent(touchPath: TouchedComponentInfo[], label?: string): void {\n const level = 'info' as SeverityLevel;\n\n const root = touchPath[0];\n if (!root) {\n logger.warn('[TouchEvents] No root component found in touch path.');\n return;\n }\n\n const detail = label ? label : `${root.name}${root.file ? ` (${root.file})` : ''}`;\n const crumb = {\n category: this.props.breadcrumbCategory,\n data: { path: touchPath },\n level: level,\n message: `Touch event within element: ${detail}`,\n type: this.props.breadcrumbType,\n };\n addBreadcrumb(crumb);\n\n logger.log(`[TouchEvents] ${crumb.message}`);\n }\n\n /**\n * Checks if the name is supposed to be ignored.\n */\n private _isNameIgnored(name: string): boolean {\n let ignoreNames = this.props.ignoreNames || [];\n // eslint-disable-next-line deprecation/deprecation\n if (this.props.ignoredDisplayNames) {\n // This is to make it compatible with prior version.\n // eslint-disable-next-line deprecation/deprecation\n ignoreNames = [...ignoreNames, ...this.props.ignoredDisplayNames];\n }\n\n return ignoreNames.some(\n (ignoreName: string | RegExp) =>\n (typeof ignoreName === 'string' && name === ignoreName) ||\n (ignoreName instanceof RegExp && name.match(ignoreName)),\n );\n }\n\n // Originally was going to clean the names of any HOCs as well but decided that it might hinder debugging effectively. Will leave here in case\n // private readonly _cleanName = (name: string): string =>\n // name.replace(/.*\\(/g, \"\").replace(/\\)/g, \"\");\n\n /**\n * Traverses through the component tree when a touch happens and logs it.\n * @param e\n */\n // eslint-disable-next-line complexity\n private _onTouchStart(e: PrivateGestureResponderEvent): void {\n if (!e._targetInst) {\n return;\n }\n\n let currentInst: ElementInstance | undefined = e._targetInst;\n const touchPath: TouchedComponentInfo[] = [];\n\n while (\n currentInst &&\n // maxComponentTreeSize will always be defined as we have a defaultProps. But ts needs a check so this is here.\n this.props.maxComponentTreeSize &&\n touchPath.length < this.props.maxComponentTreeSize\n ) {\n if (\n // If the loop gets to the boundary itself, break.\n currentInst.elementType?.displayName === TouchEventBoundary.displayName\n ) {\n break;\n }\n\n const info = getTouchedComponentInfo(currentInst, this.props.labelName);\n this._pushIfNotIgnored(touchPath, info);\n\n currentInst = currentInst.return;\n }\n\n const label = touchPath.find(info => info.label)?.label;\n if (touchPath.length > 0) {\n this._logTouchEvent(touchPath, label);\n }\n\n const span = startUserInteractionSpan({\n elementId: label,\n op: UI_ACTION_TOUCH,\n });\n if (span) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_AUTO_INTERACTION);\n }\n }\n\n /**\n * Pushes the name to the componentTreeNames array if it is not ignored.\n */\n private _pushIfNotIgnored(touchPath: TouchedComponentInfo[], value: TouchedComponentInfo | undefined): boolean {\n if (!value) {\n return false;\n }\n\n if (!value.name && !value.label) {\n return false;\n }\n if (value.name && this._isNameIgnored(value.name)) {\n return false;\n }\n if (value.label && this._isNameIgnored(value.label)) {\n return false;\n }\n\n // Deduplicate same subsequent items.\n if (touchPath.length > 0 && JSON.stringify(touchPath[touchPath.length - 1]) === JSON.stringify(value)) {\n return false;\n }\n\n touchPath.push(value);\n return true;\n }\n}\n\nfunction getTouchedComponentInfo(currentInst: ElementInstance, labelKey: string | undefined): TouchedComponentInfo | undefined {\n const displayName = currentInst.elementType?.displayName;\n\n const props = currentInst.memoizedProps;\n if (!props) {\n // Early return if no props are available, as we can't extract any useful information\n if (displayName) {\n return {\n name: displayName,\n };\n }\n return undefined;\n }\n\n return dropUndefinedKeys<TouchedComponentInfo>({\n // provided by @sentry/babel-plugin-component-annotate\n name: getComponentName(props) || displayName,\n element: getElementName(props),\n file: getFileName(props),\n\n // `sentry-label` or user defined label key\n label: getLabelValue(props, labelKey),\n });\n}\n\nfunction getComponentName(props: Record<string, unknown>): string | undefined {\n return typeof props[SENTRY_COMPONENT_PROP_KEY] === 'string' &&\n props[SENTRY_COMPONENT_PROP_KEY].length > 0 &&\n props[SENTRY_COMPONENT_PROP_KEY] !== 'unknown' &&\n props[SENTRY_COMPONENT_PROP_KEY] || undefined;\n}\n\nfunction getElementName(props: Record<string, unknown>): string | undefined {\n return typeof props[SENTRY_ELEMENT_PROP_KEY] === 'string' &&\n props[SENTRY_ELEMENT_PROP_KEY].length > 0 &&\n props[SENTRY_ELEMENT_PROP_KEY] !== 'unknown' &&\n props[SENTRY_ELEMENT_PROP_KEY] || undefined;\n}\n\nfunction getFileName(props: Record<string, unknown>): string | undefined {\n return typeof props[SENTRY_FILE_PROP_KEY] === 'string' &&\n props[SENTRY_FILE_PROP_KEY].length > 0 &&\n props[SENTRY_FILE_PROP_KEY] !== 'unknown' &&\n props[SENTRY_FILE_PROP_KEY] || undefined;\n}\n\nfunction getLabelValue(props: Record<string, unknown>, labelKey: string | undefined): string | undefined {\n return typeof props[SENTRY_LABEL_PROP_KEY] === 'string' && props[SENTRY_LABEL_PROP_KEY].length > 0\n ? props[SENTRY_LABEL_PROP_KEY] as string\n // For some reason type narrowing doesn't work as expected with indexing when checking it all in one go in\n // the \"check-label\" if sentence, so we have to assign it to a variable here first\n : typeof labelKey === 'string' && typeof props[labelKey] == 'string' && (props[labelKey] as string).length > 0\n ? props[labelKey] as string\n : undefined;\n}\n\n/**\n * Convenience Higher-Order-Component for TouchEventBoundary\n * @param WrappedComponent any React Component\n * @param boundaryProps TouchEventBoundaryProps\n */\nconst withTouchEventBoundary = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n InnerComponent: React.ComponentType<any>,\n boundaryProps?: TouchEventBoundaryProps,\n): React.FunctionComponent => {\n const WrappedComponent: React.FunctionComponent = props => (\n <TouchEventBoundary {...(boundaryProps ?? {})}>\n <InnerComponent {...props} />\n </TouchEventBoundary>\n );\n\n WrappedComponent.displayName = 'WithTouchEventBoundary';\n\n return WrappedComponent;\n};\n\nexport { TouchEventBoundary, withTouchEventBoundary };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appStart.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/appStart.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,WAAW,EAAoC,MAAM,cAAc,CAAC;AAiCjG,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,yBAAyB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,CAAC;AAqBF;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzF;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG9E;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,gBAAiB,MAAM,KAAG,IAGhE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,IAAI,CAE7D;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAG9B;;;;;OAKG
|
|
1
|
+
{"version":3,"file":"appStart.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/appStart.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,WAAW,EAAoC,MAAM,cAAc,CAAC;AAiCjG,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,yBAAyB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,CAAC;AAqBF;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzF;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG9E;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,gBAAiB,MAAM,KAAG,IAGhE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,IAAI,CAE7D;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAG9B;;;;;OAKG;;MAEI,mBAiRR,CAAC"}
|
|
@@ -160,6 +160,12 @@ export const appStartIntegration = ({ standalone = false, } = {}) => {
|
|
|
160
160
|
};
|
|
161
161
|
function captureStandaloneAppStart() {
|
|
162
162
|
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
if (!_client) {
|
|
164
|
+
// If client is not set, SDK was not initialized, logger is thus disabled
|
|
165
|
+
// eslint-disable-next-line no-console
|
|
166
|
+
console.warn('[AppStart] Could not capture App Start, missing client, call `Sentry.init` first.');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
163
169
|
if (!standalone) {
|
|
164
170
|
logger.debug('[AppStart] App start tracking is enabled. App start will be added to the first transaction as a child span.');
|
|
165
171
|
return;
|
|
@@ -191,6 +197,7 @@ export const appStartIntegration = ({ standalone = false, } = {}) => {
|
|
|
191
197
|
});
|
|
192
198
|
}
|
|
193
199
|
function attachAppStartToTransactionEvent(event) {
|
|
200
|
+
var _a;
|
|
194
201
|
return __awaiter(this, void 0, void 0, function* () {
|
|
195
202
|
if (appStartDataFlushed) {
|
|
196
203
|
// App start data is only relevant for the first transaction of the app run
|
|
@@ -200,7 +207,7 @@ export const appStartIntegration = ({ standalone = false, } = {}) => {
|
|
|
200
207
|
logger.warn('[AppStart] No first started active root span id recorded. Can not attach app start.');
|
|
201
208
|
return;
|
|
202
209
|
}
|
|
203
|
-
if (!event.contexts ||
|
|
210
|
+
if (!((_a = event.contexts) === null || _a === void 0 ? void 0 : _a.trace)) {
|
|
204
211
|
logger.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.');
|
|
205
212
|
return;
|
|
206
213
|
}
|
|
@@ -275,7 +282,7 @@ export const appStartIntegration = ({ standalone = false, } = {}) => {
|
|
|
275
282
|
const op = appStart.type === 'cold' ? APP_START_COLD_OP : APP_START_WARM_OP;
|
|
276
283
|
const appStartSpanJSON = createSpanJSON({
|
|
277
284
|
op,
|
|
278
|
-
description: appStart.type === 'cold' ? 'Cold
|
|
285
|
+
description: appStart.type === 'cold' ? 'Cold Start' : 'Warm Start',
|
|
279
286
|
start_timestamp: appStartTimestampSeconds,
|
|
280
287
|
timestamp: appStartEndTimestampSeconds,
|
|
281
288
|
trace_id: event.contexts.trace.trace_id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appStart.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/appStart.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity, max-lines */\nimport type { Client, Event, Integration, Span, SpanJSON, TransactionEvent } from '@sentry/core';\nimport {\n getCapturedScopesOnSpan,\n getClient,\n getCurrentScope,\n logger,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SentryNonRecordingSpan,\n startInactiveSpan,\n timestampInSeconds,\n} from '@sentry/core';\n\nimport { getAppRegistryIntegration } from '../../integrations/appRegistry';\nimport {\n APP_START_COLD as APP_START_COLD_MEASUREMENT,\n APP_START_WARM as APP_START_WARM_MEASUREMENT,\n} from '../../measurements';\nimport type { NativeAppStartResponse } from '../../NativeRNSentry';\nimport type { ReactNativeClientOptions } from '../../options';\nimport { convertSpanToTransaction, isRootSpan, setEndTimeValue } from '../../utils/span';\nimport { NATIVE } from '../../wrapper';\nimport {\n APP_START_COLD as APP_START_COLD_OP,\n APP_START_WARM as APP_START_WARM_OP,\n UI_LOAD as UI_LOAD_OP,\n} from '../ops';\nimport { SPAN_ORIGIN_AUTO_APP_START, SPAN_ORIGIN_MANUAL_APP_START } from '../origin';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../semanticAttributes';\nimport { setMainThreadInfo } from '../span';\nimport { createChildSpanJSON, createSpanJSON, getBundleStartTimestampMs } from '../utils';\n\nconst INTEGRATION_NAME = 'AppStart';\n\nexport type AppStartIntegration = Integration & {\n captureStandaloneAppStart: () => Promise<void>;\n};\n\n/**\n * We filter out app start more than 60s.\n * This could be due to many different reasons.\n * We've seen app starts with hours, days and even months.\n */\nconst MAX_APP_START_DURATION_MS = 60_000;\n\n/** We filter out App starts which timestamp is 60s and more before the transaction start */\nconst MAX_APP_START_AGE_MS = 60_000;\n\n/** App Start transaction name */\nconst APP_START_TX_NAME = 'App Start';\n\nlet recordedAppStartEndTimestampMs: number | undefined = undefined;\nlet isRecordedAppStartEndTimestampMsManual = false;\n\nlet rootComponentCreationTimestampMs: number | undefined = undefined;\nlet isRootComponentCreationTimestampMsManual = false;\n\n/**\n * Records the application start end.\n * Used automatically by `Sentry.wrap` and `Sentry.ReactNativeProfiler`.\n */\nexport function captureAppStart(): Promise<void> {\n return _captureAppStart({ isManual: true });\n}\n\n/**\n * For internal use only.\n *\n * @private\n */\nexport async function _captureAppStart({ isManual }: { isManual: boolean }): Promise<void> {\n const client = getClient();\n if (!client) {\n logger.warn('[AppStart] Could not capture App Start, missing client.');\n return;\n }\n\n isRecordedAppStartEndTimestampMsManual = isManual;\n _setAppStartEndTimestampMs(timestampInSeconds() * 1000);\n await client.getIntegrationByName<AppStartIntegration>(INTEGRATION_NAME)?.captureStandaloneAppStart();\n}\n\n/**\n * Sets the root component first constructor call timestamp.\n * Used automatically by `Sentry.wrap` and `Sentry.ReactNativeProfiler`.\n */\nexport function setRootComponentCreationTimestampMs(timestampMs: number): void {\n recordedAppStartEndTimestampMs &&\n logger.warn('Setting Root component creation timestamp after app start end is set.');\n rootComponentCreationTimestampMs && logger.warn('Overwriting already set root component creation timestamp.');\n rootComponentCreationTimestampMs = timestampMs;\n isRootComponentCreationTimestampMsManual = true;\n}\n\n/**\n * For internal use only.\n *\n * @private\n */\nexport function _setRootComponentCreationTimestampMs(timestampMs: number): void {\n setRootComponentCreationTimestampMs(timestampMs);\n isRootComponentCreationTimestampMsManual = false;\n}\n\n/**\n * For internal use only.\n *\n * @private\n */\nexport const _setAppStartEndTimestampMs = (timestampMs: number): void => {\n recordedAppStartEndTimestampMs && logger.warn('Overwriting already set app start.');\n recordedAppStartEndTimestampMs = timestampMs;\n};\n\n/**\n * For testing purposes only.\n *\n * @private\n */\nexport function _clearRootComponentCreationTimestampMs(): void {\n rootComponentCreationTimestampMs = undefined;\n}\n\n/**\n * Adds AppStart spans from the native layer to the transaction event.\n */\nexport const appStartIntegration = ({\n standalone = false,\n}: {\n /**\n * Should the integration send App Start as a standalone root span (transaction)?\n * If false, App Start will be added as a child span to the first transaction.\n *\n * @default false\n */\n standalone?: boolean;\n} = {}): AppStartIntegration => {\n let _client: Client | undefined = undefined;\n let isEnabled = true;\n let appStartDataFlushed = false;\n let afterAllSetupCalled = false;\n let firstStartedActiveRootSpanId: string | undefined = undefined;\n\n const setup = (client: Client): void => {\n _client = client;\n const { enableAppStartTracking } = client.getOptions() as ReactNativeClientOptions;\n\n if (!enableAppStartTracking) {\n isEnabled = false;\n logger.warn('[AppStart] App start tracking is disabled.');\n }\n\n client.on('spanStart', recordFirstStartedActiveRootSpanId);\n };\n\n const afterAllSetup = (client: Client): void => {\n if (afterAllSetupCalled) {\n return;\n }\n afterAllSetupCalled = true;\n\n // TODO: automatically set standalone based on the presence of the native layer navigation integration\n\n getAppRegistryIntegration(client)?.onRunApplication(() => {\n if (appStartDataFlushed) {\n logger.log('[AppStartIntegration] Resetting app start data flushed flag based on runApplication call.');\n appStartDataFlushed = false;\n firstStartedActiveRootSpanId = undefined;\n } else {\n logger.log(\n '[AppStartIntegration] Waiting for initial app start was flush, before updating based on runApplication call.',\n );\n }\n });\n };\n\n const processEvent = async (event: Event): Promise<Event> => {\n if (!isEnabled || standalone) {\n return event;\n }\n\n if (event.type !== 'transaction') {\n // App start data is only relevant for transactions\n return event;\n }\n\n await attachAppStartToTransactionEvent(event as TransactionEvent);\n\n return event;\n };\n\n const recordFirstStartedActiveRootSpanId = (rootSpan: Span): void => {\n if (firstStartedActiveRootSpanId) {\n return;\n }\n\n if (!isRootSpan(rootSpan)) {\n return;\n }\n\n setFirstStartedActiveRootSpanId(rootSpan.spanContext().spanId);\n };\n\n /**\n * For testing purposes only.\n * @private\n */\n const setFirstStartedActiveRootSpanId = (spanId: string | undefined): void => {\n firstStartedActiveRootSpanId = spanId;\n logger.debug('[AppStart] First started active root span id recorded.', firstStartedActiveRootSpanId);\n };\n\n async function captureStandaloneAppStart(): Promise<void> {\n if (!standalone) {\n logger.debug(\n '[AppStart] App start tracking is enabled. App start will be added to the first transaction as a child span.',\n );\n return;\n }\n\n logger.debug('[AppStart] App start tracking standalone root span (transaction).');\n\n const span = startInactiveSpan({\n forceTransaction: true,\n name: APP_START_TX_NAME,\n op: UI_LOAD_OP,\n });\n if (span instanceof SentryNonRecordingSpan) {\n // Tracing is disabled or the transaction was sampled\n return;\n }\n\n setEndTimeValue(span, timestampInSeconds());\n _client.emit('spanEnd', span);\n\n const event = convertSpanToTransaction(span);\n if (!event) {\n logger.warn('[AppStart] Failed to convert App Start span to transaction.');\n return;\n }\n\n await attachAppStartToTransactionEvent(event);\n if (!event.spans || event.spans.length === 0) {\n // No spans were added to the transaction, so we don't need to send it\n return;\n }\n\n const scope = getCapturedScopesOnSpan(span).scope || getCurrentScope();\n scope.captureEvent(event);\n }\n\n async function attachAppStartToTransactionEvent(event: TransactionEvent): Promise<void> {\n if (appStartDataFlushed) {\n // App start data is only relevant for the first transaction of the app run\n return;\n }\n\n if (!firstStartedActiveRootSpanId) {\n logger.warn('[AppStart] No first started active root span id recorded. Can not attach app start.');\n return;\n }\n\n if (!event.contexts || !event.contexts.trace) {\n logger.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.');\n return;\n }\n\n if (firstStartedActiveRootSpanId !== event.contexts.trace.span_id) {\n logger.warn(\n '[AppStart] First started active root span id does not match the transaction event span id. Can not attached app start.',\n );\n return;\n }\n\n const appStart = await NATIVE.fetchNativeAppStart();\n if (!appStart) {\n logger.warn('[AppStart] Failed to retrieve the app start metrics from the native layer.');\n return;\n }\n if (appStart.has_fetched) {\n logger.warn('[AppStart] Measured app start metrics were already reported from the native layer.');\n return;\n }\n\n const appStartTimestampMs = appStart.app_start_timestamp_ms;\n if (!appStartTimestampMs) {\n logger.warn('[AppStart] App start timestamp could not be loaded from the native layer.');\n return;\n }\n\n const appStartEndTimestampMs = recordedAppStartEndTimestampMs || getBundleStartTimestampMs();\n if (!appStartEndTimestampMs) {\n logger.warn(\n '[AppStart] Javascript failed to record app start end. `setAppStartEndTimestampMs` was not called nor could the bundle start be found.',\n );\n return;\n }\n\n const isAppStartWithinBounds =\n !!event.start_timestamp && appStartTimestampMs >= event.start_timestamp * 1_000 - MAX_APP_START_AGE_MS;\n if (!__DEV__ && !isAppStartWithinBounds) {\n logger.warn('[AppStart] App start timestamp is too far in the past to be used for app start span.');\n return;\n }\n\n const appStartDurationMs = appStartEndTimestampMs - appStartTimestampMs;\n if (!__DEV__ && appStartDurationMs >= MAX_APP_START_DURATION_MS) {\n // Dev builds can have long app start waiting over minute for the first bundle to be produced\n logger.warn('[AppStart] App start duration is over a minute long, not adding app start span.');\n return;\n }\n\n if (appStartDurationMs < 0) {\n // This can happen when MainActivity on Android is recreated,\n // and the app start end timestamp is not updated, for example\n // due to missing `Sentry.wrap(RootComponent)` call.\n logger.warn(\n '[AppStart] Last recorded app start end timestamp is before the app start timestamp.',\n 'This is usually caused by missing `Sentry.wrap(RootComponent)` call.',\n );\n return;\n }\n\n appStartDataFlushed = true;\n\n event.contexts.trace.data = event.contexts.trace.data || {};\n event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_OP] = UI_LOAD_OP;\n event.contexts.trace.op = UI_LOAD_OP;\n\n const origin = isRecordedAppStartEndTimestampMsManual ? SPAN_ORIGIN_MANUAL_APP_START : SPAN_ORIGIN_AUTO_APP_START;\n event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] = origin;\n event.contexts.trace.origin = origin;\n\n const appStartTimestampSeconds = appStartTimestampMs / 1000;\n event.start_timestamp = appStartTimestampSeconds;\n\n event.spans = event.spans || [];\n /** event.spans reference */\n const children: SpanJSON[] = event.spans;\n\n const maybeTtidSpan = children.find(({ op }) => op === 'ui.load.initial_display');\n if (maybeTtidSpan) {\n maybeTtidSpan.start_timestamp = appStartTimestampSeconds;\n setSpanDurationAsMeasurementOnTransactionEvent(event, 'time_to_initial_display', maybeTtidSpan);\n }\n\n const maybeTtfdSpan = children.find(({ op }) => op === 'ui.load.full_display');\n if (maybeTtfdSpan) {\n maybeTtfdSpan.start_timestamp = appStartTimestampSeconds;\n setSpanDurationAsMeasurementOnTransactionEvent(event, 'time_to_full_display', maybeTtfdSpan);\n }\n\n const appStartEndTimestampSeconds = appStartEndTimestampMs / 1000;\n if (event.timestamp && event.timestamp < appStartEndTimestampSeconds) {\n logger.debug(\n '[AppStart] Transaction event timestamp is before app start end. Adjusting transaction event timestamp.',\n );\n event.timestamp = appStartEndTimestampSeconds;\n }\n\n const op = appStart.type === 'cold' ? APP_START_COLD_OP : APP_START_WARM_OP;\n const appStartSpanJSON: SpanJSON = createSpanJSON({\n op,\n description: appStart.type === 'cold' ? 'Cold App Start' : 'Warm App Start',\n start_timestamp: appStartTimestampSeconds,\n timestamp: appStartEndTimestampSeconds,\n trace_id: event.contexts.trace.trace_id,\n parent_span_id: event.contexts.trace.span_id,\n origin,\n });\n const jsExecutionSpanJSON = createJSExecutionStartSpan(appStartSpanJSON, rootComponentCreationTimestampMs);\n\n const appStartSpans = [\n appStartSpanJSON,\n ...(jsExecutionSpanJSON ? [jsExecutionSpanJSON] : []),\n ...convertNativeSpansToSpanJSON(appStartSpanJSON, appStart.spans),\n ];\n\n children.push(...appStartSpans);\n logger.debug('[AppStart] Added app start spans to transaction event.', JSON.stringify(appStartSpans, undefined, 2));\n\n const measurementKey = appStart.type === 'cold' ? APP_START_COLD_MEASUREMENT : APP_START_WARM_MEASUREMENT;\n const measurementValue = {\n value: appStartDurationMs,\n unit: 'millisecond',\n };\n event.measurements = event.measurements || {};\n event.measurements[measurementKey] = measurementValue;\n logger.debug(\n `[AppStart] Added app start measurement to transaction event.`,\n JSON.stringify(measurementValue, undefined, 2),\n );\n }\n\n return {\n name: INTEGRATION_NAME,\n setup,\n afterAllSetup,\n processEvent,\n captureStandaloneAppStart,\n setFirstStartedActiveRootSpanId,\n } as AppStartIntegration;\n};\n\nfunction setSpanDurationAsMeasurementOnTransactionEvent(event: TransactionEvent, label: string, span: SpanJSON): void {\n if (!span.timestamp || !span.start_timestamp) {\n logger.warn('Span is missing start or end timestamp. Cam not set measurement on transaction event.');\n return;\n }\n\n event.measurements = event.measurements || {};\n event.measurements[label] = {\n value: (span.timestamp - span.start_timestamp) * 1000,\n unit: 'millisecond',\n };\n}\n\n/**\n * Adds JS Execution before React Root. If `Sentry.wrap` is not used, create a span for the start of JS Bundle execution.\n */\nfunction createJSExecutionStartSpan(\n parentSpan: SpanJSON,\n rootComponentCreationTimestampMs: number | undefined,\n): SpanJSON | undefined {\n const bundleStartTimestampMs = getBundleStartTimestampMs();\n if (!bundleStartTimestampMs) {\n return undefined;\n }\n\n const bundleStartTimestampSeconds = bundleStartTimestampMs / 1000;\n if (bundleStartTimestampSeconds < parentSpan.start_timestamp) {\n logger.warn('Bundle start timestamp is before the app start span start timestamp. Skipping JS execution span.');\n return undefined;\n }\n\n if (!rootComponentCreationTimestampMs) {\n logger.warn('Missing the root component first constructor call timestamp.');\n return createChildSpanJSON(parentSpan, {\n description: 'JS Bundle Execution Start',\n start_timestamp: bundleStartTimestampSeconds,\n timestamp: bundleStartTimestampSeconds,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n });\n }\n\n return createChildSpanJSON(parentSpan, {\n description: 'JS Bundle Execution Before React Root',\n start_timestamp: bundleStartTimestampSeconds,\n timestamp: rootComponentCreationTimestampMs / 1000,\n origin: isRootComponentCreationTimestampMsManual ? SPAN_ORIGIN_MANUAL_APP_START : SPAN_ORIGIN_AUTO_APP_START,\n });\n}\n\n/**\n * Adds native spans to the app start span.\n */\nfunction convertNativeSpansToSpanJSON(parentSpan: SpanJSON, nativeSpans: NativeAppStartResponse['spans']): SpanJSON[] {\n return nativeSpans\n .filter(span => span.start_timestamp_ms / 1000 >= parentSpan.start_timestamp)\n .map(span => {\n if (span.description === 'UIKit init') {\n return setMainThreadInfo(createUIKitSpan(parentSpan, span));\n }\n\n return setMainThreadInfo(\n createChildSpanJSON(parentSpan, {\n description: span.description,\n start_timestamp: span.start_timestamp_ms / 1000,\n timestamp: span.end_timestamp_ms / 1000,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n }),\n );\n });\n}\n\n/**\n * UIKit init is measured by the native layers till the native SDK start\n * RN initializes the native SDK later, the end timestamp would be wrong\n */\nfunction createUIKitSpan(parentSpan: SpanJSON, nativeUIKitSpan: NativeAppStartResponse['spans'][number]): SpanJSON {\n const bundleStart = getBundleStartTimestampMs();\n\n // If UIKit init ends after the bundle start, the native SDK was auto-initialized\n // and so the end timestamp is incorrect.\n // The timestamps can't equal, as RN initializes after UIKit.\n if (bundleStart && bundleStart < nativeUIKitSpan.end_timestamp_ms) {\n return createChildSpanJSON(parentSpan, {\n description: 'UIKit Init to JS Exec Start',\n start_timestamp: nativeUIKitSpan.start_timestamp_ms / 1000,\n timestamp: bundleStart / 1000,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n });\n } else {\n return createChildSpanJSON(parentSpan, {\n description: 'UIKit Init',\n start_timestamp: nativeUIKitSpan.start_timestamp_ms / 1000,\n timestamp: nativeUIKitSpan.end_timestamp_ms / 1000,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"appStart.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/appStart.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity, max-lines */\nimport type { Client, Event, Integration, Span, SpanJSON, TransactionEvent } from '@sentry/core';\nimport {\n getCapturedScopesOnSpan,\n getClient,\n getCurrentScope,\n logger,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SentryNonRecordingSpan,\n startInactiveSpan,\n timestampInSeconds,\n} from '@sentry/core';\n\nimport { getAppRegistryIntegration } from '../../integrations/appRegistry';\nimport {\n APP_START_COLD as APP_START_COLD_MEASUREMENT,\n APP_START_WARM as APP_START_WARM_MEASUREMENT,\n} from '../../measurements';\nimport type { NativeAppStartResponse } from '../../NativeRNSentry';\nimport type { ReactNativeClientOptions } from '../../options';\nimport { convertSpanToTransaction, isRootSpan, setEndTimeValue } from '../../utils/span';\nimport { NATIVE } from '../../wrapper';\nimport {\n APP_START_COLD as APP_START_COLD_OP,\n APP_START_WARM as APP_START_WARM_OP,\n UI_LOAD as UI_LOAD_OP,\n} from '../ops';\nimport { SPAN_ORIGIN_AUTO_APP_START, SPAN_ORIGIN_MANUAL_APP_START } from '../origin';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../semanticAttributes';\nimport { setMainThreadInfo } from '../span';\nimport { createChildSpanJSON, createSpanJSON, getBundleStartTimestampMs } from '../utils';\n\nconst INTEGRATION_NAME = 'AppStart';\n\nexport type AppStartIntegration = Integration & {\n captureStandaloneAppStart: () => Promise<void>;\n};\n\n/**\n * We filter out app start more than 60s.\n * This could be due to many different reasons.\n * We've seen app starts with hours, days and even months.\n */\nconst MAX_APP_START_DURATION_MS = 60_000;\n\n/** We filter out App starts which timestamp is 60s and more before the transaction start */\nconst MAX_APP_START_AGE_MS = 60_000;\n\n/** App Start transaction name */\nconst APP_START_TX_NAME = 'App Start';\n\nlet recordedAppStartEndTimestampMs: number | undefined = undefined;\nlet isRecordedAppStartEndTimestampMsManual = false;\n\nlet rootComponentCreationTimestampMs: number | undefined = undefined;\nlet isRootComponentCreationTimestampMsManual = false;\n\n/**\n * Records the application start end.\n * Used automatically by `Sentry.wrap` and `Sentry.ReactNativeProfiler`.\n */\nexport function captureAppStart(): Promise<void> {\n return _captureAppStart({ isManual: true });\n}\n\n/**\n * For internal use only.\n *\n * @private\n */\nexport async function _captureAppStart({ isManual }: { isManual: boolean }): Promise<void> {\n const client = getClient();\n if (!client) {\n logger.warn('[AppStart] Could not capture App Start, missing client.');\n return;\n }\n\n isRecordedAppStartEndTimestampMsManual = isManual;\n _setAppStartEndTimestampMs(timestampInSeconds() * 1000);\n await client.getIntegrationByName<AppStartIntegration>(INTEGRATION_NAME)?.captureStandaloneAppStart();\n}\n\n/**\n * Sets the root component first constructor call timestamp.\n * Used automatically by `Sentry.wrap` and `Sentry.ReactNativeProfiler`.\n */\nexport function setRootComponentCreationTimestampMs(timestampMs: number): void {\n recordedAppStartEndTimestampMs &&\n logger.warn('Setting Root component creation timestamp after app start end is set.');\n rootComponentCreationTimestampMs && logger.warn('Overwriting already set root component creation timestamp.');\n rootComponentCreationTimestampMs = timestampMs;\n isRootComponentCreationTimestampMsManual = true;\n}\n\n/**\n * For internal use only.\n *\n * @private\n */\nexport function _setRootComponentCreationTimestampMs(timestampMs: number): void {\n setRootComponentCreationTimestampMs(timestampMs);\n isRootComponentCreationTimestampMsManual = false;\n}\n\n/**\n * For internal use only.\n *\n * @private\n */\nexport const _setAppStartEndTimestampMs = (timestampMs: number): void => {\n recordedAppStartEndTimestampMs && logger.warn('Overwriting already set app start.');\n recordedAppStartEndTimestampMs = timestampMs;\n};\n\n/**\n * For testing purposes only.\n *\n * @private\n */\nexport function _clearRootComponentCreationTimestampMs(): void {\n rootComponentCreationTimestampMs = undefined;\n}\n\n/**\n * Adds AppStart spans from the native layer to the transaction event.\n */\nexport const appStartIntegration = ({\n standalone = false,\n}: {\n /**\n * Should the integration send App Start as a standalone root span (transaction)?\n * If false, App Start will be added as a child span to the first transaction.\n *\n * @default false\n */\n standalone?: boolean;\n} = {}): AppStartIntegration => {\n let _client: Client | undefined = undefined;\n let isEnabled = true;\n let appStartDataFlushed = false;\n let afterAllSetupCalled = false;\n let firstStartedActiveRootSpanId: string | undefined = undefined;\n\n const setup = (client: Client): void => {\n _client = client;\n const { enableAppStartTracking } = client.getOptions() as ReactNativeClientOptions;\n\n if (!enableAppStartTracking) {\n isEnabled = false;\n logger.warn('[AppStart] App start tracking is disabled.');\n }\n\n client.on('spanStart', recordFirstStartedActiveRootSpanId);\n };\n\n const afterAllSetup = (client: Client): void => {\n if (afterAllSetupCalled) {\n return;\n }\n afterAllSetupCalled = true;\n\n // TODO: automatically set standalone based on the presence of the native layer navigation integration\n\n getAppRegistryIntegration(client)?.onRunApplication(() => {\n if (appStartDataFlushed) {\n logger.log('[AppStartIntegration] Resetting app start data flushed flag based on runApplication call.');\n appStartDataFlushed = false;\n firstStartedActiveRootSpanId = undefined;\n } else {\n logger.log(\n '[AppStartIntegration] Waiting for initial app start was flush, before updating based on runApplication call.',\n );\n }\n });\n };\n\n const processEvent = async (event: Event): Promise<Event> => {\n if (!isEnabled || standalone) {\n return event;\n }\n\n if (event.type !== 'transaction') {\n // App start data is only relevant for transactions\n return event;\n }\n\n await attachAppStartToTransactionEvent(event as TransactionEvent);\n\n return event;\n };\n\n const recordFirstStartedActiveRootSpanId = (rootSpan: Span): void => {\n if (firstStartedActiveRootSpanId) {\n return;\n }\n\n if (!isRootSpan(rootSpan)) {\n return;\n }\n\n setFirstStartedActiveRootSpanId(rootSpan.spanContext().spanId);\n };\n\n /**\n * For testing purposes only.\n * @private\n */\n const setFirstStartedActiveRootSpanId = (spanId: string | undefined): void => {\n firstStartedActiveRootSpanId = spanId;\n logger.debug('[AppStart] First started active root span id recorded.', firstStartedActiveRootSpanId);\n };\n\n async function captureStandaloneAppStart(): Promise<void> {\n if (!_client) {\n // If client is not set, SDK was not initialized, logger is thus disabled\n // eslint-disable-next-line no-console\n console.warn('[AppStart] Could not capture App Start, missing client, call `Sentry.init` first.');\n return;\n }\n\n if (!standalone) {\n logger.debug(\n '[AppStart] App start tracking is enabled. App start will be added to the first transaction as a child span.',\n );\n return;\n }\n\n logger.debug('[AppStart] App start tracking standalone root span (transaction).');\n\n const span = startInactiveSpan({\n forceTransaction: true,\n name: APP_START_TX_NAME,\n op: UI_LOAD_OP,\n });\n if (span instanceof SentryNonRecordingSpan) {\n // Tracing is disabled or the transaction was sampled\n return;\n }\n\n setEndTimeValue(span, timestampInSeconds());\n _client.emit('spanEnd', span);\n\n const event = convertSpanToTransaction(span);\n if (!event) {\n logger.warn('[AppStart] Failed to convert App Start span to transaction.');\n return;\n }\n\n await attachAppStartToTransactionEvent(event);\n if (!event.spans || event.spans.length === 0) {\n // No spans were added to the transaction, so we don't need to send it\n return;\n }\n\n const scope = getCapturedScopesOnSpan(span).scope || getCurrentScope();\n scope.captureEvent(event);\n }\n\n async function attachAppStartToTransactionEvent(event: TransactionEvent): Promise<void> {\n if (appStartDataFlushed) {\n // App start data is only relevant for the first transaction of the app run\n return;\n }\n\n if (!firstStartedActiveRootSpanId) {\n logger.warn('[AppStart] No first started active root span id recorded. Can not attach app start.');\n return;\n }\n\n if (!event.contexts?.trace) {\n logger.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.');\n return;\n }\n\n if (firstStartedActiveRootSpanId !== event.contexts.trace.span_id) {\n logger.warn(\n '[AppStart] First started active root span id does not match the transaction event span id. Can not attached app start.',\n );\n return;\n }\n\n const appStart = await NATIVE.fetchNativeAppStart();\n if (!appStart) {\n logger.warn('[AppStart] Failed to retrieve the app start metrics from the native layer.');\n return;\n }\n if (appStart.has_fetched) {\n logger.warn('[AppStart] Measured app start metrics were already reported from the native layer.');\n return;\n }\n\n const appStartTimestampMs = appStart.app_start_timestamp_ms;\n if (!appStartTimestampMs) {\n logger.warn('[AppStart] App start timestamp could not be loaded from the native layer.');\n return;\n }\n\n const appStartEndTimestampMs = recordedAppStartEndTimestampMs || getBundleStartTimestampMs();\n if (!appStartEndTimestampMs) {\n logger.warn(\n '[AppStart] Javascript failed to record app start end. `setAppStartEndTimestampMs` was not called nor could the bundle start be found.',\n );\n return;\n }\n\n const isAppStartWithinBounds =\n !!event.start_timestamp && appStartTimestampMs >= event.start_timestamp * 1_000 - MAX_APP_START_AGE_MS;\n if (!__DEV__ && !isAppStartWithinBounds) {\n logger.warn('[AppStart] App start timestamp is too far in the past to be used for app start span.');\n return;\n }\n\n const appStartDurationMs = appStartEndTimestampMs - appStartTimestampMs;\n if (!__DEV__ && appStartDurationMs >= MAX_APP_START_DURATION_MS) {\n // Dev builds can have long app start waiting over minute for the first bundle to be produced\n logger.warn('[AppStart] App start duration is over a minute long, not adding app start span.');\n return;\n }\n\n if (appStartDurationMs < 0) {\n // This can happen when MainActivity on Android is recreated,\n // and the app start end timestamp is not updated, for example\n // due to missing `Sentry.wrap(RootComponent)` call.\n logger.warn(\n '[AppStart] Last recorded app start end timestamp is before the app start timestamp.',\n 'This is usually caused by missing `Sentry.wrap(RootComponent)` call.',\n );\n return;\n }\n\n appStartDataFlushed = true;\n\n event.contexts.trace.data = event.contexts.trace.data || {};\n event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_OP] = UI_LOAD_OP;\n event.contexts.trace.op = UI_LOAD_OP;\n\n const origin = isRecordedAppStartEndTimestampMsManual ? SPAN_ORIGIN_MANUAL_APP_START : SPAN_ORIGIN_AUTO_APP_START;\n event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] = origin;\n event.contexts.trace.origin = origin;\n\n const appStartTimestampSeconds = appStartTimestampMs / 1000;\n event.start_timestamp = appStartTimestampSeconds;\n\n event.spans = event.spans || [];\n /** event.spans reference */\n const children: SpanJSON[] = event.spans;\n\n const maybeTtidSpan = children.find(({ op }) => op === 'ui.load.initial_display');\n if (maybeTtidSpan) {\n maybeTtidSpan.start_timestamp = appStartTimestampSeconds;\n setSpanDurationAsMeasurementOnTransactionEvent(event, 'time_to_initial_display', maybeTtidSpan);\n }\n\n const maybeTtfdSpan = children.find(({ op }) => op === 'ui.load.full_display');\n if (maybeTtfdSpan) {\n maybeTtfdSpan.start_timestamp = appStartTimestampSeconds;\n setSpanDurationAsMeasurementOnTransactionEvent(event, 'time_to_full_display', maybeTtfdSpan);\n }\n\n const appStartEndTimestampSeconds = appStartEndTimestampMs / 1000;\n if (event.timestamp && event.timestamp < appStartEndTimestampSeconds) {\n logger.debug(\n '[AppStart] Transaction event timestamp is before app start end. Adjusting transaction event timestamp.',\n );\n event.timestamp = appStartEndTimestampSeconds;\n }\n\n const op = appStart.type === 'cold' ? APP_START_COLD_OP : APP_START_WARM_OP;\n const appStartSpanJSON: SpanJSON = createSpanJSON({\n op,\n description: appStart.type === 'cold' ? 'Cold Start' : 'Warm Start',\n start_timestamp: appStartTimestampSeconds,\n timestamp: appStartEndTimestampSeconds,\n trace_id: event.contexts.trace.trace_id,\n parent_span_id: event.contexts.trace.span_id,\n origin,\n });\n const jsExecutionSpanJSON = createJSExecutionStartSpan(appStartSpanJSON, rootComponentCreationTimestampMs);\n\n const appStartSpans = [\n appStartSpanJSON,\n ...(jsExecutionSpanJSON ? [jsExecutionSpanJSON] : []),\n ...convertNativeSpansToSpanJSON(appStartSpanJSON, appStart.spans),\n ];\n\n children.push(...appStartSpans);\n logger.debug('[AppStart] Added app start spans to transaction event.', JSON.stringify(appStartSpans, undefined, 2));\n\n const measurementKey = appStart.type === 'cold' ? APP_START_COLD_MEASUREMENT : APP_START_WARM_MEASUREMENT;\n const measurementValue = {\n value: appStartDurationMs,\n unit: 'millisecond',\n };\n event.measurements = event.measurements || {};\n event.measurements[measurementKey] = measurementValue;\n logger.debug(\n `[AppStart] Added app start measurement to transaction event.`,\n JSON.stringify(measurementValue, undefined, 2),\n );\n }\n\n return {\n name: INTEGRATION_NAME,\n setup,\n afterAllSetup,\n processEvent,\n captureStandaloneAppStart,\n setFirstStartedActiveRootSpanId,\n } as AppStartIntegration;\n};\n\nfunction setSpanDurationAsMeasurementOnTransactionEvent(event: TransactionEvent, label: string, span: SpanJSON): void {\n if (!span.timestamp || !span.start_timestamp) {\n logger.warn('Span is missing start or end timestamp. Cam not set measurement on transaction event.');\n return;\n }\n\n event.measurements = event.measurements || {};\n event.measurements[label] = {\n value: (span.timestamp - span.start_timestamp) * 1000,\n unit: 'millisecond',\n };\n}\n\n/**\n * Adds JS Execution before React Root. If `Sentry.wrap` is not used, create a span for the start of JS Bundle execution.\n */\nfunction createJSExecutionStartSpan(\n parentSpan: SpanJSON,\n rootComponentCreationTimestampMs: number | undefined,\n): SpanJSON | undefined {\n const bundleStartTimestampMs = getBundleStartTimestampMs();\n if (!bundleStartTimestampMs) {\n return undefined;\n }\n\n const bundleStartTimestampSeconds = bundleStartTimestampMs / 1000;\n if (bundleStartTimestampSeconds < parentSpan.start_timestamp) {\n logger.warn('Bundle start timestamp is before the app start span start timestamp. Skipping JS execution span.');\n return undefined;\n }\n\n if (!rootComponentCreationTimestampMs) {\n logger.warn('Missing the root component first constructor call timestamp.');\n return createChildSpanJSON(parentSpan, {\n description: 'JS Bundle Execution Start',\n start_timestamp: bundleStartTimestampSeconds,\n timestamp: bundleStartTimestampSeconds,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n });\n }\n\n return createChildSpanJSON(parentSpan, {\n description: 'JS Bundle Execution Before React Root',\n start_timestamp: bundleStartTimestampSeconds,\n timestamp: rootComponentCreationTimestampMs / 1000,\n origin: isRootComponentCreationTimestampMsManual ? SPAN_ORIGIN_MANUAL_APP_START : SPAN_ORIGIN_AUTO_APP_START,\n });\n}\n\n/**\n * Adds native spans to the app start span.\n */\nfunction convertNativeSpansToSpanJSON(parentSpan: SpanJSON, nativeSpans: NativeAppStartResponse['spans']): SpanJSON[] {\n return nativeSpans\n .filter(span => span.start_timestamp_ms / 1000 >= parentSpan.start_timestamp)\n .map(span => {\n if (span.description === 'UIKit init') {\n return setMainThreadInfo(createUIKitSpan(parentSpan, span));\n }\n\n return setMainThreadInfo(\n createChildSpanJSON(parentSpan, {\n description: span.description,\n start_timestamp: span.start_timestamp_ms / 1000,\n timestamp: span.end_timestamp_ms / 1000,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n }),\n );\n });\n}\n\n/**\n * UIKit init is measured by the native layers till the native SDK start\n * RN initializes the native SDK later, the end timestamp would be wrong\n */\nfunction createUIKitSpan(parentSpan: SpanJSON, nativeUIKitSpan: NativeAppStartResponse['spans'][number]): SpanJSON {\n const bundleStart = getBundleStartTimestampMs();\n\n // If UIKit init ends after the bundle start, the native SDK was auto-initialized\n // and so the end timestamp is incorrect.\n // The timestamps can't equal, as RN initializes after UIKit.\n if (bundleStart && bundleStart < nativeUIKitSpan.end_timestamp_ms) {\n return createChildSpanJSON(parentSpan, {\n description: 'UIKit Init to JS Exec Start',\n start_timestamp: nativeUIKitSpan.start_timestamp_ms / 1000,\n timestamp: bundleStart / 1000,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n });\n } else {\n return createChildSpanJSON(parentSpan, {\n description: 'UIKit Init',\n start_timestamp: nativeUIKitSpan.start_timestamp_ms / 1000,\n timestamp: nativeUIKitSpan.end_timestamp_ms / 1000,\n origin: SPAN_ORIGIN_AUTO_APP_START,\n });\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeFrames.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/nativeFrames.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Event, Integration, Measurements, MeasurementUnit, Span } from '@sentry/core';\nimport { logger, timestampInSeconds } from '@sentry/core';\n\nimport type { NativeFramesResponse } from '../../NativeRNSentry';\nimport { AsyncExpiringMap } from '../../utils/AsyncExpiringMap';\nimport { isRootSpan } from '../../utils/span';\nimport { NATIVE } from '../../wrapper';\n\n/**\n * Timeout from the start of a span to fetching the associated native frames.\n */\nconst FETCH_FRAMES_TIMEOUT_MS = 2_000;\n\n/**\n * This is the time end frames data from the native layer will be\n * kept in memory and waiting for the event processing. This ensures that spans\n * which are never processed are not leaking memory.\n */\nconst END_FRAMES_TIMEOUT_MS = 2_000;\n\n/**\n * This is the time start frames data from the native layer will be\n * kept in memory and waiting for span end. This ensures that spans\n * which never end or are not processed are not leaking memory.\n */\nconst START_FRAMES_TIMEOUT_MS = 60_000;\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nconst MARGIN_OF_ERROR_SECONDS = 0.05;\n\nconst INTEGRATION_NAME = 'NativeFrames';\n\nexport interface FramesMeasurements extends Measurements {\n frames_total: { value: number; unit: MeasurementUnit };\n frames_slow: { value: number; unit: MeasurementUnit };\n frames_frozen: { value: number; unit: MeasurementUnit };\n}\n\ninterface NativeFramesResponseWithTimestamp {\n timestamp: number;\n nativeFrames: NativeFramesResponse;\n}\n\nexport const createNativeFramesIntegrations = (enable: boolean | undefined): Integration | undefined => {\n if (!enable && NATIVE.enableNative) {\n // On Android this will free up resource when JS reloaded (native modules stay) and thus JS side of the SDK reinitialized.\n NATIVE.disableNativeFramesTracking();\n return undefined;\n }\n\n return nativeFramesIntegration();\n};\n\n/**\n * Instrumentation to add native slow/frozen frames measurements onto transactions.\n */\nexport const nativeFramesIntegration = (): Integration => {\n /** The native frames at the finish time of the most recent span. */\n let _lastChildSpanEndFrames: NativeFramesResponseWithTimestamp | null = null;\n const _spanToNativeFramesAtStartMap: AsyncExpiringMap<string, NativeFramesResponse> = new AsyncExpiringMap({\n ttl: START_FRAMES_TIMEOUT_MS,\n });\n const _spanToNativeFramesAtEndMap: AsyncExpiringMap<string, NativeFramesResponseWithTimestamp | null> =\n new AsyncExpiringMap({ ttl: END_FRAMES_TIMEOUT_MS });\n\n /**\n * Hooks into the client start and end span events.\n */\n const setup = (client: Client): void => {\n if (!NATIVE.enableNative) {\n logger.warn(\n `[${INTEGRATION_NAME}] This is not available on the Web, Expo Go and other platforms without native modules.`,\n );\n return undefined;\n }\n\n NATIVE.enableNativeFramesTracking();\n client.on('spanStart', fetchStartFramesForSpan);\n client.on('spanEnd', fetchEndFramesForSpan);\n };\n\n const fetchStartFramesForSpan = (rootSpan: Span): void => {\n if (!isRootSpan(rootSpan)) {\n return;\n }\n\n const spanId = rootSpan.spanContext().spanId;\n logger.debug(`[${INTEGRATION_NAME}] Fetching frames for root span start (${spanId}).`);\n _spanToNativeFramesAtStartMap.set(\n spanId,\n new Promise<NativeFramesResponse | null>(resolve => {\n fetchNativeFrames()\n .then(frames => resolve(frames))\n .then(undefined, error => {\n logger.debug(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error);\n resolve(null);\n });\n }),\n );\n };\n\n const fetchEndFramesForSpan = (span: Span): void => {\n const timestamp = timestampInSeconds();\n const spanId = span.spanContext().spanId;\n\n if (isRootSpan(span)) {\n const hasStartFrames = _spanToNativeFramesAtStartMap.has(spanId);\n if (!hasStartFrames) {\n // We don't have start frames, won't be able to calculate the difference.\n return;\n }\n\n logger.debug(`[${INTEGRATION_NAME}] Fetch frames for root span end (${spanId}).`);\n _spanToNativeFramesAtEndMap.set(\n spanId,\n new Promise<NativeFramesResponseWithTimestamp | null>(resolve => {\n fetchNativeFrames()\n .then(frames => {\n resolve({\n timestamp,\n nativeFrames: frames,\n });\n })\n .then(undefined, error => {\n logger.debug(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error);\n resolve(null);\n });\n }),\n );\n return undefined;\n } else {\n logger.debug(`[${INTEGRATION_NAME}] Fetch frames for child span end (${spanId}).`);\n fetchNativeFrames()\n .then(frames => {\n _lastChildSpanEndFrames = {\n timestamp,\n nativeFrames: frames,\n };\n })\n .catch(error => logger.debug(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error));\n }\n };\n\n const processEvent = async (event: Event): Promise<Event> => {\n if (\n event.type !== 'transaction' ||\n !event.transaction ||\n !event.contexts ||\n !event.contexts.trace ||\n !event.timestamp ||\n !event.contexts.trace.span_id\n ) {\n return event;\n }\n\n const traceOp = event.contexts.trace.op;\n const spanId = event.contexts.trace.span_id;\n const startFrames = await _spanToNativeFramesAtStartMap.pop(spanId);\n if (!startFrames) {\n logger.warn(\n `[${INTEGRATION_NAME}] Start frames of transaction ${event.transaction} (eventId, ${event.event_id}) are missing, but the transaction already ended.`,\n );\n return event;\n }\n\n const endFrames = await _spanToNativeFramesAtEndMap.pop(spanId);\n let finalEndFrames: NativeFramesResponse | undefined;\n\n if (endFrames && isClose(endFrames.timestamp, event.timestamp)) {\n // Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)\n logger.debug(`[${INTEGRATION_NAME}] Using frames from root span end (spanId, ${spanId}).`);\n finalEndFrames = endFrames.nativeFrames;\n } else if (_lastChildSpanEndFrames && isClose(_lastChildSpanEndFrames.timestamp, event.timestamp)) {\n // Fallback to the last span finish if it is within the margin of error of the actual finish timestamp.\n // This should be the case for trimEnd.\n logger.debug(`[${INTEGRATION_NAME}] Using native frames from last child span end (spanId, ${spanId}).`);\n finalEndFrames = _lastChildSpanEndFrames.nativeFrames;\n } else {\n logger.warn(\n `[${INTEGRATION_NAME}] Frames were collected within larger than margin of error delay for spanId (${spanId}). Dropping the inaccurate values.`,\n );\n return event;\n }\n\n const measurements = {\n frames_total: {\n value: finalEndFrames.totalFrames - startFrames.totalFrames,\n unit: 'none',\n },\n frames_frozen: {\n value: finalEndFrames.frozenFrames - startFrames.frozenFrames,\n unit: 'none',\n },\n frames_slow: {\n value: finalEndFrames.slowFrames - startFrames.slowFrames,\n unit: 'none',\n },\n };\n\n if (\n measurements.frames_frozen.value <= 0 &&\n measurements.frames_slow.value <= 0 &&\n measurements.frames_total.value <= 0\n ) {\n logger.warn(\n `[${INTEGRATION_NAME}] Detected zero slow or frozen frames. Not adding measurements to spanId (${spanId}).`,\n );\n return event;\n }\n\n logger.log(\n `[${INTEGRATION_NAME}] Adding measurements to ${traceOp} transaction ${event.transaction}: ${JSON.stringify(\n measurements,\n undefined,\n 2,\n )}`,\n );\n event.measurements = {\n ...(event.measurements ?? {}),\n ...measurements,\n };\n return event;\n };\n\n return {\n name: INTEGRATION_NAME,\n setup,\n processEvent,\n };\n};\n\nfunction fetchNativeFrames(): Promise<NativeFramesResponse> {\n return new Promise<NativeFramesResponse>((resolve, reject) => {\n NATIVE.fetchNativeFrames()\n .then(value => {\n if (!value) {\n reject('Native frames response is null.');\n return;\n }\n resolve(value);\n })\n .then(undefined, error => {\n reject(error);\n });\n\n setTimeout(() => {\n reject('Fetching native frames took too long. Dropping frames.');\n }, FETCH_FRAMES_TIMEOUT_MS);\n });\n}\n\nfunction isClose(t1: number, t2: number): boolean {\n return Math.abs(t1 - t2) < MARGIN_OF_ERROR_SECONDS;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"nativeFrames.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/nativeFrames.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Event, Integration, Measurements, MeasurementUnit, Span } from '@sentry/core';\nimport { logger, timestampInSeconds } from '@sentry/core';\n\nimport type { NativeFramesResponse } from '../../NativeRNSentry';\nimport { AsyncExpiringMap } from '../../utils/AsyncExpiringMap';\nimport { isRootSpan } from '../../utils/span';\nimport { NATIVE } from '../../wrapper';\n\n/**\n * Timeout from the start of a span to fetching the associated native frames.\n */\nconst FETCH_FRAMES_TIMEOUT_MS = 2_000;\n\n/**\n * This is the time end frames data from the native layer will be\n * kept in memory and waiting for the event processing. This ensures that spans\n * which are never processed are not leaking memory.\n */\nconst END_FRAMES_TIMEOUT_MS = 2_000;\n\n/**\n * This is the time start frames data from the native layer will be\n * kept in memory and waiting for span end. This ensures that spans\n * which never end or are not processed are not leaking memory.\n */\nconst START_FRAMES_TIMEOUT_MS = 60_000;\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nconst MARGIN_OF_ERROR_SECONDS = 0.05;\n\nconst INTEGRATION_NAME = 'NativeFrames';\n\nexport interface FramesMeasurements extends Measurements {\n frames_total: { value: number; unit: MeasurementUnit };\n frames_slow: { value: number; unit: MeasurementUnit };\n frames_frozen: { value: number; unit: MeasurementUnit };\n}\n\ninterface NativeFramesResponseWithTimestamp {\n timestamp: number;\n nativeFrames: NativeFramesResponse;\n}\n\nexport const createNativeFramesIntegrations = (enable: boolean | undefined): Integration | undefined => {\n if (!enable && NATIVE.enableNative) {\n // On Android this will free up resource when JS reloaded (native modules stay) and thus JS side of the SDK reinitialized.\n NATIVE.disableNativeFramesTracking();\n return undefined;\n }\n\n return nativeFramesIntegration();\n};\n\n/**\n * Instrumentation to add native slow/frozen frames measurements onto transactions.\n */\nexport const nativeFramesIntegration = (): Integration => {\n /** The native frames at the finish time of the most recent span. */\n let _lastChildSpanEndFrames: NativeFramesResponseWithTimestamp | null = null;\n const _spanToNativeFramesAtStartMap: AsyncExpiringMap<string, NativeFramesResponse | null> = new AsyncExpiringMap({\n ttl: START_FRAMES_TIMEOUT_MS,\n });\n const _spanToNativeFramesAtEndMap: AsyncExpiringMap<string, NativeFramesResponseWithTimestamp | null> =\n new AsyncExpiringMap({ ttl: END_FRAMES_TIMEOUT_MS });\n\n /**\n * Hooks into the client start and end span events.\n */\n const setup = (client: Client): void => {\n if (!NATIVE.enableNative) {\n logger.warn(\n `[${INTEGRATION_NAME}] This is not available on the Web, Expo Go and other platforms without native modules.`,\n );\n return undefined;\n }\n\n NATIVE.enableNativeFramesTracking();\n client.on('spanStart', fetchStartFramesForSpan);\n client.on('spanEnd', fetchEndFramesForSpan);\n };\n\n const fetchStartFramesForSpan = (rootSpan: Span): void => {\n if (!isRootSpan(rootSpan)) {\n return;\n }\n\n const spanId = rootSpan.spanContext().spanId;\n logger.debug(`[${INTEGRATION_NAME}] Fetching frames for root span start (${spanId}).`);\n _spanToNativeFramesAtStartMap.set(\n spanId,\n new Promise<NativeFramesResponse | null>(resolve => {\n fetchNativeFrames()\n .then(frames => resolve(frames))\n .then(undefined, error => {\n logger.debug(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error);\n resolve(null);\n });\n }),\n );\n };\n\n const fetchEndFramesForSpan = (span: Span): void => {\n const timestamp = timestampInSeconds();\n const spanId = span.spanContext().spanId;\n\n if (isRootSpan(span)) {\n const hasStartFrames = _spanToNativeFramesAtStartMap.has(spanId);\n if (!hasStartFrames) {\n // We don't have start frames, won't be able to calculate the difference.\n return;\n }\n\n logger.debug(`[${INTEGRATION_NAME}] Fetch frames for root span end (${spanId}).`);\n _spanToNativeFramesAtEndMap.set(\n spanId,\n new Promise<NativeFramesResponseWithTimestamp | null>(resolve => {\n fetchNativeFrames()\n .then(frames => {\n resolve({\n timestamp,\n nativeFrames: frames,\n });\n })\n .then(undefined, error => {\n logger.debug(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error);\n resolve(null);\n });\n }),\n );\n return undefined;\n } else {\n logger.debug(`[${INTEGRATION_NAME}] Fetch frames for child span end (${spanId}).`);\n fetchNativeFrames()\n .then(frames => {\n _lastChildSpanEndFrames = {\n timestamp,\n nativeFrames: frames,\n };\n })\n .catch(error => logger.debug(`[${INTEGRATION_NAME}] Error while fetching native frames.`, error));\n }\n };\n\n const processEvent = async (event: Event): Promise<Event> => {\n if (\n event.type !== 'transaction' ||\n !event.transaction ||\n !event.contexts ||\n !event.contexts.trace ||\n !event.timestamp ||\n !event.contexts.trace.span_id\n ) {\n return event;\n }\n\n const traceOp = event.contexts.trace.op;\n const spanId = event.contexts.trace.span_id;\n const startFrames = await _spanToNativeFramesAtStartMap.pop(spanId);\n if (!startFrames) {\n logger.warn(\n `[${INTEGRATION_NAME}] Start frames of transaction ${event.transaction} (eventId, ${event.event_id}) are missing, but the transaction already ended.`,\n );\n return event;\n }\n\n const endFrames = await _spanToNativeFramesAtEndMap.pop(spanId);\n let finalEndFrames: NativeFramesResponse | undefined;\n\n if (endFrames && isClose(endFrames.timestamp, event.timestamp)) {\n // Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)\n logger.debug(`[${INTEGRATION_NAME}] Using frames from root span end (spanId, ${spanId}).`);\n finalEndFrames = endFrames.nativeFrames;\n } else if (_lastChildSpanEndFrames && isClose(_lastChildSpanEndFrames.timestamp, event.timestamp)) {\n // Fallback to the last span finish if it is within the margin of error of the actual finish timestamp.\n // This should be the case for trimEnd.\n logger.debug(`[${INTEGRATION_NAME}] Using native frames from last child span end (spanId, ${spanId}).`);\n finalEndFrames = _lastChildSpanEndFrames.nativeFrames;\n } else {\n logger.warn(\n `[${INTEGRATION_NAME}] Frames were collected within larger than margin of error delay for spanId (${spanId}). Dropping the inaccurate values.`,\n );\n return event;\n }\n\n const measurements = {\n frames_total: {\n value: finalEndFrames.totalFrames - startFrames.totalFrames,\n unit: 'none',\n },\n frames_frozen: {\n value: finalEndFrames.frozenFrames - startFrames.frozenFrames,\n unit: 'none',\n },\n frames_slow: {\n value: finalEndFrames.slowFrames - startFrames.slowFrames,\n unit: 'none',\n },\n };\n\n if (\n measurements.frames_frozen.value <= 0 &&\n measurements.frames_slow.value <= 0 &&\n measurements.frames_total.value <= 0\n ) {\n logger.warn(\n `[${INTEGRATION_NAME}] Detected zero slow or frozen frames. Not adding measurements to spanId (${spanId}).`,\n );\n return event;\n }\n\n logger.log(\n `[${INTEGRATION_NAME}] Adding measurements to ${traceOp} transaction ${event.transaction}: ${JSON.stringify(\n measurements,\n undefined,\n 2,\n )}`,\n );\n event.measurements = {\n ...(event.measurements ?? {}),\n ...measurements,\n };\n return event;\n };\n\n return {\n name: INTEGRATION_NAME,\n setup,\n processEvent,\n };\n};\n\nfunction fetchNativeFrames(): Promise<NativeFramesResponse> {\n return new Promise<NativeFramesResponse>((resolve, reject) => {\n NATIVE.fetchNativeFrames()\n .then(value => {\n if (!value) {\n reject('Native frames response is null.');\n return;\n }\n resolve(value);\n })\n .then(undefined, error => {\n reject(error);\n });\n\n setTimeout(() => {\n reject('Fetching native frames took too long. Dropping frames.');\n }, FETCH_FRAMES_TIMEOUT_MS);\n });\n}\n\nfunction isClose(t1: number, t2: number): boolean {\n return Math.abs(t1 - t2) < MARGIN_OF_ERROR_SECONDS;\n}\n"]}
|
|
@@ -26,6 +26,6 @@ export declare const stallTrackingIntegration: ({ minimumStallThresholdMs, }?: {
|
|
|
26
26
|
* How long in milliseconds an event loop iteration can be delayed for before being considered a "stall."
|
|
27
27
|
* @default 50
|
|
28
28
|
*/
|
|
29
|
-
minimumStallThresholdMs?: number;
|
|
29
|
+
minimumStallThresholdMs?: number | undefined;
|
|
30
30
|
}) => Integration;
|
|
31
31
|
//# sourceMappingURL=stalltracking.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stalltracking.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/stalltracking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,WAAW,EAAE,YAAY,EAAE,eAAe,EAAQ,MAAM,cAAc,CAAC;AAK7F,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAMvF,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,CAAC,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACxD,CAAC,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IAC7D,CAAC,kBAAkB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CAChE;AASD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;IAGnC;;;OAGG
|
|
1
|
+
{"version":3,"file":"stalltracking.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/stalltracking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,WAAW,EAAE,YAAY,EAAE,eAAe,EAAQ,MAAM,cAAc,CAAC;AAK7F,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAMvF,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,CAAC,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACxD,CAAC,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IAC7D,CAAC,kBAAkB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CAChE;AASD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;IAGnC;;;OAGG;;MAEI,WA0TR,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeToDisplayIntegration.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/timeToDisplayIntegration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,WAAW,EAAY,MAAM,cAAc,CAAC;AAYjE,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAKhD,eAAO,MAAM,wBAAwB,QAAO,
|
|
1
|
+
{"version":3,"file":"timeToDisplayIntegration.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/timeToDisplayIntegration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,WAAW,EAAY,MAAM,cAAc,CAAC;AAYjE,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAKhD,eAAO,MAAM,wBAAwB,QAAO,WAwE3C,CAAC"}
|
|
@@ -29,12 +29,12 @@ export const timeToDisplayIntegration = () => {
|
|
|
29
29
|
(_b = (_a = getReactNavigationIntegration(client)) === null || _a === void 0 ? void 0 : _a.options.enableTimeToInitialDisplayForPreloadedRoutes) !== null && _b !== void 0 ? _b : false;
|
|
30
30
|
},
|
|
31
31
|
processEvent: (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
-
var _a, _b, _c;
|
|
32
|
+
var _a, _b, _c, _d, _e;
|
|
33
33
|
if (event.type !== 'transaction') {
|
|
34
34
|
// TimeToDisplay data is only relevant for transactions
|
|
35
35
|
return event;
|
|
36
36
|
}
|
|
37
|
-
const rootSpanId = event.contexts.trace.span_id;
|
|
37
|
+
const rootSpanId = (_b = (_a = event.contexts) === null || _a === void 0 ? void 0 : _a.trace) === null || _b === void 0 ? void 0 : _b.span_id;
|
|
38
38
|
if (!rootSpanId) {
|
|
39
39
|
logger.warn(`[${INTEGRATION_NAME}] No root span id found in transaction.`);
|
|
40
40
|
return event;
|
|
@@ -54,16 +54,18 @@ export const timeToDisplayIntegration = () => {
|
|
|
54
54
|
enableTimeToInitialDisplayForPreloadedRoutes,
|
|
55
55
|
});
|
|
56
56
|
const ttfdSpan = yield addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan });
|
|
57
|
-
if (ttidSpan
|
|
57
|
+
if ((ttidSpan === null || ttidSpan === void 0 ? void 0 : ttidSpan.start_timestamp) && (ttidSpan === null || ttidSpan === void 0 ? void 0 : ttidSpan.timestamp)) {
|
|
58
58
|
event.measurements['time_to_initial_display'] = {
|
|
59
59
|
value: (ttidSpan.timestamp - ttidSpan.start_timestamp) * 1000,
|
|
60
60
|
unit: 'millisecond',
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
if (ttfdSpan
|
|
63
|
+
if ((ttfdSpan === null || ttfdSpan === void 0 ? void 0 : ttfdSpan.start_timestamp) && (ttfdSpan === null || ttfdSpan === void 0 ? void 0 : ttfdSpan.timestamp)) {
|
|
64
64
|
const durationMs = (ttfdSpan.timestamp - ttfdSpan.start_timestamp) * 1000;
|
|
65
65
|
if (isDeadlineExceeded(durationMs)) {
|
|
66
|
-
|
|
66
|
+
if (event.measurements['time_to_initial_display']) {
|
|
67
|
+
event.measurements['time_to_full_display'] = event.measurements['time_to_initial_display'];
|
|
68
|
+
}
|
|
67
69
|
}
|
|
68
70
|
else {
|
|
69
71
|
event.measurements['time_to_full_display'] = {
|
|
@@ -72,7 +74,7 @@ export const timeToDisplayIntegration = () => {
|
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
|
-
const newTransactionEndTimestampSeconds = Math.max((
|
|
77
|
+
const newTransactionEndTimestampSeconds = Math.max((_c = ttidSpan === null || ttidSpan === void 0 ? void 0 : ttidSpan.timestamp) !== null && _c !== void 0 ? _c : -1, (_d = ttfdSpan === null || ttfdSpan === void 0 ? void 0 : ttfdSpan.timestamp) !== null && _d !== void 0 ? _d : -1, (_e = event.timestamp) !== null && _e !== void 0 ? _e : -1);
|
|
76
78
|
if (newTransactionEndTimestampSeconds !== -1) {
|
|
77
79
|
event.timestamp = newTransactionEndTimestampSeconds;
|
|
78
80
|
}
|
|
@@ -84,6 +86,7 @@ function addTimeToInitialDisplay({ event, rootSpanId, transactionStartTimestampS
|
|
|
84
86
|
var _a;
|
|
85
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
88
|
const ttidEndTimestampSeconds = yield NATIVE.popTimeToDisplayFor(`ttid-${rootSpanId}`);
|
|
89
|
+
event.spans = event.spans || [];
|
|
87
90
|
let ttidSpan = (_a = event.spans) === null || _a === void 0 ? void 0 : _a.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);
|
|
88
91
|
if (ttidSpan && (ttidSpan.status === undefined || ttidSpan.status === 'ok') && !ttidEndTimestampSeconds) {
|
|
89
92
|
logger.debug(`[${INTEGRATION_NAME}] Ttid span already exists and is ok.`, ttidSpan);
|
|
@@ -98,7 +101,7 @@ function addTimeToInitialDisplay({ event, rootSpanId, transactionStartTimestampS
|
|
|
98
101
|
enableTimeToInitialDisplayForPreloadedRoutes,
|
|
99
102
|
});
|
|
100
103
|
}
|
|
101
|
-
if (ttidSpan
|
|
104
|
+
if ((ttidSpan === null || ttidSpan === void 0 ? void 0 : ttidSpan.status) && ttidSpan.status !== 'ok') {
|
|
102
105
|
ttidSpan.status = 'ok';
|
|
103
106
|
ttidSpan.timestamp = ttidEndTimestampSeconds;
|
|
104
107
|
logger.debug(`[${INTEGRATION_NAME}] Updated existing ttid span.`, ttidSpan);
|
|
@@ -160,14 +163,15 @@ function addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeco
|
|
|
160
163
|
if (!ttidSpan || !ttfdEndTimestampSeconds) {
|
|
161
164
|
return undefined;
|
|
162
165
|
}
|
|
166
|
+
event.spans = event.spans || [];
|
|
163
167
|
let ttfdSpan = (_a = event.spans) === null || _a === void 0 ? void 0 : _a.find(span => span.op === UI_LOAD_FULL_DISPLAY);
|
|
164
168
|
let ttfdAdjustedEndTimestampSeconds = ttfdEndTimestampSeconds;
|
|
165
|
-
const ttfdIsBeforeTtid =
|
|
166
|
-
if (ttfdIsBeforeTtid) {
|
|
169
|
+
const ttfdIsBeforeTtid = ttidSpan.timestamp && ttfdEndTimestampSeconds < ttidSpan.timestamp;
|
|
170
|
+
if (ttfdIsBeforeTtid && ttidSpan.timestamp) {
|
|
167
171
|
ttfdAdjustedEndTimestampSeconds = ttidSpan.timestamp;
|
|
168
172
|
}
|
|
169
173
|
const durationMs = (ttfdAdjustedEndTimestampSeconds - transactionStartTimestampSeconds) * 1000;
|
|
170
|
-
if (ttfdSpan
|
|
174
|
+
if ((ttfdSpan === null || ttfdSpan === void 0 ? void 0 : ttfdSpan.status) && ttfdSpan.status !== 'ok') {
|
|
171
175
|
ttfdSpan.status = 'ok';
|
|
172
176
|
ttfdSpan.timestamp = ttfdAdjustedEndTimestampSeconds;
|
|
173
177
|
logger.debug(`[${INTEGRATION_NAME}] Updated existing ttfd span.`, ttfdSpan);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeToDisplayIntegration.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/timeToDisplayIntegration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Event, Integration, SpanJSON } from '@sentry/core';\nimport { logger } from '@sentry/core';\n\nimport { NATIVE } from '../../wrapper';\nimport { UI_LOAD_FULL_DISPLAY, UI_LOAD_INITIAL_DISPLAY } from '../ops';\nimport { SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY, SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY } from '../origin';\nimport { getReactNavigationIntegration } from '../reactnavigation';\nimport { SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN } from '../semanticAttributes';\nimport { SPAN_THREAD_NAME, SPAN_THREAD_NAME_JAVASCRIPT } from '../span';\nimport { getTimeToInitialDisplayFallback } from '../timeToDisplayFallback';\nimport { createSpanJSON } from '../utils';\n\nexport const INTEGRATION_NAME = 'TimeToDisplay';\n\nconst TIME_TO_DISPLAY_TIMEOUT_MS = 30_000;\nconst isDeadlineExceeded = (durationMs: number): boolean => durationMs > TIME_TO_DISPLAY_TIMEOUT_MS;\n\nexport const timeToDisplayIntegration = (): Integration => {\n let enableTimeToInitialDisplayForPreloadedRoutes = false;\n\n return {\n name: INTEGRATION_NAME,\n afterAllSetup(client) {\n enableTimeToInitialDisplayForPreloadedRoutes =\n getReactNavigationIntegration(client)?.options.enableTimeToInitialDisplayForPreloadedRoutes ?? false;\n },\n processEvent: async event => {\n if (event.type !== 'transaction') {\n // TimeToDisplay data is only relevant for transactions\n return event;\n }\n\n const rootSpanId = event.contexts.trace.span_id;\n if (!rootSpanId) {\n logger.warn(`[${INTEGRATION_NAME}] No root span id found in transaction.`);\n return event;\n }\n\n const transactionStartTimestampSeconds = event.start_timestamp;\n if (!transactionStartTimestampSeconds) {\n // This should never happen\n logger.warn(`[${INTEGRATION_NAME}] No transaction start timestamp found in transaction.`);\n return event;\n }\n\n event.spans = event.spans || [];\n event.measurements = event.measurements || {};\n\n const ttidSpan = await addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n const ttfdSpan = await addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan });\n\n if (ttidSpan && ttidSpan.start_timestamp && ttidSpan.timestamp) {\n event.measurements['time_to_initial_display'] = {\n value: (ttidSpan.timestamp - ttidSpan.start_timestamp) * 1000,\n unit: 'millisecond',\n };\n }\n\n if (ttfdSpan && ttfdSpan.start_timestamp && ttfdSpan.timestamp) {\n const durationMs = (ttfdSpan.timestamp - ttfdSpan.start_timestamp) * 1000;\n if (isDeadlineExceeded(durationMs)) {\n event.measurements['time_to_full_display'] = event.measurements['time_to_initial_display'];\n } else {\n event.measurements['time_to_full_display'] = {\n value: durationMs,\n unit: 'millisecond',\n };\n }\n }\n\n const newTransactionEndTimestampSeconds = Math.max(\n ttidSpan?.timestamp ?? -1,\n ttfdSpan?.timestamp ?? -1,\n event.timestamp ?? -1,\n );\n if (newTransactionEndTimestampSeconds !== -1) {\n event.timestamp = newTransactionEndTimestampSeconds;\n }\n\n return event;\n },\n };\n};\n\nasync function addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-${rootSpanId}`);\n\n let ttidSpan: SpanJSON | undefined = event.spans?.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);\n\n if (ttidSpan && (ttidSpan.status === undefined || ttidSpan.status === 'ok') && !ttidEndTimestampSeconds) {\n logger.debug(`[${INTEGRATION_NAME}] Ttid span already exists and is ok.`, ttidSpan);\n return ttidSpan;\n }\n\n if (!ttidEndTimestampSeconds) {\n logger.debug(`[${INTEGRATION_NAME}] No manual ttid end timestamp found for span ${rootSpanId}.`);\n return addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n }\n\n if (ttidSpan && ttidSpan.status && ttidSpan.status !== 'ok') {\n ttidSpan.status = 'ok';\n ttidSpan.timestamp = ttidEndTimestampSeconds;\n logger.debug(`[${INTEGRATION_NAME}] Updated existing ttid span.`, ttidSpan);\n return ttidSpan;\n }\n\n ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n logger.debug(`[${INTEGRATION_NAME}] Added ttid span to transaction.`, ttidSpan);\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidNativeTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-navigation-${rootSpanId}`);\n const ttidFallbackTimestampSeconds = await getTimeToInitialDisplayFallback(rootSpanId);\n\n const hasBeenSeen = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN];\n if (hasBeenSeen && !enableTimeToInitialDisplayForPreloadedRoutes) {\n logger.debug(\n `[${INTEGRATION_NAME}] Route has been seen and time to initial display is disabled for preloaded routes.`,\n );\n return undefined;\n }\n\n const ttidTimestampSeconds = ttidNativeTimestampSeconds ?? ttidFallbackTimestampSeconds;\n if (!ttidTimestampSeconds) {\n logger.debug(`[${INTEGRATION_NAME}] No automatic ttid end timestamp found for span ${rootSpanId}.`);\n return undefined;\n }\n\n const viewNames = event.contexts?.app?.view_names;\n const screenName = Array.isArray(viewNames) ? viewNames[0] : viewNames;\n\n const ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: screenName ? `${screenName} initial display` : 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidTimestampSeconds,\n origin: SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n event.spans = event.spans ?? [];\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addTimeToFullDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n ttidSpan,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n ttidSpan: SpanJSON | undefined;\n}): Promise<SpanJSON | undefined> {\n const ttfdEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttfd-${rootSpanId}`);\n\n if (!ttidSpan || !ttfdEndTimestampSeconds) {\n return undefined;\n }\n\n let ttfdSpan = event.spans?.find(span => span.op === UI_LOAD_FULL_DISPLAY);\n\n let ttfdAdjustedEndTimestampSeconds = ttfdEndTimestampSeconds;\n const ttfdIsBeforeTtid = ttidSpan?.timestamp && ttfdEndTimestampSeconds < ttidSpan.timestamp;\n if (ttfdIsBeforeTtid) {\n ttfdAdjustedEndTimestampSeconds = ttidSpan.timestamp;\n }\n\n const durationMs = (ttfdAdjustedEndTimestampSeconds - transactionStartTimestampSeconds) * 1000;\n\n if (ttfdSpan && ttfdSpan.status && ttfdSpan.status !== 'ok') {\n ttfdSpan.status = 'ok';\n ttfdSpan.timestamp = ttfdAdjustedEndTimestampSeconds;\n logger.debug(`[${INTEGRATION_NAME}] Updated existing ttfd span.`, ttfdSpan);\n return ttfdSpan;\n }\n\n ttfdSpan = createSpanJSON({\n status: isDeadlineExceeded(durationMs) ? 'deadline_exceeded' : 'ok',\n op: UI_LOAD_FULL_DISPLAY,\n description: 'Time To Full Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttfdAdjustedEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n logger.debug(`[${INTEGRATION_NAME}] Added ttfd span to transaction.`, ttfdSpan);\n event.spans.push(ttfdSpan);\n return ttfdSpan;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"timeToDisplayIntegration.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/timeToDisplayIntegration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Event, Integration, SpanJSON } from '@sentry/core';\nimport { logger } from '@sentry/core';\n\nimport { NATIVE } from '../../wrapper';\nimport { UI_LOAD_FULL_DISPLAY, UI_LOAD_INITIAL_DISPLAY } from '../ops';\nimport { SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY, SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY } from '../origin';\nimport { getReactNavigationIntegration } from '../reactnavigation';\nimport { SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN } from '../semanticAttributes';\nimport { SPAN_THREAD_NAME, SPAN_THREAD_NAME_JAVASCRIPT } from '../span';\nimport { getTimeToInitialDisplayFallback } from '../timeToDisplayFallback';\nimport { createSpanJSON } from '../utils';\n\nexport const INTEGRATION_NAME = 'TimeToDisplay';\n\nconst TIME_TO_DISPLAY_TIMEOUT_MS = 30_000;\nconst isDeadlineExceeded = (durationMs: number): boolean => durationMs > TIME_TO_DISPLAY_TIMEOUT_MS;\n\nexport const timeToDisplayIntegration = (): Integration => {\n let enableTimeToInitialDisplayForPreloadedRoutes = false;\n\n return {\n name: INTEGRATION_NAME,\n afterAllSetup(client) {\n enableTimeToInitialDisplayForPreloadedRoutes =\n getReactNavigationIntegration(client)?.options.enableTimeToInitialDisplayForPreloadedRoutes ?? false;\n },\n processEvent: async event => {\n if (event.type !== 'transaction') {\n // TimeToDisplay data is only relevant for transactions\n return event;\n }\n\n const rootSpanId = event.contexts?.trace?.span_id;\n if (!rootSpanId) {\n logger.warn(`[${INTEGRATION_NAME}] No root span id found in transaction.`);\n return event;\n }\n\n const transactionStartTimestampSeconds = event.start_timestamp;\n if (!transactionStartTimestampSeconds) {\n // This should never happen\n logger.warn(`[${INTEGRATION_NAME}] No transaction start timestamp found in transaction.`);\n return event;\n }\n\n event.spans = event.spans || [];\n event.measurements = event.measurements || {};\n\n const ttidSpan = await addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n const ttfdSpan = await addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan });\n\n if (ttidSpan?.start_timestamp && ttidSpan?.timestamp) {\n event.measurements['time_to_initial_display'] = {\n value: (ttidSpan.timestamp - ttidSpan.start_timestamp) * 1000,\n unit: 'millisecond',\n };\n }\n\n if (ttfdSpan?.start_timestamp && ttfdSpan?.timestamp) {\n const durationMs = (ttfdSpan.timestamp - ttfdSpan.start_timestamp) * 1000;\n if (isDeadlineExceeded(durationMs)) {\n if (event.measurements['time_to_initial_display']) {\n event.measurements['time_to_full_display'] = event.measurements['time_to_initial_display'];\n }\n } else {\n event.measurements['time_to_full_display'] = {\n value: durationMs,\n unit: 'millisecond',\n };\n }\n }\n\n const newTransactionEndTimestampSeconds = Math.max(\n ttidSpan?.timestamp ?? -1,\n ttfdSpan?.timestamp ?? -1,\n event.timestamp ?? -1,\n );\n if (newTransactionEndTimestampSeconds !== -1) {\n event.timestamp = newTransactionEndTimestampSeconds;\n }\n\n return event;\n },\n };\n};\n\nasync function addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-${rootSpanId}`);\n\n event.spans = event.spans || [];\n\n let ttidSpan: SpanJSON | undefined = event.spans?.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);\n\n if (ttidSpan && (ttidSpan.status === undefined || ttidSpan.status === 'ok') && !ttidEndTimestampSeconds) {\n logger.debug(`[${INTEGRATION_NAME}] Ttid span already exists and is ok.`, ttidSpan);\n return ttidSpan;\n }\n\n if (!ttidEndTimestampSeconds) {\n logger.debug(`[${INTEGRATION_NAME}] No manual ttid end timestamp found for span ${rootSpanId}.`);\n return addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n }\n\n if (ttidSpan?.status && ttidSpan.status !== 'ok') {\n ttidSpan.status = 'ok';\n ttidSpan.timestamp = ttidEndTimestampSeconds;\n logger.debug(`[${INTEGRATION_NAME}] Updated existing ttid span.`, ttidSpan);\n return ttidSpan;\n }\n\n ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n logger.debug(`[${INTEGRATION_NAME}] Added ttid span to transaction.`, ttidSpan);\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidNativeTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-navigation-${rootSpanId}`);\n const ttidFallbackTimestampSeconds = await getTimeToInitialDisplayFallback(rootSpanId);\n\n const hasBeenSeen = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN];\n if (hasBeenSeen && !enableTimeToInitialDisplayForPreloadedRoutes) {\n logger.debug(\n `[${INTEGRATION_NAME}] Route has been seen and time to initial display is disabled for preloaded routes.`,\n );\n return undefined;\n }\n\n const ttidTimestampSeconds = ttidNativeTimestampSeconds ?? ttidFallbackTimestampSeconds;\n if (!ttidTimestampSeconds) {\n logger.debug(`[${INTEGRATION_NAME}] No automatic ttid end timestamp found for span ${rootSpanId}.`);\n return undefined;\n }\n\n const viewNames = event.contexts?.app?.view_names;\n const screenName = Array.isArray(viewNames) ? viewNames[0] : viewNames;\n\n const ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: screenName ? `${screenName} initial display` : 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidTimestampSeconds,\n origin: SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n event.spans = event.spans ?? [];\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addTimeToFullDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n ttidSpan,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n ttidSpan: SpanJSON | undefined;\n}): Promise<SpanJSON | undefined> {\n const ttfdEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttfd-${rootSpanId}`);\n\n if (!ttidSpan || !ttfdEndTimestampSeconds) {\n return undefined;\n }\n\n event.spans = event.spans || [];\n\n let ttfdSpan = event.spans?.find(span => span.op === UI_LOAD_FULL_DISPLAY);\n\n let ttfdAdjustedEndTimestampSeconds = ttfdEndTimestampSeconds;\n const ttfdIsBeforeTtid = ttidSpan.timestamp && ttfdEndTimestampSeconds < ttidSpan.timestamp;\n if (ttfdIsBeforeTtid && ttidSpan.timestamp) {\n ttfdAdjustedEndTimestampSeconds = ttidSpan.timestamp;\n }\n\n const durationMs = (ttfdAdjustedEndTimestampSeconds - transactionStartTimestampSeconds) * 1000;\n\n if (ttfdSpan?.status && ttfdSpan.status !== 'ok') {\n ttfdSpan.status = 'ok';\n ttfdSpan.timestamp = ttfdAdjustedEndTimestampSeconds;\n logger.debug(`[${INTEGRATION_NAME}] Updated existing ttfd span.`, ttfdSpan);\n return ttfdSpan;\n }\n\n ttfdSpan = createSpanJSON({\n status: isDeadlineExceeded(durationMs) ? 'deadline_exceeded' : 'ok',\n op: UI_LOAD_FULL_DISPLAY,\n description: 'Time To Full Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttfdAdjustedEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n logger.debug(`[${INTEGRATION_NAME}] Added ttfd span to transaction.`, ttfdSpan);\n event.spans.push(ttfdSpan);\n return ttfdSpan;\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import type { Client, Span } from '@sentry/core';
|
|
|
4
4
|
*/
|
|
5
5
|
export declare function onThisSpanEnd(client: Client, span: Span, callback: (span: Span) => void): void;
|
|
6
6
|
export declare const adjustTransactionDuration: (client: Client, span: Span, maxDurationMs: number) => void;
|
|
7
|
-
export declare const ignoreEmptyBackNavigation: (client: Client | undefined, span: Span) => void;
|
|
7
|
+
export declare const ignoreEmptyBackNavigation: (client: Client | undefined, span: Span | undefined) => void;
|
|
8
8
|
/**
|
|
9
9
|
* Idle Transaction callback to only sample transactions with child spans.
|
|
10
10
|
* To avoid side effects of other callbacks this should be hooked as the last callback.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onSpanEndUtils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAOjD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAO9F;AAED,eAAO,MAAM,yBAAyB,WAAY,MAAM,QAAQ,IAAI,iBAAiB,MAAM,KAAG,IAyB7F,CAAC;AAEF,eAAO,MAAM,yBAAyB,WAAY,MAAM,GAAG,SAAS,QAAQ,IAAI,KAAG,
|
|
1
|
+
{"version":3,"file":"onSpanEndUtils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAOjD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAO9F;AAED,eAAO,MAAM,yBAAyB,WAAY,MAAM,QAAQ,IAAI,iBAAiB,MAAM,KAAG,IAyB7F,CAAC;AAEF,eAAO,MAAM,yBAAyB,WAAY,MAAM,GAAG,SAAS,QAAQ,IAAI,GAAG,SAAS,KAAG,IA0C9F,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,QAAQ,IAAI,KAAG,IAmBnE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,WAAY,MAAM,QAAQ,IAAI,KAAG,IAgB/D,CAAC"}
|
|
@@ -102,9 +102,10 @@ export const cancelInBackground = (client, span) => {
|
|
|
102
102
|
});
|
|
103
103
|
subscription &&
|
|
104
104
|
client.on('spanEnd', (endedSpan) => {
|
|
105
|
+
var _a;
|
|
105
106
|
if (endedSpan === span) {
|
|
106
107
|
logger.debug(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);
|
|
107
|
-
subscription
|
|
108
|
+
(_a = subscription === null || subscription === void 0 ? void 0 : subscription.remove) === null || _a === void 0 ? void 0 : _a.call(subscription);
|
|
108
109
|
}
|
|
109
110
|
});
|
|
110
111
|
};
|