@sentry/react-native 8.2.0 → 8.4.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.
Files changed (122) hide show
  1. package/README.md +0 -1
  2. package/RNSentry.podspec +1 -1
  3. package/android/AGENTS.md +51 -0
  4. package/android/libs/replay-stubs.jar +0 -0
  5. package/android/src/main/java/io/sentry/react/RNSentryLogger.java +96 -0
  6. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +13 -3
  7. package/android/src/main/java/io/sentry/react/RNSentryStart.java +21 -9
  8. package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
  9. package/dist/js/NativeLogListener.d.ts +16 -0
  10. package/dist/js/NativeLogListener.d.ts.map +1 -0
  11. package/dist/js/NativeLogListener.js +72 -0
  12. package/dist/js/NativeLogListener.js.map +1 -0
  13. package/dist/js/client.d.ts +1 -0
  14. package/dist/js/client.d.ts.map +1 -1
  15. package/dist/js/client.js +14 -3
  16. package/dist/js/client.js.map +1 -1
  17. package/dist/js/index.d.ts +4 -4
  18. package/dist/js/index.d.ts.map +1 -1
  19. package/dist/js/index.js +2 -2
  20. package/dist/js/index.js.map +1 -1
  21. package/dist/js/integrations/default.d.ts.map +1 -1
  22. package/dist/js/integrations/default.js +2 -1
  23. package/dist/js/integrations/default.js.map +1 -1
  24. package/dist/js/integrations/expoconstants.d.ts +24 -0
  25. package/dist/js/integrations/expoconstants.d.ts.map +1 -0
  26. package/dist/js/integrations/expoconstants.js +77 -0
  27. package/dist/js/integrations/expoconstants.js.map +1 -0
  28. package/dist/js/integrations/expocontext.d.ts.map +1 -1
  29. package/dist/js/integrations/expocontext.js +35 -1
  30. package/dist/js/integrations/expocontext.js.map +1 -1
  31. package/dist/js/integrations/exports.d.ts +1 -0
  32. package/dist/js/integrations/exports.d.ts.map +1 -1
  33. package/dist/js/integrations/exports.js +1 -0
  34. package/dist/js/integrations/exports.js.map +1 -1
  35. package/dist/js/options.d.ts +26 -0
  36. package/dist/js/options.d.ts.map +1 -1
  37. package/dist/js/options.js.map +1 -1
  38. package/dist/js/sdk.d.ts.map +1 -1
  39. package/dist/js/sdk.js +3 -2
  40. package/dist/js/sdk.js.map +1 -1
  41. package/dist/js/tools/easBuildHooks.d.ts +48 -0
  42. package/dist/js/tools/easBuildHooks.d.ts.map +1 -0
  43. package/dist/js/tools/easBuildHooks.js +228 -0
  44. package/dist/js/tools/easBuildHooks.js.map +1 -0
  45. package/dist/js/tools/metroconfig.d.ts +4 -0
  46. package/dist/js/tools/metroconfig.d.ts.map +1 -1
  47. package/dist/js/tools/metroconfig.js +46 -1
  48. package/dist/js/tools/metroconfig.js.map +1 -1
  49. package/dist/js/tracing/expoAsset.d.ts +42 -0
  50. package/dist/js/tracing/expoAsset.d.ts.map +1 -0
  51. package/dist/js/tracing/expoAsset.js +60 -0
  52. package/dist/js/tracing/expoAsset.js.map +1 -0
  53. package/dist/js/tracing/expoImage.d.ts +61 -0
  54. package/dist/js/tracing/expoImage.d.ts.map +1 -0
  55. package/dist/js/tracing/expoImage.js +101 -0
  56. package/dist/js/tracing/expoImage.js.map +1 -0
  57. package/dist/js/tracing/index.d.ts +4 -0
  58. package/dist/js/tracing/index.d.ts.map +1 -1
  59. package/dist/js/tracing/index.js +2 -0
  60. package/dist/js/tracing/index.js.map +1 -1
  61. package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
  62. package/dist/js/tracing/integrations/appStart.js +4 -1
  63. package/dist/js/tracing/integrations/appStart.js.map +1 -1
  64. package/dist/js/tracing/onSpanEndUtils.d.ts +7 -0
  65. package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -1
  66. package/dist/js/tracing/onSpanEndUtils.js +45 -6
  67. package/dist/js/tracing/onSpanEndUtils.js.map +1 -1
  68. package/dist/js/tracing/origin.d.ts +2 -0
  69. package/dist/js/tracing/origin.d.ts.map +1 -1
  70. package/dist/js/tracing/origin.js +2 -0
  71. package/dist/js/tracing/origin.js.map +1 -1
  72. package/dist/js/tracing/reactnavigation.d.ts +15 -0
  73. package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
  74. package/dist/js/tracing/reactnavigation.js +50 -17
  75. package/dist/js/tracing/reactnavigation.js.map +1 -1
  76. package/dist/js/tracing/span.d.ts +6 -6
  77. package/dist/js/tracing/span.d.ts.map +1 -1
  78. package/dist/js/tracing/span.js +3 -3
  79. package/dist/js/tracing/span.js.map +1 -1
  80. package/dist/js/tracing/utils.d.ts +27 -1
  81. package/dist/js/tracing/utils.d.ts.map +1 -1
  82. package/dist/js/tracing/utils.js +66 -1
  83. package/dist/js/tracing/utils.js.map +1 -1
  84. package/dist/js/utils/expoglobalobject.d.ts +47 -7
  85. package/dist/js/utils/expoglobalobject.d.ts.map +1 -1
  86. package/dist/js/utils/expoglobalobject.js.map +1 -1
  87. package/dist/js/version.d.ts +1 -1
  88. package/dist/js/version.js +6 -3
  89. package/dist/js/version.js.map +1 -1
  90. package/dist/js/wrapper.d.ts.map +1 -1
  91. package/dist/js/wrapper.js +1 -1
  92. package/dist/js/wrapper.js.map +1 -1
  93. package/ios/AGENTS.md +60 -0
  94. package/ios/RNSentry.mm +4 -1
  95. package/ios/RNSentryEvents.h +1 -0
  96. package/ios/RNSentryEvents.m +1 -0
  97. package/ios/RNSentryNativeLogsForwarder.h +20 -0
  98. package/ios/RNSentryNativeLogsForwarder.m +145 -0
  99. package/ios/RNSentryVersion.m +1 -1
  100. package/package.json +14 -11
  101. package/plugin/build/utils.d.ts +1 -0
  102. package/plugin/build/utils.js +19 -1
  103. package/plugin/build/withSentry.d.ts +1 -0
  104. package/plugin/build/withSentry.js +28 -0
  105. package/scripts/eas-build-hook.js +234 -0
  106. package/scripts/sentry-xcode.sh +7 -0
  107. package/ts3.8/dist/js/NativeLogListener.d.ts +16 -0
  108. package/ts3.8/dist/js/client.d.ts +1 -0
  109. package/ts3.8/dist/js/index.d.ts +4 -4
  110. package/ts3.8/dist/js/integrations/expoconstants.d.ts +24 -0
  111. package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
  112. package/ts3.8/dist/js/options.d.ts +26 -0
  113. package/ts3.8/dist/js/tracing/expoAsset.d.ts +42 -0
  114. package/ts3.8/dist/js/tracing/expoImage.d.ts +61 -0
  115. package/ts3.8/dist/js/tracing/index.d.ts +4 -0
  116. package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +7 -0
  117. package/ts3.8/dist/js/tracing/origin.d.ts +2 -0
  118. package/ts3.8/dist/js/tracing/reactnavigation.d.ts +15 -0
  119. package/ts3.8/dist/js/tracing/span.d.ts +6 -6
  120. package/ts3.8/dist/js/tracing/utils.d.ts +27 -1
  121. package/ts3.8/dist/js/utils/expoglobalobject.d.ts +47 -7
  122. package/ts3.8/dist/js/version.d.ts +1 -1
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Internal interface for expo-image's ImageSource.
3
+ * We define this to avoid a hard dependency on expo-image.
4
+ */
5
+ interface ExpoImageSource {
6
+ uri?: string;
7
+ headers?: Record<string, string>;
8
+ width?: number | null;
9
+ height?: number | null;
10
+ cacheKey?: string;
11
+ }
12
+ /**
13
+ * Internal interface for expo-image's ImageLoadOptions.
14
+ * We define this to avoid a hard dependency on expo-image.
15
+ */
16
+ interface ExpoImageLoadOptions {
17
+ maxWidth?: number;
18
+ maxHeight?: number;
19
+ onError?(error: Error, retry: () => void): void;
20
+ }
21
+ /**
22
+ * Internal interface for expo-image's ImageRef.
23
+ * We define this to avoid a hard dependency on expo-image.
24
+ */
25
+ interface ExpoImageRef {
26
+ readonly width: number;
27
+ readonly height: number;
28
+ readonly scale: number;
29
+ readonly mediaType: string | null;
30
+ readonly isAnimated?: boolean;
31
+ }
32
+ /**
33
+ * Represents the expo-image `Image` class with its static methods.
34
+ * We only describe the methods that we instrument.
35
+ */
36
+ export interface ExpoImage {
37
+ prefetch(urls: string | string[], cachePolicyOrOptions?: any): Promise<boolean>;
38
+ loadAsync(source: ExpoImageSource | string | number, options?: ExpoImageLoadOptions): Promise<ExpoImageRef>;
39
+ clearMemoryCache?(): Promise<boolean>;
40
+ clearDiskCache?(): Promise<boolean>;
41
+ }
42
+ /**
43
+ * Wraps expo-image's `Image` class to add automated performance monitoring.
44
+ *
45
+ * This function instruments `Image.prefetch` and `Image.loadAsync` static methods
46
+ * to create performance spans that measure how long image prefetching and loading take.
47
+ *
48
+ * @param imageClass - The `Image` class from `expo-image`
49
+ * @returns The same class with instrumented static methods
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * import { Image } from 'expo-image';
54
+ * import * as Sentry from '@sentry/react-native';
55
+ *
56
+ * Sentry.wrapExpoImage(Image);
57
+ * ```
58
+ */
59
+ export declare function wrapExpoImage<T extends ExpoImage>(imageClass: T): T;
60
+ export {};
61
+ //# sourceMappingURL=expoImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expoImage.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/expoImage.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,UAAU,eAAe;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,UAAU,YAAY;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IAExB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5G,gBAAgB,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,cAAc,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,SAAS,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAenE"}
@@ -0,0 +1,101 @@
1
+ import { SPAN_STATUS_ERROR, SPAN_STATUS_OK, startInactiveSpan } from '@sentry/core';
2
+ import { SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE } from './origin';
3
+ import { describeUrl, sanitizeUrl, traceAsyncOperation } from './utils';
4
+ /**
5
+ * Wraps expo-image's `Image` class to add automated performance monitoring.
6
+ *
7
+ * This function instruments `Image.prefetch` and `Image.loadAsync` static methods
8
+ * to create performance spans that measure how long image prefetching and loading take.
9
+ *
10
+ * @param imageClass - The `Image` class from `expo-image`
11
+ * @returns The same class with instrumented static methods
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { Image } from 'expo-image';
16
+ * import * as Sentry from '@sentry/react-native';
17
+ *
18
+ * Sentry.wrapExpoImage(Image);
19
+ * ```
20
+ */
21
+ export function wrapExpoImage(imageClass) {
22
+ if (!imageClass) {
23
+ return imageClass;
24
+ }
25
+ if (imageClass.__sentryWrapped) {
26
+ return imageClass;
27
+ }
28
+ wrapPrefetch(imageClass);
29
+ wrapLoadAsync(imageClass);
30
+ imageClass.__sentryWrapped = true;
31
+ return imageClass;
32
+ }
33
+ function wrapPrefetch(imageClass) {
34
+ if (!imageClass.prefetch) {
35
+ return;
36
+ }
37
+ const originalPrefetch = imageClass.prefetch.bind(imageClass);
38
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
+ imageClass.prefetch = ((urls, cachePolicyOrOptions) => {
40
+ const urlList = Array.isArray(urls) ? urls : [urls];
41
+ const urlCount = urlList.length;
42
+ const firstUrl = urlList[0] || 'unknown';
43
+ const description = urlCount === 1 ? describeUrl(firstUrl) : `${urlCount} images`;
44
+ const span = startInactiveSpan({
45
+ op: 'resource.image.prefetch',
46
+ name: `Image prefetch ${description}`,
47
+ attributes: Object.assign({ 'sentry.origin': SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE, 'image.url_count': urlCount }, (urlCount === 1 ? { 'image.url': sanitizeUrl(firstUrl) } : undefined)),
48
+ });
49
+ try {
50
+ return originalPrefetch(urls, cachePolicyOrOptions)
51
+ .then(result => {
52
+ if (result) {
53
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_OK });
54
+ }
55
+ else {
56
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_ERROR, message: 'prefetch_failed' });
57
+ }
58
+ span === null || span === void 0 ? void 0 : span.end();
59
+ return result;
60
+ })
61
+ .catch((error) => {
62
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });
63
+ span === null || span === void 0 ? void 0 : span.end();
64
+ throw error;
65
+ });
66
+ }
67
+ catch (error) {
68
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });
69
+ span === null || span === void 0 ? void 0 : span.end();
70
+ throw error;
71
+ }
72
+ });
73
+ }
74
+ function wrapLoadAsync(imageClass) {
75
+ if (!imageClass.loadAsync) {
76
+ return;
77
+ }
78
+ const originalLoadAsync = imageClass.loadAsync.bind(imageClass);
79
+ imageClass.loadAsync = ((source, options) => {
80
+ const description = describeSource(source);
81
+ const imageUrl = typeof source === 'string' ? source : typeof source === 'object' && source.uri ? source.uri : undefined;
82
+ return traceAsyncOperation({
83
+ op: 'resource.image.load',
84
+ name: `Image load ${description}`,
85
+ attributes: Object.assign({ 'sentry.origin': SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE }, (imageUrl ? { 'image.url': sanitizeUrl(imageUrl) } : undefined)),
86
+ }, () => originalLoadAsync(source, options));
87
+ });
88
+ }
89
+ function describeSource(source) {
90
+ if (typeof source === 'number') {
91
+ return `asset #${source}`;
92
+ }
93
+ if (typeof source === 'string') {
94
+ return describeUrl(source);
95
+ }
96
+ if (source.uri) {
97
+ return describeUrl(source.uri);
98
+ }
99
+ return 'unknown source';
100
+ }
101
+ //# sourceMappingURL=expoImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expoImage.js","sourceRoot":"","sources":["../../../src/js/tracing/expoImage.ts"],"names":[],"mappings":"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","sourcesContent":["import { SPAN_STATUS_ERROR, SPAN_STATUS_OK, startInactiveSpan } from '@sentry/core';\nimport { SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE } from './origin';\nimport { describeUrl, sanitizeUrl, traceAsyncOperation } from './utils';\n\n/**\n * Internal interface for expo-image's ImageSource.\n * We define this to avoid a hard dependency on expo-image.\n */\ninterface ExpoImageSource {\n uri?: string;\n headers?: Record<string, string>;\n width?: number | null;\n height?: number | null;\n cacheKey?: string;\n}\n\n/**\n * Internal interface for expo-image's ImageLoadOptions.\n * We define this to avoid a hard dependency on expo-image.\n */\ninterface ExpoImageLoadOptions {\n maxWidth?: number;\n maxHeight?: number;\n onError?(error: Error, retry: () => void): void;\n}\n\n/**\n * Internal interface for expo-image's ImageRef.\n * We define this to avoid a hard dependency on expo-image.\n */\ninterface ExpoImageRef {\n readonly width: number;\n readonly height: number;\n readonly scale: number;\n readonly mediaType: string | null;\n readonly isAnimated?: boolean;\n}\n\n/**\n * Represents the expo-image `Image` class with its static methods.\n * We only describe the methods that we instrument.\n */\nexport interface ExpoImage {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prefetch(urls: string | string[], cachePolicyOrOptions?: any): Promise<boolean>;\n loadAsync(source: ExpoImageSource | string | number, options?: ExpoImageLoadOptions): Promise<ExpoImageRef>;\n clearMemoryCache?(): Promise<boolean>;\n clearDiskCache?(): Promise<boolean>;\n}\n\n/**\n * Wraps expo-image's `Image` class to add automated performance monitoring.\n *\n * This function instruments `Image.prefetch` and `Image.loadAsync` static methods\n * to create performance spans that measure how long image prefetching and loading take.\n *\n * @param imageClass - The `Image` class from `expo-image`\n * @returns The same class with instrumented static methods\n *\n * @example\n * ```typescript\n * import { Image } from 'expo-image';\n * import * as Sentry from '@sentry/react-native';\n *\n * Sentry.wrapExpoImage(Image);\n * ```\n */\nexport function wrapExpoImage<T extends ExpoImage>(imageClass: T): T {\n if (!imageClass) {\n return imageClass;\n }\n\n if ((imageClass as T & { __sentryWrapped?: boolean }).__sentryWrapped) {\n return imageClass;\n }\n\n wrapPrefetch(imageClass);\n wrapLoadAsync(imageClass);\n\n (imageClass as T & { __sentryWrapped?: boolean }).__sentryWrapped = true;\n\n return imageClass;\n}\n\nfunction wrapPrefetch<T extends ExpoImage>(imageClass: T): void {\n if (!imageClass.prefetch) {\n return;\n }\n\n const originalPrefetch = imageClass.prefetch.bind(imageClass);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n imageClass.prefetch = ((urls: string | string[], cachePolicyOrOptions?: any): Promise<boolean> => {\n const urlList = Array.isArray(urls) ? urls : [urls];\n const urlCount = urlList.length;\n const firstUrl = urlList[0] || 'unknown';\n const description = urlCount === 1 ? describeUrl(firstUrl) : `${urlCount} images`;\n\n const span = startInactiveSpan({\n op: 'resource.image.prefetch',\n name: `Image prefetch ${description}`,\n attributes: {\n 'sentry.origin': SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE,\n 'image.url_count': urlCount,\n ...(urlCount === 1 ? { 'image.url': sanitizeUrl(firstUrl) } : undefined),\n },\n });\n\n try {\n return originalPrefetch(urls, cachePolicyOrOptions)\n .then(result => {\n if (result) {\n span?.setStatus({ code: SPAN_STATUS_OK });\n } else {\n span?.setStatus({ code: SPAN_STATUS_ERROR, message: 'prefetch_failed' });\n }\n span?.end();\n return result;\n })\n .catch((error: unknown) => {\n span?.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });\n span?.end();\n throw error;\n });\n } catch (error) {\n span?.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });\n span?.end();\n throw error;\n }\n }) as T['prefetch'];\n}\n\nfunction wrapLoadAsync<T extends ExpoImage>(imageClass: T): void {\n if (!imageClass.loadAsync) {\n return;\n }\n\n const originalLoadAsync = imageClass.loadAsync.bind(imageClass);\n\n imageClass.loadAsync = ((\n source: ExpoImageSource | string | number,\n options?: ExpoImageLoadOptions,\n ): Promise<ExpoImageRef> => {\n const description = describeSource(source);\n\n const imageUrl =\n typeof source === 'string' ? source : typeof source === 'object' && source.uri ? source.uri : undefined;\n\n return traceAsyncOperation(\n {\n op: 'resource.image.load',\n name: `Image load ${description}`,\n attributes: {\n 'sentry.origin': SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE,\n ...(imageUrl ? { 'image.url': sanitizeUrl(imageUrl) } : undefined),\n },\n },\n () => originalLoadAsync(source, options),\n );\n }) as T['loadAsync'];\n}\n\nfunction describeSource(source: ExpoImageSource | string | number): string {\n if (typeof source === 'number') {\n return `asset #${source}`;\n }\n if (typeof source === 'string') {\n return describeUrl(source);\n }\n if (source.uri) {\n return describeUrl(source.uri);\n }\n return 'unknown source';\n}\n"]}
@@ -4,6 +4,10 @@ export { reactNavigationIntegration } from './reactnavigation';
4
4
  export { reactNativeNavigationIntegration } from './reactnativenavigation';
5
5
  export { wrapExpoRouter } from './expoRouter';
6
6
  export type { ExpoRouter } from './expoRouter';
7
+ export { wrapExpoImage } from './expoImage';
8
+ export type { ExpoImage } from './expoImage';
9
+ export { wrapExpoAsset } from './expoAsset';
10
+ export type { ExpoAsset } from './expoAsset';
7
11
  export { startIdleNavigationSpan, startIdleSpan, getDefaultIdleNavigationSpanOptions } from './span';
8
12
  export type { ReactNavigationCurrentRoute, ReactNavigationRoute } from './types';
9
13
  export { ReactNativeProfiler } from './reactnativeprofiler';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,gBAAgB,IAAI,qCAAqC,EACzD,uCAAuC,EACvC,gCAAgC,GACjC,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,mCAAmC,EAAE,MAAM,QAAQ,CAAC;AAErG,YAAY,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,cAAc,OAAO,CAAC;AAEtB,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,gBAAgB,IAAI,qCAAqC,EACzD,uCAAuC,EACvC,gCAAgC,GACjC,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,mCAAmC,EAAE,MAAM,QAAQ,CAAC;AAErG,YAAY,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,cAAc,OAAO,CAAC;AAEtB,cAAc,iBAAiB,CAAC"}
@@ -2,6 +2,8 @@ export { reactNativeTracingIntegration, INTEGRATION_NAME as REACT_NATIVE_TRACING
2
2
  export { reactNavigationIntegration } from './reactnavigation';
3
3
  export { reactNativeNavigationIntegration } from './reactnativenavigation';
4
4
  export { wrapExpoRouter } from './expoRouter';
5
+ export { wrapExpoImage } from './expoImage';
6
+ export { wrapExpoAsset } from './expoAsset';
5
7
  export { startIdleNavigationSpan, startIdleSpan, getDefaultIdleNavigationSpanOptions } from './span';
6
8
  export { ReactNativeProfiler } from './reactnativeprofiler';
7
9
  export { sentryTraceGesture } from './gesturetracing';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,gBAAgB,IAAI,qCAAqC,EACzD,uCAAuC,EACvC,gCAAgC,GACjC,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,mCAAmC,EAAE,MAAM,QAAQ,CAAC;AAIrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,cAAc,OAAO,CAAC;AAEtB,cAAc,iBAAiB,CAAC","sourcesContent":["export {\n reactNativeTracingIntegration,\n INTEGRATION_NAME as REACT_NATIVE_TRACING_INTEGRATION_NAME,\n getCurrentReactNativeTracingIntegration,\n getReactNativeTracingIntegration,\n} from './reactnativetracing';\nexport type { ReactNativeTracingIntegration } from './reactnativetracing';\n\nexport { reactNavigationIntegration } from './reactnavigation';\nexport { reactNativeNavigationIntegration } from './reactnativenavigation';\n\nexport { wrapExpoRouter } from './expoRouter';\nexport type { ExpoRouter } from './expoRouter';\n\nexport { startIdleNavigationSpan, startIdleSpan, getDefaultIdleNavigationSpanOptions } from './span';\n\nexport type { ReactNavigationCurrentRoute, ReactNavigationRoute } from './types';\n\nexport { ReactNativeProfiler } from './reactnativeprofiler';\n\nexport { sentryTraceGesture } from './gesturetracing';\n\nexport * from './ops';\n\nexport * from './timetodisplay';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,gBAAgB,IAAI,qCAAqC,EACzD,uCAAuC,EACvC,gCAAgC,GACjC,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,mCAAmC,EAAE,MAAM,QAAQ,CAAC;AAIrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,cAAc,OAAO,CAAC;AAEtB,cAAc,iBAAiB,CAAC","sourcesContent":["export {\n reactNativeTracingIntegration,\n INTEGRATION_NAME as REACT_NATIVE_TRACING_INTEGRATION_NAME,\n getCurrentReactNativeTracingIntegration,\n getReactNativeTracingIntegration,\n} from './reactnativetracing';\nexport type { ReactNativeTracingIntegration } from './reactnativetracing';\n\nexport { reactNavigationIntegration } from './reactnavigation';\nexport { reactNativeNavigationIntegration } from './reactnativenavigation';\n\nexport { wrapExpoRouter } from './expoRouter';\nexport type { ExpoRouter } from './expoRouter';\n\nexport { wrapExpoImage } from './expoImage';\nexport type { ExpoImage } from './expoImage';\n\nexport { wrapExpoAsset } from './expoAsset';\nexport type { ExpoAsset } from './expoAsset';\n\nexport { startIdleNavigationSpan, startIdleSpan, getDefaultIdleNavigationSpanOptions } from './span';\n\nexport type { ReactNavigationCurrentRoute, ReactNavigationRoute } from './types';\n\nexport { ReactNativeProfiler } from './reactnativeprofiler';\n\nexport { sentryTraceGesture } from './gesturetracing';\n\nexport * from './ops';\n\nexport * from './timetodisplay';\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;AAgBjG,OAAO,KAAK,EAA0B,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAgBzF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,yBAAyB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,CAAC;AAeF,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACxC;AAQD;;;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,CA2BzF;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAK7E;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG9E;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,SAAU,eAAe,KAAG,IAG3D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,IAAI,CAE7D;AAyBD;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAG9B;;;;;OAKG;;MAEI,mBA0SR,CAAC"}
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;AAiBjG,OAAO,KAAK,EAA0B,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAgBzF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,yBAAyB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,CAAC;AAeF,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACxC;AAQD;;;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,CA2BzF;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAK7E;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG9E;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,SAAU,eAAe,KAAG,IAG3D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,IAAI,CAE7D;AAyBD;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAG9B;;;;;OAKG;;MAEI,mBA8SR,CAAC"}
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { debug, getCapturedScopesOnSpan, getClient, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SentryNonRecordingSpan, startInactiveSpan, timestampInSeconds, } from '@sentry/core';
10
+ import { debug, getCapturedScopesOnSpan, getClient, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SentryNonRecordingSpan, spanIsSampled, startInactiveSpan, timestampInSeconds, } from '@sentry/core';
11
11
  import { getAppRegistryIntegration } from '../../integrations/appRegistry';
12
12
  import { APP_START_COLD as APP_START_COLD_MEASUREMENT, APP_START_WARM as APP_START_WARM_MEASUREMENT, } from '../../measurements';
13
13
  import { convertSpanToTransaction, isRootSpan, setEndTimeValue } from '../../utils/span';
@@ -182,6 +182,9 @@ export const appStartIntegration = ({ standalone = false, } = {}) => {
182
182
  if (!isRootSpan(rootSpan)) {
183
183
  return;
184
184
  }
185
+ if (!spanIsSampled(rootSpan)) {
186
+ return;
187
+ }
185
188
  setFirstStartedActiveRootSpanId(rootSpan.spanContext().spanId);
186
189
  };
187
190
  /**
@@ -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 debug,\n getCapturedScopesOnSpan,\n getClient,\n getCurrentScope,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SentryNonRecordingSpan,\n startInactiveSpan,\n timestampInSeconds,\n} from '@sentry/core';\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, NativeFramesResponse } 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\ninterface AppStartEndData {\n timestampMs: number;\n endFrames: NativeFramesResponse | null;\n}\n\nlet appStartEndData: AppStartEndData | 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 debug.warn('[AppStart] Could not capture App Start, missing client.');\n return;\n }\n\n isRecordedAppStartEndTimestampMsManual = isManual;\n\n const timestampMs = timestampInSeconds() * 1000;\n let endFrames: NativeFramesResponse | null = null;\n\n if (NATIVE.enableNative) {\n try {\n endFrames = await NATIVE.fetchNativeFrames();\n debug.log('[AppStart] Captured end frames for app start.', endFrames);\n } catch (error) {\n debug.log('[AppStart] Failed to capture end frames for app start.', error);\n }\n }\n\n _setAppStartEndData({\n timestampMs,\n endFrames,\n });\n\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 appStartEndData?.timestampMs && debug.warn('Setting Root component creation timestamp after app start end is set.');\n rootComponentCreationTimestampMs && debug.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 _setAppStartEndData = (data: AppStartEndData): void => {\n appStartEndData && debug.warn('Overwriting already set app start end data.');\n appStartEndData = data;\n};\n\n/**\n * For testing purposes only.\n *\n * @private\n */\nexport function _clearRootComponentCreationTimestampMs(): void {\n rootComponentCreationTimestampMs = undefined;\n}\n\n/**\n * Attaches frame data to a span's data object.\n */\nfunction attachFrameDataToSpan(span: SpanJSON, frames: NativeFramesResponse): void {\n if (frames.totalFrames <= 0 && frames.slowFrames <= 0 && frames.totalFrames <= 0) {\n debug.warn(`[AppStart] Detected zero slow or frozen frames. Not adding measurements to spanId (${span.span_id}).`);\n return;\n }\n span.data = span.data || {};\n span.data['frames.total'] = frames.totalFrames;\n span.data['frames.slow'] = frames.slowFrames;\n span.data['frames.frozen'] = frames.frozenFrames;\n\n debug.log('[AppStart] Attached frame data to span.', {\n spanId: span.span_id,\n frameData: {\n total: frames.totalFrames,\n slow: frames.slowFrames,\n frozen: frames.frozenFrames,\n },\n });\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 debug.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 debug.log('[AppStartIntegration] Resetting app start data flushed flag based on runApplication call.');\n appStartDataFlushed = false;\n firstStartedActiveRootSpanId = undefined;\n } else {\n debug.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 debug.log('[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 debug.log(\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 debug.log('[AppStart] App start tracking standalone root span (transaction).');\n\n if (!appStartEndData?.endFrames && NATIVE.enableNative) {\n try {\n const endFrames = await NATIVE.fetchNativeFrames();\n debug.log('[AppStart] Captured end frames for standalone app start.', endFrames);\n\n const currentTimestamp = appStartEndData?.timestampMs || timestampInSeconds() * 1000;\n _setAppStartEndData({\n timestampMs: currentTimestamp,\n endFrames,\n });\n } catch (error) {\n debug.log('[AppStart] Failed to capture frames for standalone app start.', error);\n }\n }\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 debug.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 (!event.contexts?.trace) {\n debug.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.');\n return;\n }\n\n // When standalone is true, we create our own transaction and don't need to verify\n // it matches the first navigation transaction. When standalone is false, we need to\n // ensure we're attaching app start to the first transaction (not a later one).\n if (!standalone) {\n if (!firstStartedActiveRootSpanId) {\n debug.warn('[AppStart] No first started active root span id recorded. Can not attach app start.');\n return;\n }\n\n if (firstStartedActiveRootSpanId !== event.contexts.trace.span_id) {\n debug.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\n const appStart = await NATIVE.fetchNativeAppStart();\n if (!appStart) {\n debug.warn('[AppStart] Failed to retrieve the app start metrics from the native layer.');\n return;\n }\n if (appStart.has_fetched) {\n debug.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 debug.warn('[AppStart] App start timestamp could not be loaded from the native layer.');\n return;\n }\n\n const appStartEndTimestampMs = appStartEndData?.timestampMs || getBundleStartTimestampMs();\n if (!appStartEndTimestampMs) {\n debug.warn(\n '[AppStart] Javascript failed to record app start end. `_setAppStartEndData` 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 debug.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 debug.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 debug.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 debug.log(\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\n if (appStartEndData?.endFrames) {\n attachFrameDataToSpan(appStartSpanJSON, appStartEndData.endFrames);\n }\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 debug.log('[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 debug.log(\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 debug.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 debug.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 debug.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 debug,\n getCapturedScopesOnSpan,\n getClient,\n getCurrentScope,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SentryNonRecordingSpan,\n spanIsSampled,\n startInactiveSpan,\n timestampInSeconds,\n} from '@sentry/core';\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, NativeFramesResponse } 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\ninterface AppStartEndData {\n timestampMs: number;\n endFrames: NativeFramesResponse | null;\n}\n\nlet appStartEndData: AppStartEndData | 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 debug.warn('[AppStart] Could not capture App Start, missing client.');\n return;\n }\n\n isRecordedAppStartEndTimestampMsManual = isManual;\n\n const timestampMs = timestampInSeconds() * 1000;\n let endFrames: NativeFramesResponse | null = null;\n\n if (NATIVE.enableNative) {\n try {\n endFrames = await NATIVE.fetchNativeFrames();\n debug.log('[AppStart] Captured end frames for app start.', endFrames);\n } catch (error) {\n debug.log('[AppStart] Failed to capture end frames for app start.', error);\n }\n }\n\n _setAppStartEndData({\n timestampMs,\n endFrames,\n });\n\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 appStartEndData?.timestampMs && debug.warn('Setting Root component creation timestamp after app start end is set.');\n rootComponentCreationTimestampMs && debug.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 _setAppStartEndData = (data: AppStartEndData): void => {\n appStartEndData && debug.warn('Overwriting already set app start end data.');\n appStartEndData = data;\n};\n\n/**\n * For testing purposes only.\n *\n * @private\n */\nexport function _clearRootComponentCreationTimestampMs(): void {\n rootComponentCreationTimestampMs = undefined;\n}\n\n/**\n * Attaches frame data to a span's data object.\n */\nfunction attachFrameDataToSpan(span: SpanJSON, frames: NativeFramesResponse): void {\n if (frames.totalFrames <= 0 && frames.slowFrames <= 0 && frames.totalFrames <= 0) {\n debug.warn(`[AppStart] Detected zero slow or frozen frames. Not adding measurements to spanId (${span.span_id}).`);\n return;\n }\n span.data = span.data || {};\n span.data['frames.total'] = frames.totalFrames;\n span.data['frames.slow'] = frames.slowFrames;\n span.data['frames.frozen'] = frames.frozenFrames;\n\n debug.log('[AppStart] Attached frame data to span.', {\n spanId: span.span_id,\n frameData: {\n total: frames.totalFrames,\n slow: frames.slowFrames,\n frozen: frames.frozenFrames,\n },\n });\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 debug.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 debug.log('[AppStartIntegration] Resetting app start data flushed flag based on runApplication call.');\n appStartDataFlushed = false;\n firstStartedActiveRootSpanId = undefined;\n } else {\n debug.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 if (!spanIsSampled(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 debug.log('[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 debug.log(\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 debug.log('[AppStart] App start tracking standalone root span (transaction).');\n\n if (!appStartEndData?.endFrames && NATIVE.enableNative) {\n try {\n const endFrames = await NATIVE.fetchNativeFrames();\n debug.log('[AppStart] Captured end frames for standalone app start.', endFrames);\n\n const currentTimestamp = appStartEndData?.timestampMs || timestampInSeconds() * 1000;\n _setAppStartEndData({\n timestampMs: currentTimestamp,\n endFrames,\n });\n } catch (error) {\n debug.log('[AppStart] Failed to capture frames for standalone app start.', error);\n }\n }\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 debug.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 (!event.contexts?.trace) {\n debug.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.');\n return;\n }\n\n // When standalone is true, we create our own transaction and don't need to verify\n // it matches the first navigation transaction. When standalone is false, we need to\n // ensure we're attaching app start to the first transaction (not a later one).\n if (!standalone) {\n if (!firstStartedActiveRootSpanId) {\n debug.warn('[AppStart] No first started active root span id recorded. Can not attach app start.');\n return;\n }\n\n if (firstStartedActiveRootSpanId !== event.contexts.trace.span_id) {\n debug.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\n const appStart = await NATIVE.fetchNativeAppStart();\n if (!appStart) {\n debug.warn('[AppStart] Failed to retrieve the app start metrics from the native layer.');\n return;\n }\n if (appStart.has_fetched) {\n debug.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 debug.warn('[AppStart] App start timestamp could not be loaded from the native layer.');\n return;\n }\n\n const appStartEndTimestampMs = appStartEndData?.timestampMs || getBundleStartTimestampMs();\n if (!appStartEndTimestampMs) {\n debug.warn(\n '[AppStart] Javascript failed to record app start end. `_setAppStartEndData` 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 debug.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 debug.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 debug.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 debug.log(\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\n if (appStartEndData?.endFrames) {\n attachFrameDataToSpan(appStartSpanJSON, appStartEndData.endFrames);\n }\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 debug.log('[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 debug.log(\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 debug.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 debug.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 debug.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"]}
@@ -21,6 +21,13 @@ export declare const ignoreEmptyRouteChangeTransactions: (client: Client | undef
21
21
  export declare const onlySampleIfChildSpans: (client: Client, span: Span) => void;
22
22
  /**
23
23
  * Hooks on AppState change to cancel the span if the app goes background.
24
+ *
25
+ * On iOS the JS thread can be suspended between the `inactive` and
26
+ * `background` transitions, which means the `background` event may never
27
+ * reach JS in time. To handle this we schedule a deferred cancellation when
28
+ * the app becomes `inactive`. If the app returns to `active` before the
29
+ * timeout fires, the cancellation is cleared. If it transitions to
30
+ * `background` first, we cancel immediately and clear the timeout.
24
31
  */
25
32
  export declare const cancelInBackground: (client: Client, span: Span) => void;
26
33
  //# sourceMappingURL=onSpanEndUtils.d.ts.map
@@ -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;AAMjD;;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;AAwDF,eAAO,MAAM,yBAAyB,WAAY,MAAM,GAAG,SAAS,QAAQ,IAAI,GAAG,SAAS,KAAG,IAa9F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,WACrC,MAAM,GAAG,SAAS,QACpB,IAAI,GAAG,SAAS,6BACK,MAAM,sBACb,MAAM,OAAO,KAChC,IAoBF,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"}
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;AAYjD;;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,IA0B7F,CAAC;AAwDF,eAAO,MAAM,yBAAyB,WAAY,MAAM,GAAG,SAAS,QAAQ,IAAI,GAAG,SAAS,KAAG,IAa9F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,WACrC,MAAM,GAAG,SAAS,QACpB,IAAI,GAAG,SAAS,6BACK,MAAM,sBACb,MAAM,OAAO,KAChC,IAoBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,QAAQ,IAAI,KAAG,IAmBnE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,WAAY,MAAM,QAAQ,IAAI,KAAG,IA2C/D,CAAC"}
@@ -1,6 +1,11 @@
1
1
  import { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';
2
- import { AppState } from 'react-native';
2
+ import { AppState, Platform } from 'react-native';
3
3
  import { isRootSpan, isSentrySpan } from '../utils/span';
4
+ /**
5
+ * The time to wait after the app enters the `inactive` state on iOS before
6
+ * cancelling the span.
7
+ */
8
+ const IOS_INACTIVE_CANCEL_DELAY_MS = 5000;
4
9
  /**
5
10
  * Hooks on span end event to execute a callback when the span ends.
6
11
  */
@@ -26,8 +31,8 @@ export const adjustTransactionDuration = (client, span, maxDurationMs) => {
26
31
  if (!endTimestamp || !startTimestamp) {
27
32
  return;
28
33
  }
29
- const diff = endTimestamp - startTimestamp;
30
- const isOutdatedTransaction = endTimestamp && (diff > maxDurationMs || diff < 0);
34
+ const diff = endTimestamp - startTimestamp; // a diff in *seconds*
35
+ const isOutdatedTransaction = diff > maxDurationMs / 1000 || diff < 0;
31
36
  if (isOutdatedTransaction) {
32
37
  span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });
33
38
  // TODO: check where was used, might be possible to delete
@@ -131,13 +136,43 @@ export const onlySampleIfChildSpans = (client, span) => {
131
136
  };
132
137
  /**
133
138
  * Hooks on AppState change to cancel the span if the app goes background.
139
+ *
140
+ * On iOS the JS thread can be suspended between the `inactive` and
141
+ * `background` transitions, which means the `background` event may never
142
+ * reach JS in time. To handle this we schedule a deferred cancellation when
143
+ * the app becomes `inactive`. If the app returns to `active` before the
144
+ * timeout fires, the cancellation is cleared. If it transitions to
145
+ * `background` first, we cancel immediately and clear the timeout.
134
146
  */
135
147
  export const cancelInBackground = (client, span) => {
148
+ let inactiveTimeout;
149
+ const cancelSpan = () => {
150
+ if (inactiveTimeout !== undefined) {
151
+ clearTimeout(inactiveTimeout);
152
+ inactiveTimeout = undefined;
153
+ }
154
+ debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);
155
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });
156
+ span.end();
157
+ };
136
158
  const subscription = AppState.addEventListener('change', (newState) => {
137
159
  if (newState === 'background') {
138
- debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);
139
- span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });
140
- span.end();
160
+ cancelSpan();
161
+ }
162
+ else if (Platform.OS === 'ios' && newState === 'inactive') {
163
+ // Schedule a deferred cancellation — if the JS thread is suspended
164
+ // before the 'background' event fires, this timer will execute when
165
+ // the app is eventually resumed and end the span.
166
+ if (inactiveTimeout === undefined) {
167
+ inactiveTimeout = setTimeout(cancelSpan, IOS_INACTIVE_CANCEL_DELAY_MS);
168
+ }
169
+ }
170
+ else if (newState === 'active') {
171
+ // App returned to foreground — clear any pending inactive cancellation.
172
+ if (inactiveTimeout !== undefined) {
173
+ clearTimeout(inactiveTimeout);
174
+ inactiveTimeout = undefined;
175
+ }
141
176
  }
142
177
  });
143
178
  subscription &&
@@ -145,6 +180,10 @@ export const cancelInBackground = (client, span) => {
145
180
  var _a;
146
181
  if (endedSpan === span) {
147
182
  debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);
183
+ if (inactiveTimeout !== undefined) {
184
+ clearTimeout(inactiveTimeout);
185
+ inactiveTimeout = undefined;
186
+ }
148
187
  (_a = subscription === null || subscription === void 0 ? void 0 : subscription.remove) === null || _a === void 0 ? void 0 : _a.call(subscription);
149
188
  }
150
189
  });
@@ -1 +1 @@
1
- {"version":3,"file":"onSpanEndUtils.js","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Span } from '@sentry/core';\nimport { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';\nimport type { AppStateStatus } from 'react-native';\nimport { AppState } from 'react-native';\nimport { isRootSpan, isSentrySpan } from '../utils/span';\n\n/**\n * Hooks on span end event to execute a callback when the span ends.\n */\nexport function onThisSpanEnd(client: Client, span: Span, callback: (span: Span) => void): void {\n client.on('spanEnd', (endedSpan: Span) => {\n if (span !== endedSpan) {\n return;\n }\n callback(endedSpan);\n });\n}\n\nexport const adjustTransactionDuration = (client: Client, span: Span, maxDurationMs: number): void => {\n if (!isRootSpan(span)) {\n debug.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n const endTimestamp = spanToJSON(span).timestamp;\n const startTimestamp = spanToJSON(span).start_timestamp;\n if (!endTimestamp || !startTimestamp) {\n return;\n }\n\n const diff = endTimestamp - startTimestamp;\n const isOutdatedTransaction = endTimestamp && (diff > maxDurationMs || diff < 0);\n if (isOutdatedTransaction) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });\n // TODO: check where was used, might be possible to delete\n span.setAttribute('maxTransactionDurationExceeded', 'true');\n }\n });\n};\n\n/**\n * Helper function to filter out auto-instrumentation child spans.\n */\nfunction getMeaningfulChildSpans(span: Span): Span[] {\n const children = getSpanDescendants(span);\n return children.filter(\n child =>\n child.spanContext().spanId !== span.spanContext().spanId &&\n spanToJSON(child).op !== 'ui.load.initial_display' &&\n spanToJSON(child).op !== 'navigation.processing',\n );\n}\n\n/**\n * Generic helper to discard empty navigation spans based on a condition.\n */\nfunction discardEmptyNavigationSpan(\n client: Client | undefined,\n span: Span | undefined,\n shouldDiscardFn: (span: Span) => boolean,\n onDiscardFn: (span: Span) => void,\n): void {\n if (!client) {\n debug.warn('Could not hook on spanEnd event because client is not defined.');\n return;\n }\n\n if (!span) {\n debug.warn('Could not hook on spanEnd event because span is not defined.');\n return;\n }\n\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling empty navigation spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n if (!shouldDiscardFn(span)) {\n return;\n }\n\n const meaningfulChildren = getMeaningfulChildSpans(span);\n if (meaningfulChildren.length <= 0) {\n onDiscardFn(span);\n span['_sampled'] = false;\n }\n });\n}\n\nexport const ignoreEmptyBackNavigation = (client: Client | undefined, span: Span | undefined): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if route has been seen before\n span => spanToJSON(span).data?.['route.has_been_seen'] === true,\n // Log message when discarding\n () => {\n debug.log(\n 'Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.',\n );\n },\n );\n};\n\n/**\n * Discards empty \"Route Change\" transactions that never received route information.\n * This happens when navigation library emits a route change event but getCurrentRoute() returns undefined.\n * Such transactions don't contain any useful information and should not be sent to Sentry.\n *\n * This function must be called with a reference tracker function that can check if the span\n * was cleared from the integration's tracking (indicating it went through the state listener).\n */\nexport const ignoreEmptyRouteChangeTransactions = (\n client: Client | undefined,\n span: Span | undefined,\n defaultNavigationSpanName: string,\n isSpanStillTracked: () => boolean,\n): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if:\n // 1. Still has default name\n // 2. No route information was set\n // 3. Still being tracked (state listener never called)\n span => {\n const spanJSON = spanToJSON(span);\n return (\n spanJSON.description === defaultNavigationSpanName && !spanJSON.data?.['route.name'] && isSpanStillTracked()\n );\n },\n // Log and record dropped event\n _span => {\n debug.log(`Discarding empty \"${defaultNavigationSpanName}\" transaction that never received route information.`);\n client?.recordDroppedEvent('sample_rate', 'transaction');\n },\n );\n};\n\n/**\n * Idle Transaction callback to only sample transactions with child spans.\n * To avoid side effects of other callbacks this should be hooked as the last callback.\n */\nexport const onlySampleIfChildSpans = (client: Client, span: Span): void => {\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling childless spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n const children = getSpanDescendants(span);\n\n if (children.length <= 1) {\n // Span always has at lest one child, itself\n debug.log(`Not sampling as ${spanToJSON(span).op} transaction has no child spans.`);\n span['_sampled'] = false;\n }\n });\n};\n\n/**\n * Hooks on AppState change to cancel the span if the app goes background.\n */\nexport const cancelInBackground = (client: Client, span: Span): void => {\n const subscription = AppState.addEventListener('change', (newState: AppStateStatus) => {\n if (newState === 'background') {\n debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });\n span.end();\n }\n });\n\n subscription &&\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan === span) {\n debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);\n subscription?.remove?.();\n }\n });\n};\n"]}
1
+ {"version":3,"file":"onSpanEndUtils.js","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Span } from '@sentry/core';\nimport { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';\nimport type { AppStateStatus } from 'react-native';\nimport { AppState, Platform } from 'react-native';\nimport { isRootSpan, isSentrySpan } from '../utils/span';\n\n/**\n * The time to wait after the app enters the `inactive` state on iOS before\n * cancelling the span.\n */\nconst IOS_INACTIVE_CANCEL_DELAY_MS = 5_000;\n\n/**\n * Hooks on span end event to execute a callback when the span ends.\n */\nexport function onThisSpanEnd(client: Client, span: Span, callback: (span: Span) => void): void {\n client.on('spanEnd', (endedSpan: Span) => {\n if (span !== endedSpan) {\n return;\n }\n callback(endedSpan);\n });\n}\n\nexport const adjustTransactionDuration = (client: Client, span: Span, maxDurationMs: number): void => {\n if (!isRootSpan(span)) {\n debug.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n const endTimestamp = spanToJSON(span).timestamp;\n const startTimestamp = spanToJSON(span).start_timestamp;\n if (!endTimestamp || !startTimestamp) {\n return;\n }\n\n const diff = endTimestamp - startTimestamp; // a diff in *seconds*\n const isOutdatedTransaction = diff > maxDurationMs / 1000 || diff < 0;\n\n if (isOutdatedTransaction) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });\n // TODO: check where was used, might be possible to delete\n span.setAttribute('maxTransactionDurationExceeded', 'true');\n }\n });\n};\n\n/**\n * Helper function to filter out auto-instrumentation child spans.\n */\nfunction getMeaningfulChildSpans(span: Span): Span[] {\n const children = getSpanDescendants(span);\n return children.filter(\n child =>\n child.spanContext().spanId !== span.spanContext().spanId &&\n spanToJSON(child).op !== 'ui.load.initial_display' &&\n spanToJSON(child).op !== 'navigation.processing',\n );\n}\n\n/**\n * Generic helper to discard empty navigation spans based on a condition.\n */\nfunction discardEmptyNavigationSpan(\n client: Client | undefined,\n span: Span | undefined,\n shouldDiscardFn: (span: Span) => boolean,\n onDiscardFn: (span: Span) => void,\n): void {\n if (!client) {\n debug.warn('Could not hook on spanEnd event because client is not defined.');\n return;\n }\n\n if (!span) {\n debug.warn('Could not hook on spanEnd event because span is not defined.');\n return;\n }\n\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling empty navigation spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n if (!shouldDiscardFn(span)) {\n return;\n }\n\n const meaningfulChildren = getMeaningfulChildSpans(span);\n if (meaningfulChildren.length <= 0) {\n onDiscardFn(span);\n span['_sampled'] = false;\n }\n });\n}\n\nexport const ignoreEmptyBackNavigation = (client: Client | undefined, span: Span | undefined): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if route has been seen before\n span => spanToJSON(span).data?.['route.has_been_seen'] === true,\n // Log message when discarding\n () => {\n debug.log(\n 'Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.',\n );\n },\n );\n};\n\n/**\n * Discards empty \"Route Change\" transactions that never received route information.\n * This happens when navigation library emits a route change event but getCurrentRoute() returns undefined.\n * Such transactions don't contain any useful information and should not be sent to Sentry.\n *\n * This function must be called with a reference tracker function that can check if the span\n * was cleared from the integration's tracking (indicating it went through the state listener).\n */\nexport const ignoreEmptyRouteChangeTransactions = (\n client: Client | undefined,\n span: Span | undefined,\n defaultNavigationSpanName: string,\n isSpanStillTracked: () => boolean,\n): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if:\n // 1. Still has default name\n // 2. No route information was set\n // 3. Still being tracked (state listener never called)\n span => {\n const spanJSON = spanToJSON(span);\n return (\n spanJSON.description === defaultNavigationSpanName && !spanJSON.data?.['route.name'] && isSpanStillTracked()\n );\n },\n // Log and record dropped event\n _span => {\n debug.log(`Discarding empty \"${defaultNavigationSpanName}\" transaction that never received route information.`);\n client?.recordDroppedEvent('sample_rate', 'transaction');\n },\n );\n};\n\n/**\n * Idle Transaction callback to only sample transactions with child spans.\n * To avoid side effects of other callbacks this should be hooked as the last callback.\n */\nexport const onlySampleIfChildSpans = (client: Client, span: Span): void => {\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling childless spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n const children = getSpanDescendants(span);\n\n if (children.length <= 1) {\n // Span always has at lest one child, itself\n debug.log(`Not sampling as ${spanToJSON(span).op} transaction has no child spans.`);\n span['_sampled'] = false;\n }\n });\n};\n\n/**\n * Hooks on AppState change to cancel the span if the app goes background.\n *\n * On iOS the JS thread can be suspended between the `inactive` and\n * `background` transitions, which means the `background` event may never\n * reach JS in time. To handle this we schedule a deferred cancellation when\n * the app becomes `inactive`. If the app returns to `active` before the\n * timeout fires, the cancellation is cleared. If it transitions to\n * `background` first, we cancel immediately and clear the timeout.\n */\nexport const cancelInBackground = (client: Client, span: Span): void => {\n let inactiveTimeout: ReturnType<typeof setTimeout> | undefined;\n\n const cancelSpan = (): void => {\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });\n span.end();\n };\n\n const subscription = AppState.addEventListener('change', (newState: AppStateStatus) => {\n if (newState === 'background') {\n cancelSpan();\n } else if (Platform.OS === 'ios' && newState === 'inactive') {\n // Schedule a deferred cancellation — if the JS thread is suspended\n // before the 'background' event fires, this timer will execute when\n // the app is eventually resumed and end the span.\n if (inactiveTimeout === undefined) {\n inactiveTimeout = setTimeout(cancelSpan, IOS_INACTIVE_CANCEL_DELAY_MS);\n }\n } else if (newState === 'active') {\n // App returned to foreground — clear any pending inactive cancellation.\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n }\n });\n\n subscription &&\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan === span) {\n debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n subscription?.remove?.();\n }\n });\n};\n"]}
@@ -8,4 +8,6 @@ export declare const SPAN_ORIGIN_AUTO_NAVIGATION_CUSTOM = "auto.navigation.custo
8
8
  export declare const SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY = "auto.ui.time_to_display";
9
9
  export declare const SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY = "manual.ui.time_to_display";
10
10
  export declare const SPAN_ORIGIN_AUTO_EXPO_ROUTER_PREFETCH = "auto.expo_router.prefetch";
11
+ export declare const SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE = "auto.resource.expo_image";
12
+ export declare const SPAN_ORIGIN_AUTO_RESOURCE_EXPO_ASSET = "auto.resource.expo_asset";
11
13
  //# sourceMappingURL=origin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/origin.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAC/D,eAAO,MAAM,8BAA8B,uBAAuB,CAAC;AAEnE,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAC/D,eAAO,MAAM,0BAA0B,mBAAmB,CAAC;AAE3D,eAAO,MAAM,mDAAmD,4CAA4C,CAAC;AAC7G,eAAO,MAAM,4CAA4C,qCAAqC,CAAC;AAC/F,eAAO,MAAM,kCAAkC,2BAA2B,CAAC;AAE3E,eAAO,MAAM,mCAAmC,4BAA4B,CAAC;AAC7E,eAAO,MAAM,qCAAqC,8BAA8B,CAAC;AAEjF,eAAO,MAAM,qCAAqC,8BAA8B,CAAC"}
1
+ {"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/origin.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAC/D,eAAO,MAAM,8BAA8B,uBAAuB,CAAC;AAEnE,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAC/D,eAAO,MAAM,0BAA0B,mBAAmB,CAAC;AAE3D,eAAO,MAAM,mDAAmD,4CAA4C,CAAC;AAC7G,eAAO,MAAM,4CAA4C,qCAAqC,CAAC;AAC/F,eAAO,MAAM,kCAAkC,2BAA2B,CAAC;AAE3E,eAAO,MAAM,mCAAmC,4BAA4B,CAAC;AAC7E,eAAO,MAAM,qCAAqC,8BAA8B,CAAC;AAEjF,eAAO,MAAM,qCAAqC,8BAA8B,CAAC;AACjF,eAAO,MAAM,oCAAoC,6BAA6B,CAAC;AAC/E,eAAO,MAAM,oCAAoC,6BAA6B,CAAC"}
@@ -8,4 +8,6 @@ export const SPAN_ORIGIN_AUTO_NAVIGATION_CUSTOM = 'auto.navigation.custom';
8
8
  export const SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY = 'auto.ui.time_to_display';
9
9
  export const SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY = 'manual.ui.time_to_display';
10
10
  export const SPAN_ORIGIN_AUTO_EXPO_ROUTER_PREFETCH = 'auto.expo_router.prefetch';
11
+ export const SPAN_ORIGIN_AUTO_RESOURCE_EXPO_IMAGE = 'auto.resource.expo_image';
12
+ export const SPAN_ORIGIN_AUTO_RESOURCE_EXPO_ASSET = 'auto.resource.expo_asset';
11
13
  //# sourceMappingURL=origin.js.map