@sentry/react-native 5.25.0 → 5.26.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 (101) hide show
  1. package/CHANGELOG.md +139 -3
  2. package/RNSentry.podspec +1 -1
  3. package/android/build.gradle +1 -1
  4. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +63 -2
  5. package/android/src/main/java/io/sentry/react/RNSentryReplayBreadcrumbConverter.java +187 -0
  6. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +10 -0
  7. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +10 -0
  8. package/dist/js/NativeRNSentry.d.ts +2 -0
  9. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  10. package/dist/js/NativeRNSentry.js.map +1 -1
  11. package/dist/js/client.d.ts +4 -0
  12. package/dist/js/client.d.ts.map +1 -1
  13. package/dist/js/client.js +12 -2
  14. package/dist/js/client.js.map +1 -1
  15. package/dist/js/integrations/default.d.ts.map +1 -1
  16. package/dist/js/integrations/default.js +9 -1
  17. package/dist/js/integrations/default.js.map +1 -1
  18. package/dist/js/integrations/exports.d.ts +2 -1
  19. package/dist/js/integrations/exports.d.ts.map +1 -1
  20. package/dist/js/integrations/exports.js +2 -1
  21. package/dist/js/integrations/exports.js.map +1 -1
  22. package/dist/js/integrations/index.d.ts +1 -0
  23. package/dist/js/integrations/index.d.ts.map +1 -1
  24. package/dist/js/integrations/index.js +1 -0
  25. package/dist/js/integrations/index.js.map +1 -1
  26. package/dist/js/options.d.ts +24 -2
  27. package/dist/js/options.d.ts.map +1 -1
  28. package/dist/js/options.js.map +1 -1
  29. package/dist/js/replay/mobilereplay.d.ts +47 -0
  30. package/dist/js/replay/mobilereplay.d.ts.map +1 -0
  31. package/dist/js/replay/mobilereplay.js +100 -0
  32. package/dist/js/replay/mobilereplay.js.map +1 -0
  33. package/dist/js/replay/networkUtils.d.ts +8 -0
  34. package/dist/js/replay/networkUtils.d.ts.map +1 -0
  35. package/dist/js/replay/networkUtils.js +52 -0
  36. package/dist/js/replay/networkUtils.js.map +1 -0
  37. package/dist/js/replay/xhrUtils.d.ts +6 -0
  38. package/dist/js/replay/xhrUtils.d.ts.map +1 -0
  39. package/dist/js/replay/xhrUtils.js +31 -0
  40. package/dist/js/replay/xhrUtils.js.map +1 -0
  41. package/dist/js/tools/enableLogger.d.ts +5 -0
  42. package/dist/js/tools/enableLogger.d.ts.map +1 -0
  43. package/dist/js/tools/enableLogger.js +13 -0
  44. package/dist/js/tools/enableLogger.js.map +1 -0
  45. package/dist/js/tools/metroconfig.d.ts +19 -4
  46. package/dist/js/tools/metroconfig.d.ts.map +1 -1
  47. package/dist/js/tools/metroconfig.js +38 -3
  48. package/dist/js/tools/metroconfig.js.map +1 -1
  49. package/dist/js/tools/sentryBabelTransformer.d.ts +4 -0
  50. package/dist/js/tools/sentryBabelTransformer.d.ts.map +1 -0
  51. package/dist/js/tools/sentryBabelTransformer.js +28 -0
  52. package/dist/js/tools/sentryBabelTransformer.js.map +1 -0
  53. package/dist/js/tools/sentryBabelTransformerUtils.d.ts +18 -0
  54. package/dist/js/tools/sentryBabelTransformerUtils.d.ts.map +1 -0
  55. package/dist/js/tools/sentryBabelTransformerUtils.js +67 -0
  56. package/dist/js/tools/sentryBabelTransformerUtils.js.map +1 -0
  57. package/dist/js/tools/vendor/metro/metroBabelTransformer.d.ts +35 -0
  58. package/dist/js/tools/vendor/metro/metroBabelTransformer.d.ts.map +1 -0
  59. package/dist/js/tools/vendor/metro/metroBabelTransformer.js +3 -0
  60. package/dist/js/tools/vendor/metro/metroBabelTransformer.js.map +1 -0
  61. package/dist/js/touchevents.d.ts.map +1 -1
  62. package/dist/js/touchevents.js +57 -30
  63. package/dist/js/touchevents.js.map +1 -1
  64. package/dist/js/utils/clientutils.d.ts +10 -0
  65. package/dist/js/utils/clientutils.d.ts.map +1 -0
  66. package/dist/js/utils/clientutils.js +9 -0
  67. package/dist/js/utils/clientutils.js.map +1 -0
  68. package/dist/js/utils/environment.d.ts +4 -0
  69. package/dist/js/utils/environment.d.ts.map +1 -1
  70. package/dist/js/utils/environment.js +8 -0
  71. package/dist/js/utils/environment.js.map +1 -1
  72. package/dist/js/utils/worldwide.d.ts +6 -0
  73. package/dist/js/utils/worldwide.d.ts.map +1 -1
  74. package/dist/js/utils/worldwide.js.map +1 -1
  75. package/dist/js/version.d.ts +1 -1
  76. package/dist/js/version.js +1 -1
  77. package/dist/js/version.js.map +1 -1
  78. package/dist/js/wrapper.d.ts +7 -1
  79. package/dist/js/wrapper.d.ts.map +1 -1
  80. package/dist/js/wrapper.js +24 -0
  81. package/dist/js/wrapper.js.map +1 -1
  82. package/ios/RNSentry.mm +33 -1
  83. package/ios/RNSentryReplay.h +8 -0
  84. package/ios/RNSentryReplay.m +72 -0
  85. package/ios/RNSentryReplayBreadcrumbConverter.h +16 -0
  86. package/ios/RNSentryReplayBreadcrumbConverter.m +168 -0
  87. package/package.json +2 -1
  88. package/src/js/NativeRNSentry.ts +2 -0
  89. package/ts3.8/dist/js/NativeRNSentry.d.ts +2 -0
  90. package/ts3.8/dist/js/client.d.ts +4 -0
  91. package/ts3.8/dist/js/integrations/exports.d.ts +2 -1
  92. package/ts3.8/dist/js/integrations/index.d.ts +1 -0
  93. package/ts3.8/dist/js/options.d.ts +24 -2
  94. package/ts3.8/dist/js/replay/mobilereplay.d.ts +47 -0
  95. package/ts3.8/dist/js/replay/networkUtils.d.ts +8 -0
  96. package/ts3.8/dist/js/replay/xhrUtils.d.ts +6 -0
  97. package/ts3.8/dist/js/utils/clientutils.d.ts +10 -0
  98. package/ts3.8/dist/js/utils/environment.d.ts +4 -0
  99. package/ts3.8/dist/js/utils/worldwide.d.ts +6 -0
  100. package/ts3.8/dist/js/version.d.ts +1 -1
  101. package/ts3.8/dist/js/wrapper.d.ts +7 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.26.0
4
+
5
+ ### Features
6
+
7
+ - Session Replay Public Beta ([#3830](https://github.com/getsentry/sentry-react-native/pull/3830))
8
+
9
+ To enable Replay use the `replaysSessionSampleRate` or `replaysOnErrorSampleRate` options.
10
+
11
+ ```js
12
+ import * as Sentry from '@sentry/react-native';
13
+
14
+ Sentry.init({
15
+ _experiments: {
16
+ replaysSessionSampleRate: 1.0,
17
+ replaysOnErrorSampleRate: 1.0,
18
+ },
19
+ });
20
+ ```
21
+
22
+ To add React Component Names use `annotateReactComponents` in `metro.config.js`.
23
+
24
+ ```js
25
+ // For Expo
26
+ const { getSentryExpoConfig } = require("@sentry/react-native/metro");
27
+ const config = getSentryExpoConfig(__dirname, { annotateReactComponents: true });
28
+
29
+ // For RN
30
+ const { getDefaultConfig } = require('@react-native/metro-config');
31
+ const { withSentryConfig } = require('@sentry/react-native/metro');
32
+ module.exports = withSentryConfig(getDefaultConfig(__dirname), { annotateReactComponents: true });
33
+ ```
34
+
35
+ To change default redaction behavior add the `mobileReplayIntegration`.
36
+
37
+ ```js
38
+ import * as Sentry from '@sentry/react-native';
39
+
40
+ Sentry.init({
41
+ _experiments: {
42
+ replaysSessionSampleRate: 1.0,
43
+ replaysOnErrorSampleRate: 1.0,
44
+ },
45
+ integrations: [
46
+ Sentry.mobileReplayIntegration({
47
+ maskAllImages: true,
48
+ maskAllVectors: true,
49
+ maskAllText: true,
50
+ }),
51
+ ],
52
+ });
53
+ ```
54
+
55
+ To learn more visit [Sentry's Mobile Session Replay](https://docs.sentry.io/product/explore/session-replay/mobile/) documentation page.
56
+
57
+ ### Dependencies
58
+
59
+ - Bump Cocoa SDK from v8.30.0 to v8.31.1 ([#3954](https://github.com/getsentry/sentry-react-native/pull/3954))
60
+ - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8311)
61
+ - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.30.0...8.31.1)
62
+ - Bump Android SDK from v7.11.0 to v7.12.0 ([#3950](https://github.com/getsentry/sentry-react-native/pull/3949))
63
+ - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#7120)
64
+ - [diff](https://github.com/getsentry/sentry-java/compare/7.11.0...7.12.0)
65
+
3
66
  ## 5.25.0
4
67
 
5
68
  ### Features
@@ -23,6 +86,30 @@
23
86
  - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#7110)
24
87
  - [diff](https://github.com/getsentry/sentry-java/compare/7.10.0...7.11.0)
25
88
 
89
+ ## 5.25.0-alpha.2
90
+
91
+ ### Features
92
+
93
+ - Improve touch event component info if annotated with [`@sentry/babel-plugin-component-annotate`](https://www.npmjs.com/package/@sentry/babel-plugin-component-annotate) ([#3899](https://github.com/getsentry/sentry-react-native/pull/3899))
94
+ - Add replay breadcrumbs for touch & navigation events ([#3846](https://github.com/getsentry/sentry-react-native/pull/3846))
95
+ - Add network data to Session Replays ([#3912](https://github.com/getsentry/sentry-react-native/pull/3912))
96
+ - Filter Sentry Event Breadcrumbs from Mobile Replays ([#3925](https://github.com/getsentry/sentry-react-native/pull/3925))
97
+
98
+ ### Fixes
99
+
100
+ - `sentry-expo-upload-sourcemaps` no longer requires Sentry url when uploading sourcemaps to `sentry.io` ([#3915](https://github.com/getsentry/sentry-react-native/pull/3915))
101
+
102
+ ### Dependencies
103
+
104
+ - Bump Cocoa SDK from v8.25.0-alpha.0 to v8.30.0 ([#3914](https://github.com/getsentry/sentry-react-native/pull/3914))
105
+ - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8300)
106
+ - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.25.0-alpha.0...8.30.0)
107
+ - Bump Android SDK from v7.9.0-alpha.1 to v7.11.0-alpha.2 ([#3830](https://github.com/getsentry/sentry-react-native/pull/3830))
108
+ - [changelog](https://github.com/getsentry/sentry-java/blob/7.11.0-alpha.2/CHANGELOG.md#7110-alpha2)
109
+ - [diff](https://github.com/getsentry/sentry-java/compare/7.9.0-alpha.1...7.11.0-alpha.2)
110
+
111
+ Access to Mobile Replay is limited to early access orgs on Sentry. If you're interested, [sign up for the waitlist](https://sentry.io/lp/mobile-replay-beta/)
112
+
26
113
  ## 5.24.1
27
114
 
28
115
  ### Fixes
@@ -122,6 +209,14 @@ This release does *not* build on iOS. Please use `5.23.1` or newer.
122
209
  - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8270)
123
210
  - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.26.0...8.27.0)
124
211
 
212
+ ## 5.23.0-alpha.1
213
+
214
+ ### Fixes
215
+
216
+ - Pass `replaysSessionSampleRate` option to Android ([#3714](https://github.com/getsentry/sentry-react-native/pull/3714))
217
+
218
+ Access to Mobile Replay is limited to early access orgs on Sentry. If you're interested, [sign up for the waitlist](https://sentry.io/lp/mobile-replay-beta/)
219
+
125
220
  ## 5.22.3
126
221
 
127
222
  ### Fixes
@@ -155,6 +250,47 @@ This release does *not* build on iOS. Please use `5.23.1` or newer.
155
250
  - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8250)
156
251
  - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.24.0...8.25.0)
157
252
 
253
+ ## 5.23.0-alpha.0
254
+
255
+ ### Features
256
+
257
+ - Mobile Session Replay Alpha ([#3714](https://github.com/getsentry/sentry-react-native/pull/3714))
258
+
259
+ To enable Replay for React Native on mobile and web add the following options.
260
+
261
+ ```js
262
+ Sentry.init({
263
+ _experiments: {
264
+ replaysSessionSampleRate: 1.0,
265
+ replaysOnErrorSampleRate: 1.0,
266
+ },
267
+ });
268
+ ```
269
+
270
+ To change the default Mobile Replay options add the `mobileReplayIntegration`.
271
+
272
+ ```js
273
+ Sentry.init({
274
+ _experiments: {
275
+ replaysSessionSampleRate: 1.0,
276
+ replaysOnErrorSampleRate: 1.0,
277
+ },
278
+ integration: [
279
+ Sentry.mobileReplayIntegration({
280
+ maskAllText: true,
281
+ maskAllImages: true,
282
+ }),
283
+ ],
284
+ });
285
+ ```
286
+
287
+ Access is limited to early access orgs on Sentry. If you're interested, [sign up for the waitlist](https://sentry.io/lp/mobile-replay-beta/)
288
+
289
+ ### Dependencies
290
+
291
+ - Bump Cocoa SDK to [8.25.0-alpha.0](https://github.com/getsentry/sentry-cocoa/releases/tag/8.25.0-alpha.0)
292
+ - Bump Android SDK to [7.9.0-alpha.1](https://github.com/getsentry/sentry-java/releases/tag/7.9.0-alpha.1)
293
+
158
294
  ## 5.22.0
159
295
 
160
296
  ### Features
@@ -433,7 +569,7 @@ see [the Expo guide](https://docs.sentry.io/platforms/react-native/manual-setup/
433
569
  const { getSentryExpoConfig } = require("@sentry/react-native/metro");
434
570
 
435
571
  // const config = getDefaultConfig(__dirname);
436
- const config = getSentryExpoConfig(config, {});
572
+ const config = getSentryExpoConfig(__dirname);
437
573
  ```
438
574
 
439
575
  - New `npx sentry-expo-upload-sourcemaps` for simple EAS Update (`npx expo export`) source maps upload ([#3491](https://github.com/getsentry/sentry-react-native/pull/3491), [#3510](https://github.com/getsentry/sentry-react-native/pull/3510), [#3515](https://github.com/getsentry/sentry-react-native/pull/3515), [#3507](https://github.com/getsentry/sentry-react-native/pull/3507))
@@ -665,7 +801,7 @@ This release is compatible with `expo@50.0.0-preview.6` and newer.
665
801
  });
666
802
  ```
667
803
 
668
- Read more at https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#7690
804
+ Read more at <https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#7690>
669
805
 
670
806
  - Report current screen in `contexts.app.view_names` ([#3339](https://github.com/getsentry/sentry-react-native/pull/3339))
671
807
 
@@ -2704,7 +2840,7 @@ We are looking into ways making this more stable and plan to re-enable it again
2704
2840
 
2705
2841
  ## v0.23.2
2706
2842
 
2707
- - Fixed #228 again ¯\\_(ツ)_/¯
2843
+ - Fixed #228 again ¯\\*(ツ)*/¯
2708
2844
 
2709
2845
  ## v0.23.1
2710
2846
 
package/RNSentry.podspec CHANGED
@@ -33,7 +33,7 @@ Pod::Spec.new do |s|
33
33
  s.preserve_paths = '*.js'
34
34
 
35
35
  s.dependency 'React-Core'
36
- s.dependency 'Sentry/HybridSDK', '8.30.0'
36
+ s.dependency 'Sentry/HybridSDK', '8.31.1'
37
37
 
38
38
  s.source_files = 'ios/**/*.{h,m,mm}'
39
39
  s.public_header_files = 'ios/RNSentry.h'
@@ -54,5 +54,5 @@ android {
54
54
 
55
55
  dependencies {
56
56
  implementation 'com.facebook.react:react-native:+'
57
- api 'io.sentry:sentry-android:7.11.0'
57
+ api 'io.sentry:sentry-android:7.12.0'
58
58
  }
@@ -41,9 +41,11 @@ import java.io.IOException;
41
41
  import java.io.InputStream;
42
42
  import java.nio.charset.Charset;
43
43
  import java.util.HashMap;
44
+ import java.util.HashSet;
44
45
  import java.util.List;
45
46
  import java.util.Map;
46
47
  import java.util.Properties;
48
+ import java.util.Set;
47
49
  import java.util.concurrent.CountDownLatch;
48
50
 
49
51
  import io.sentry.Breadcrumb;
@@ -61,6 +63,7 @@ import io.sentry.SentryEvent;
61
63
  import io.sentry.SentryExecutorService;
62
64
  import io.sentry.SentryLevel;
63
65
  import io.sentry.SentryOptions;
66
+ import io.sentry.SentryReplayOptions;
64
67
  import io.sentry.UncaughtExceptionHandlerIntegration;
65
68
  import io.sentry.android.core.AndroidLogger;
66
69
  import io.sentry.android.core.AndroidProfiler;
@@ -79,6 +82,7 @@ import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
79
82
  import io.sentry.android.core.performance.AppStartMetrics;
80
83
  import io.sentry.protocol.SdkVersion;
81
84
  import io.sentry.protocol.SentryException;
85
+ import io.sentry.protocol.SentryId;
82
86
  import io.sentry.protocol.SentryPackage;
83
87
  import io.sentry.protocol.User;
84
88
  import io.sentry.protocol.ViewHierarchy;
@@ -186,7 +190,7 @@ public class RNSentryModuleImpl {
186
190
 
187
191
  options.setSentryClientName(sdkVersion.getName() + "/" + sdkVersion.getVersion());
188
192
  options.setNativeSdkName(NATIVE_SDK_NAME);
189
- options.setSdkVersion(sdkVersion);
193
+ options.setSdkVersion(sdkVersion);
190
194
 
191
195
  if (rnOptions.hasKey("debug") && rnOptions.getBoolean("debug")) {
192
196
  options.setDebug(true);
@@ -252,7 +256,10 @@ public class RNSentryModuleImpl {
252
256
  if (rnOptions.hasKey("enableNdk")) {
253
257
  options.setEnableNdk(rnOptions.getBoolean("enableNdk"));
254
258
  }
255
-
259
+ if (rnOptions.hasKey("_experiments")) {
260
+ options.getExperimental().setSessionReplay(getReplayOptions(rnOptions));
261
+ options.getReplayController().setBreadcrumbConverter(new RNSentryReplayBreadcrumbConverter());
262
+ }
256
263
  options.setBeforeSend((event, hint) -> {
257
264
  // React native internally throws a JavascriptException
258
265
  // Since we catch it before that, we don't want to send this one
@@ -293,6 +300,42 @@ public class RNSentryModuleImpl {
293
300
  promise.resolve(true);
294
301
  }
295
302
 
303
+ private SentryReplayOptions getReplayOptions(@NotNull ReadableMap rnOptions) {
304
+ @NotNull final SentryReplayOptions androidReplayOptions = new SentryReplayOptions();
305
+
306
+ @Nullable final ReadableMap rnExperimentsOptions = rnOptions.getMap("_experiments");
307
+ if (rnExperimentsOptions == null) {
308
+ return androidReplayOptions;
309
+ }
310
+
311
+ if (!(rnExperimentsOptions.hasKey("replaysSessionSampleRate") || rnExperimentsOptions.hasKey("replaysOnErrorSampleRate"))) {
312
+ return androidReplayOptions;
313
+ }
314
+
315
+ androidReplayOptions.setSessionSampleRate(rnExperimentsOptions.hasKey("replaysSessionSampleRate")
316
+ ? rnExperimentsOptions.getDouble("replaysSessionSampleRate") : null);
317
+ androidReplayOptions.setErrorSampleRate(rnExperimentsOptions.hasKey("replaysOnErrorSampleRate")
318
+ ? rnExperimentsOptions.getDouble("replaysOnErrorSampleRate") : null);
319
+
320
+ if (!rnOptions.hasKey("mobileReplayOptions")) {
321
+ return androidReplayOptions;
322
+ }
323
+ @Nullable final ReadableMap rnMobileReplayOptions = rnOptions.getMap("mobileReplayOptions");
324
+ if (rnMobileReplayOptions == null) {
325
+ return androidReplayOptions;
326
+ }
327
+
328
+ androidReplayOptions.setRedactAllText(!rnMobileReplayOptions.hasKey("maskAllText") || rnMobileReplayOptions.getBoolean("maskAllText"));
329
+ androidReplayOptions.setRedactAllImages(!rnMobileReplayOptions.hasKey("maskAllImages") || rnMobileReplayOptions.getBoolean("maskAllImages"));
330
+
331
+ final boolean redactVectors = !rnMobileReplayOptions.hasKey("maskAllVectors") || rnMobileReplayOptions.getBoolean("maskAllVectors");
332
+ if (redactVectors) {
333
+ androidReplayOptions.addClassToRedact("com.horcrux.svg.SvgView"); // react-native-svg
334
+ }
335
+
336
+ return androidReplayOptions;
337
+ }
338
+
296
339
  public void crash() {
297
340
  throw new RuntimeException("TEST - Sentry Client Crash (only works in release mode)");
298
341
  }
@@ -394,6 +437,24 @@ public class RNSentryModuleImpl {
394
437
  }
395
438
  }
396
439
 
440
+ public void captureReplay(boolean isHardCrash, Promise promise) {
441
+ Sentry.getCurrentHub().getOptions().getReplayController().sendReplay(isHardCrash, null, null);
442
+ promise.resolve(getCurrentReplayId());
443
+ }
444
+
445
+ public @Nullable String getCurrentReplayId() {
446
+ final @Nullable IScope scope = InternalSentrySdk.getCurrentScope();
447
+ if (scope == null) {
448
+ return null;
449
+ }
450
+
451
+ final @NotNull SentryId id = scope.getReplayId();
452
+ if (id == SentryId.EMPTY_ID) {
453
+ return null;
454
+ }
455
+ return id.toString();
456
+ }
457
+
397
458
  public void captureEnvelope(String rawBytes, ReadableMap options, Promise promise) {
398
459
  byte[] bytes = Base64.decode(rawBytes, Base64.DEFAULT);
399
460
 
@@ -0,0 +1,187 @@
1
+ package io.sentry.react;
2
+
3
+ import io.sentry.Breadcrumb;
4
+ import io.sentry.android.replay.DefaultReplayBreadcrumbConverter;
5
+ import io.sentry.rrweb.RRWebEvent;
6
+ import io.sentry.rrweb.RRWebBreadcrumbEvent;
7
+ import io.sentry.rrweb.RRWebSpanEvent;
8
+
9
+ import java.util.HashMap;
10
+ import org.jetbrains.annotations.NotNull;
11
+ import org.jetbrains.annotations.Nullable;
12
+ import org.jetbrains.annotations.TestOnly;
13
+
14
+ import java.util.List;
15
+ import java.util.Map;
16
+
17
+ public final class RNSentryReplayBreadcrumbConverter extends DefaultReplayBreadcrumbConverter {
18
+ public RNSentryReplayBreadcrumbConverter() {
19
+ }
20
+
21
+ @Override
22
+ public @Nullable RRWebEvent convert(final @NotNull Breadcrumb breadcrumb) {
23
+ if (breadcrumb.getCategory() == null) {
24
+ return null;
25
+ }
26
+
27
+ // Do not add Sentry Event breadcrumbs to replay
28
+ if (breadcrumb.getCategory().equals("sentry.event") ||
29
+ breadcrumb.getCategory().equals("sentry.transaction")) {
30
+ return null;
31
+ }
32
+ if (breadcrumb.getCategory().equals("http")) {
33
+ // Drop native http breadcrumbs to avoid duplicates
34
+ return null;
35
+ }
36
+
37
+ if (breadcrumb.getCategory().equals("touch")) {
38
+ return convertTouchBreadcrumb(breadcrumb);
39
+ }
40
+ if (breadcrumb.getCategory().equals("navigation")) {
41
+ return convertNavigationBreadcrumb(breadcrumb);
42
+ }
43
+ if (breadcrumb.getCategory().equals("xhr")) {
44
+ return convertNetworkBreadcrumb(breadcrumb);
45
+ }
46
+
47
+ RRWebEvent nativeBreadcrumb = super.convert(breadcrumb);
48
+
49
+ // ignore native navigation breadcrumbs
50
+ if (nativeBreadcrumb instanceof RRWebBreadcrumbEvent) {
51
+ final RRWebBreadcrumbEvent rrWebBreadcrumb = (RRWebBreadcrumbEvent) nativeBreadcrumb;
52
+ if (rrWebBreadcrumb.getCategory() != null && rrWebBreadcrumb.getCategory().equals("navigation")) {
53
+ return null;
54
+ }
55
+ }
56
+
57
+ return nativeBreadcrumb;
58
+ }
59
+
60
+ @TestOnly
61
+ public @NotNull RRWebEvent convertNavigationBreadcrumb(final @NotNull Breadcrumb breadcrumb) {
62
+ final RRWebBreadcrumbEvent rrWebBreadcrumb = new RRWebBreadcrumbEvent();
63
+ rrWebBreadcrumb.setCategory(breadcrumb.getCategory());
64
+ setRRWebEventDefaultsFrom(rrWebBreadcrumb, breadcrumb);
65
+ return rrWebBreadcrumb;
66
+ }
67
+
68
+ @TestOnly
69
+ public @NotNull RRWebEvent convertTouchBreadcrumb(final @NotNull Breadcrumb breadcrumb) {
70
+ final RRWebBreadcrumbEvent rrWebBreadcrumb = new RRWebBreadcrumbEvent();
71
+
72
+ rrWebBreadcrumb.setCategory("ui.tap");
73
+
74
+ rrWebBreadcrumb.setMessage(RNSentryReplayBreadcrumbConverter
75
+ .getTouchPathMessage(breadcrumb.getData("path")));
76
+
77
+ setRRWebEventDefaultsFrom(rrWebBreadcrumb, breadcrumb);
78
+ return rrWebBreadcrumb;
79
+ }
80
+
81
+ @TestOnly
82
+ public static @Nullable String getTouchPathMessage(final @Nullable Object maybePath) {
83
+ if (!(maybePath instanceof List)) {
84
+ return null;
85
+ }
86
+
87
+ final @NotNull List path = (List) maybePath;
88
+ if (path.size() == 0) {
89
+ return null;
90
+ }
91
+
92
+ final @NotNull StringBuilder message = new StringBuilder();
93
+ for (int i = Math.min(3, path.size() - 1); i >= 0; i--) {
94
+ final @Nullable Object maybeItem = path.get(i);
95
+ if (!(maybeItem instanceof Map)) {
96
+ return null;
97
+ }
98
+
99
+ final @NotNull Map item = (Map) maybeItem;
100
+ final @Nullable Object maybeName = item.get("name");
101
+ final @Nullable Object maybeLabel = item.get("label");
102
+ boolean hasName = maybeName instanceof String;
103
+ boolean hasLabel = maybeLabel instanceof String;
104
+ if (!hasName && !hasLabel) {
105
+ return null; // This again should never be allowed in JS, but to be safe we check it here
106
+ }
107
+ if (hasLabel) {
108
+ message.append(maybeLabel);
109
+ } else { // hasName is true
110
+ message.append(maybeName);
111
+ }
112
+
113
+ final @Nullable Object maybeElement = item.get("element");
114
+ final @Nullable Object maybeFile = item.get("file");
115
+ boolean hasElement = maybeElement instanceof String;
116
+ boolean hasFile = maybeFile instanceof String;
117
+ if (hasElement && hasFile) {
118
+ message.append('(')
119
+ .append(maybeElement)
120
+ .append(", ")
121
+ .append(maybeFile)
122
+ .append(')');
123
+ } else if (hasElement) {
124
+ message.append('(')
125
+ .append(maybeElement)
126
+ .append(')');
127
+ } else if (hasFile) {
128
+ message.append('(')
129
+ .append(maybeFile)
130
+ .append(')');
131
+ }
132
+
133
+ if (i > 0) {
134
+ message.append(" > ");
135
+ }
136
+ }
137
+
138
+ return message.toString();
139
+ }
140
+
141
+ @TestOnly
142
+ public @Nullable RRWebEvent convertNetworkBreadcrumb(final @NotNull Breadcrumb breadcrumb) {
143
+ final Double startTimestamp = breadcrumb.getData("start_timestamp") instanceof Number
144
+ ? (Double) breadcrumb.getData("start_timestamp") : null;
145
+ final Double endTimestamp = breadcrumb.getData("end_timestamp") instanceof Number
146
+ ? (Double) breadcrumb.getData("end_timestamp") : null;
147
+ final String url = breadcrumb.getData("url") instanceof String
148
+ ? (String) breadcrumb.getData("url") : null;
149
+
150
+ if (startTimestamp == null || endTimestamp == null || url == null) {
151
+ return null;
152
+ }
153
+
154
+ final HashMap<String, Object> data = new HashMap<>();
155
+ if (breadcrumb.getData("method") instanceof String) {
156
+ data.put("method", breadcrumb.getData("method"));
157
+ }
158
+ if (breadcrumb.getData("status_code") instanceof Double) {
159
+ final Double statusCode = (Double) breadcrumb.getData("status_code");
160
+ if (statusCode > 0) {
161
+ data.put("statusCode", statusCode.intValue());
162
+ }
163
+ }
164
+ if (breadcrumb.getData("request_body_size") instanceof Double) {
165
+ data.put("requestBodySize", breadcrumb.getData("request_body_size"));
166
+ }
167
+ if (breadcrumb.getData("response_body_size") instanceof Double) {
168
+ data.put("responseBodySize", breadcrumb.getData("response_body_size"));
169
+ }
170
+
171
+ final RRWebSpanEvent rrWebSpanEvent = new RRWebSpanEvent();
172
+ rrWebSpanEvent.setOp("resource.http");
173
+ rrWebSpanEvent.setStartTimestamp(startTimestamp / 1000.0);
174
+ rrWebSpanEvent.setEndTimestamp(endTimestamp / 1000.0);
175
+ rrWebSpanEvent.setDescription(url);
176
+ rrWebSpanEvent.setData(data);
177
+ return rrWebSpanEvent;
178
+ }
179
+
180
+ private void setRRWebEventDefaultsFrom(final @NotNull RRWebBreadcrumbEvent rrWebBreadcrumb, final @NotNull Breadcrumb breadcrumb) {
181
+ rrWebBreadcrumb.setLevel(breadcrumb.getLevel());
182
+ rrWebBreadcrumb.setData(breadcrumb.getData());
183
+ rrWebBreadcrumb.setTimestamp(breadcrumb.getTimestamp().getTime());
184
+ rrWebBreadcrumb.setBreadcrumbTimestamp(breadcrumb.getTimestamp().getTime() / 1000.0);
185
+ rrWebBreadcrumb.setBreadcrumbType("default");
186
+ }
187
+ }
@@ -158,4 +158,14 @@ public class RNSentryModule extends NativeRNSentrySpec {
158
158
  // Not used on Android
159
159
  return null;
160
160
  }
161
+
162
+ @Override
163
+ public void captureReplay(boolean isHardCrash, Promise promise) {
164
+ this.impl.captureReplay(isHardCrash, promise);
165
+ }
166
+
167
+ @Override
168
+ public String getCurrentReplayId() {
169
+ return this.impl.getCurrentReplayId();
170
+ }
161
171
  }
@@ -158,4 +158,14 @@ public class RNSentryModule extends ReactContextBaseJavaModule {
158
158
  // Not used on Android
159
159
  return null;
160
160
  }
161
+
162
+ @ReactMethod
163
+ public void captureReplay(boolean isHardCrash, Promise promise) {
164
+ this.impl.captureReplay(isHardCrash, promise);
165
+ }
166
+
167
+ @ReactMethod(isBlockingSynchronousMethod = true)
168
+ public String getCurrentReplayId() {
169
+ return this.impl.getCurrentReplayId();
170
+ }
161
171
  }
@@ -39,6 +39,8 @@ export interface Spec extends TurboModule {
39
39
  fetchNativePackageName(): string | undefined | null;
40
40
  fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | undefined | null;
41
41
  initNativeReactNavigationNewFrameTracking(): Promise<void>;
42
+ captureReplay(isHardCrash: boolean): Promise<string | undefined | null>;
43
+ getCurrentReplayId(): string | undefined | null;
42
44
  }
43
45
  export type NativeStackFrame = {
44
46
  platform: string;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeRNSentry.d.ts","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NativeRNSentry.d.ts","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"NativeRNSentry.js","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAsJnD,2DAA2D;AAC3D,eAAe,mBAAmB,CAAC,YAAY,CAAO,UAAU,CAAC,CAAC","sourcesContent":["import type { Package } from '@sentry/types';\nimport type { TurboModule } from 'react-native';\nimport { TurboModuleRegistry } from 'react-native';\n\nimport type { UnsafeObject } from './utils/rnlibrariesinterface';\n\n// There has to be only one interface and it has to be named `Spec`\n// Only extra allowed definitions are types (probably codegen bug)\nexport interface Spec extends TurboModule {\n addListener: (eventType: string) => void;\n removeListeners: (id: number) => void;\n addBreadcrumb(breadcrumb: UnsafeObject): void;\n captureEnvelope(\n bytes: string,\n options: {\n hardCrashed: boolean;\n },\n ): Promise<boolean>;\n captureScreenshot(): Promise<NativeScreenshot[] | undefined | null>;\n clearBreadcrumbs(): void;\n crash(): void;\n closeNativeSdk(): Promise<void>;\n disableNativeFramesTracking(): void;\n fetchNativeRelease(): Promise<NativeReleaseResponse>;\n fetchNativeSdkInfo(): Promise<Package | null>;\n fetchNativeDeviceContexts(): Promise<NativeDeviceContextsResponse | null>;\n fetchNativeAppStart(): Promise<NativeAppStartResponse | null>;\n fetchNativeFrames(): Promise<NativeFramesResponse | null>;\n initNativeSdk(options: UnsafeObject): Promise<boolean>;\n setUser(defaultUserKeys: UnsafeObject | null, otherUserKeys: UnsafeObject | null): void;\n setContext(key: string, value: UnsafeObject | null): void;\n setExtra(key: string, value: string): void;\n setTag(key: string, value: string): void;\n enableNativeFramesTracking(): void;\n fetchModules(): Promise<string | undefined | null>;\n fetchViewHierarchy(): Promise<number[] | undefined | null>;\n startProfiling(): { started?: boolean; error?: string };\n stopProfiling(): {\n profile?: string;\n nativeProfile?: UnsafeObject;\n androidProfile?: UnsafeObject;\n error?: string;\n };\n fetchNativePackageName(): string | undefined | null;\n fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | undefined | null;\n initNativeReactNavigationNewFrameTracking(): Promise<void>;\n}\n\nexport type NativeStackFrame = {\n platform: string;\n /**\n * The instruction address of this frame.\n * Formatted as hex with 0x prefix.\n */\n instruction_addr: string;\n package?: string;\n /**\n * The debug image address of this frame.\n * Formatted as hex with 0x prefix.\n */\n image_addr?: string;\n in_app?: boolean;\n /**\n * The symbol name of this frame.\n * If symbolicated locally.\n */\n function?: string;\n /**\n * The symbol address of this frame.\n * If symbolicated locally.\n * Formatted as hex with 0x prefix.\n */\n symbol_addr?: string;\n};\n\nexport type NativeDebugImage = {\n name?: string;\n type?: string;\n uuid?: string;\n debug_id?: string;\n image_addr?: string;\n image_size?: number;\n code_file?: string;\n image_vmaddr?: string;\n};\n\nexport type NativeStackFrames = {\n frames: NativeStackFrame[];\n debugMetaImages?: NativeDebugImage[];\n};\n\nexport type NativeAppStartResponse = {\n type: 'cold' | 'warm' | 'unknown';\n has_fetched: boolean;\n app_start_timestamp_ms?: number;\n spans: {\n description: string;\n start_timestamp_ms: number;\n end_timestamp_ms: number;\n }[];\n};\n\nexport type NativeFramesResponse = {\n totalFrames: number;\n slowFrames: number;\n frozenFrames: number;\n};\n\nexport type NativeReleaseResponse = {\n build: string;\n id: string;\n version: string;\n};\n\n/**\n * This type describes serialized scope from sentry-cocoa and sentry-android\n * https://github.com/getsentry/sentry-cocoa/blob/master/Sources/Sentry/SentryScope.m\n * https://github.com/getsentry/sentry-java/blob/a461f7e125b65240004e6162b341f383ce2e1394/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java#L32\n */\nexport type NativeDeviceContextsResponse = {\n [key: string]: unknown;\n tags?: Record<string, string>;\n extra?: Record<string, unknown>;\n contexts?: Record<string, Record<string, unknown>>;\n user?: {\n userId?: string;\n email?: string;\n username?: string;\n ipAddress?: string;\n segment?: string;\n data?: Record<string, unknown>;\n };\n dist?: string;\n environment?: string;\n fingerprint?: string[];\n level?: string;\n breadcrumbs?: {\n level?: string;\n timestamp?: string;\n category?: string;\n type?: string;\n message?: string;\n data?: Record<string, unknown>;\n }[];\n};\n\nexport type NativeScreenshot = {\n data: number[];\n contentType: string;\n filename: string;\n};\n\n// The export must be here to pass codegen even if not used\nexport default TurboModuleRegistry.getEnforcing<Spec>('RNSentry');\n"]}
1
+ {"version":3,"file":"NativeRNSentry.js","sourceRoot":"","sources":["../../src/js/NativeRNSentry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAwJnD,2DAA2D;AAC3D,eAAe,mBAAmB,CAAC,YAAY,CAAO,UAAU,CAAC,CAAC","sourcesContent":["import type { Package } from '@sentry/types';\nimport type { TurboModule } from 'react-native';\nimport { TurboModuleRegistry } from 'react-native';\n\nimport type { UnsafeObject } from './utils/rnlibrariesinterface';\n\n// There has to be only one interface and it has to be named `Spec`\n// Only extra allowed definitions are types (probably codegen bug)\nexport interface Spec extends TurboModule {\n addListener: (eventType: string) => void;\n removeListeners: (id: number) => void;\n addBreadcrumb(breadcrumb: UnsafeObject): void;\n captureEnvelope(\n bytes: string,\n options: {\n hardCrashed: boolean;\n },\n ): Promise<boolean>;\n captureScreenshot(): Promise<NativeScreenshot[] | undefined | null>;\n clearBreadcrumbs(): void;\n crash(): void;\n closeNativeSdk(): Promise<void>;\n disableNativeFramesTracking(): void;\n fetchNativeRelease(): Promise<NativeReleaseResponse>;\n fetchNativeSdkInfo(): Promise<Package | null>;\n fetchNativeDeviceContexts(): Promise<NativeDeviceContextsResponse | null>;\n fetchNativeAppStart(): Promise<NativeAppStartResponse | null>;\n fetchNativeFrames(): Promise<NativeFramesResponse | null>;\n initNativeSdk(options: UnsafeObject): Promise<boolean>;\n setUser(defaultUserKeys: UnsafeObject | null, otherUserKeys: UnsafeObject | null): void;\n setContext(key: string, value: UnsafeObject | null): void;\n setExtra(key: string, value: string): void;\n setTag(key: string, value: string): void;\n enableNativeFramesTracking(): void;\n fetchModules(): Promise<string | undefined | null>;\n fetchViewHierarchy(): Promise<number[] | undefined | null>;\n startProfiling(): { started?: boolean; error?: string };\n stopProfiling(): {\n profile?: string;\n nativeProfile?: UnsafeObject;\n androidProfile?: UnsafeObject;\n error?: string;\n };\n fetchNativePackageName(): string | undefined | null;\n fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | undefined | null;\n initNativeReactNavigationNewFrameTracking(): Promise<void>;\n captureReplay(isHardCrash: boolean): Promise<string | undefined | null>;\n getCurrentReplayId(): string | undefined | null;\n}\n\nexport type NativeStackFrame = {\n platform: string;\n /**\n * The instruction address of this frame.\n * Formatted as hex with 0x prefix.\n */\n instruction_addr: string;\n package?: string;\n /**\n * The debug image address of this frame.\n * Formatted as hex with 0x prefix.\n */\n image_addr?: string;\n in_app?: boolean;\n /**\n * The symbol name of this frame.\n * If symbolicated locally.\n */\n function?: string;\n /**\n * The symbol address of this frame.\n * If symbolicated locally.\n * Formatted as hex with 0x prefix.\n */\n symbol_addr?: string;\n};\n\nexport type NativeDebugImage = {\n name?: string;\n type?: string;\n uuid?: string;\n debug_id?: string;\n image_addr?: string;\n image_size?: number;\n code_file?: string;\n image_vmaddr?: string;\n};\n\nexport type NativeStackFrames = {\n frames: NativeStackFrame[];\n debugMetaImages?: NativeDebugImage[];\n};\n\nexport type NativeAppStartResponse = {\n type: 'cold' | 'warm' | 'unknown';\n has_fetched: boolean;\n app_start_timestamp_ms?: number;\n spans: {\n description: string;\n start_timestamp_ms: number;\n end_timestamp_ms: number;\n }[];\n};\n\nexport type NativeFramesResponse = {\n totalFrames: number;\n slowFrames: number;\n frozenFrames: number;\n};\n\nexport type NativeReleaseResponse = {\n build: string;\n id: string;\n version: string;\n};\n\n/**\n * This type describes serialized scope from sentry-cocoa and sentry-android\n * https://github.com/getsentry/sentry-cocoa/blob/master/Sources/Sentry/SentryScope.m\n * https://github.com/getsentry/sentry-java/blob/a461f7e125b65240004e6162b341f383ce2e1394/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java#L32\n */\nexport type NativeDeviceContextsResponse = {\n [key: string]: unknown;\n tags?: Record<string, string>;\n extra?: Record<string, unknown>;\n contexts?: Record<string, Record<string, unknown>>;\n user?: {\n userId?: string;\n email?: string;\n username?: string;\n ipAddress?: string;\n segment?: string;\n data?: Record<string, unknown>;\n };\n dist?: string;\n environment?: string;\n fingerprint?: string[];\n level?: string;\n breadcrumbs?: {\n level?: string;\n timestamp?: string;\n category?: string;\n type?: string;\n message?: string;\n data?: Record<string, unknown>;\n }[];\n};\n\nexport type NativeScreenshot = {\n data: number[];\n contentType: string;\n filename: string;\n};\n\n// The export must be here to pass codegen even if not used\nexport default TurboModuleRegistry.getEnforcing<Spec>('RNSentry');\n"]}
@@ -35,6 +35,10 @@ export declare class ReactNativeClient extends BaseClient<ReactNativeClientOptio
35
35
  * Sends user feedback to Sentry.
36
36
  */
37
37
  captureUserFeedback(feedback: UserFeedback): void;
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ init(): void;
38
42
  /**
39
43
  * Sets up the integrations
40
44
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/js/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAGV,QAAQ,EACR,KAAK,EACL,SAAS,EAGT,aAAa,EAEb,YAAY,EACb,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAO1D;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,wBAAwB,CAAC;IACzE,OAAO,CAAC,eAAe,CAAY;IAEnC;;;OAGG;gBACgB,OAAO,EAAE,wBAAwB;IAUpD;;OAEG;IACI,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,GAAE,SAAc,GAAG,WAAW,CAAC,KAAK,CAAC;IAIvF;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC;IAmBrG;;;OAGG;IACI,WAAW,IAAI,IAAI;IAI1B;;OAEG;IACI,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC;IAOpC;;OAEG;IACI,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IASxD;;OAEG;IACH,SAAS,CAAC,kBAAkB,IAAI,IAAI;IAapC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA+BjD;;OAEG;IACH,OAAO,CAAC,cAAc;IAmBtB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAShC;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAa9B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/js/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAGV,QAAQ,EACR,KAAK,EACL,SAAS,EAGT,aAAa,EAEb,YAAY,EACb,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAS1D;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,wBAAwB,CAAC;IACzE,OAAO,CAAC,eAAe,CAAY;IAEnC;;;OAGG;gBACgB,OAAO,EAAE,wBAAwB;IASpD;;OAEG;IACI,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,GAAE,SAAc,GAAG,WAAW,CAAC,KAAK,CAAC;IAIvF;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC;IAmBrG;;;OAGG;IACI,WAAW,IAAI,IAAI;IAI1B;;OAEG;IACI,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC;IAOpC;;OAEG;IACI,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IASxD;;OAEG;IACI,IAAI,IAAI,IAAI;IAKnB;;OAEG;IACH,SAAS,CAAC,kBAAkB,IAAI,IAAI;IAapC;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA+BjD;;OAEG;IACH,OAAO,CAAC,cAAc;IA0BtB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAShC;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAa9B"}
package/dist/js/client.js CHANGED
@@ -4,6 +4,7 @@ import { dateTimestampInSeconds, logger, SentryError } from '@sentry/utils';
4
4
  import { Alert } from 'react-native';
5
5
  import { createIntegration } from './integrations/factory';
6
6
  import { defaultSdkInfo } from './integrations/sdkinfo';
7
+ import { MOBILE_REPLAY_INTEGRATION_NAME } from './replay/mobilereplay';
7
8
  import { ReactNativeTracing } from './tracing';
8
9
  import { createUserFeedbackEnvelope, items } from './utils/envelope';
9
10
  import { ignoreRequireCycleLogs } from './utils/ignorerequirecyclelogs';
@@ -26,7 +27,6 @@ export class ReactNativeClient extends BaseClient {
26
27
  options._metadata.sdk = options._metadata.sdk || defaultSdkInfo;
27
28
  super(options);
28
29
  this._outcomesBuffer = [];
29
- this._initNativeSdk();
30
30
  }
31
31
  /**
32
32
  * @inheritDoc
@@ -79,6 +79,13 @@ export class ReactNativeClient extends BaseClient {
79
79
  });
80
80
  this._sendEnvelope(envelope);
81
81
  }
82
+ /**
83
+ * @inheritDoc
84
+ */
85
+ init() {
86
+ super.init();
87
+ this._initNativeSdk();
88
+ }
82
89
  /**
83
90
  * Sets up the integrations
84
91
  */
@@ -130,7 +137,10 @@ export class ReactNativeClient extends BaseClient {
130
137
  * Starts native client with dsn and options
131
138
  */
132
139
  _initNativeSdk() {
133
- NATIVE.initNativeSdk(this._options)
140
+ NATIVE.initNativeSdk(Object.assign(Object.assign({}, this._options), { mobileReplayOptions: this._integrations[MOBILE_REPLAY_INTEGRATION_NAME] &&
141
+ 'options' in this._integrations[MOBILE_REPLAY_INTEGRATION_NAME]
142
+ ? this._integrations[MOBILE_REPLAY_INTEGRATION_NAME].options
143
+ : undefined }))
134
144
  .then((result) => {
135
145
  return result;
136
146
  }, () => {