noibu-react-native 0.2.35-rc.3 → 0.2.35-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,6 +71,7 @@ That's it! First time the module is set up, it runs an init and starts listening
71
71
  - `@property domain {string}` - indicates which Noibu dashboard session recordings should go to ([learn more about domains](https://help.noibu.com/hc/en-us/articles/4846518088845-Domains-Overview))
72
72
  - `@property [blockedElements] {string[]}` - defaults see below; lets you specify component ids to be ignored by SDK when collecting error information
73
73
  - `@property [enableHttpDataCollection] {boolean}` - default `false`; indicates whether SDK should collect HTTP information like headers or body from requests
74
+ - `@property [enableWebViewCapture] {boolean}` - default `true`; indicates whether SDK should capture and record React Native WebView/WKWebView DOM content in session replay
74
75
  - `@property [listOfUrlsToCollectHttpDataFrom] {string[]}` - is an allowlist of URLs to allow HTTP data collection from, works best with `enableHttpDataCollection` enabled
75
76
  - `@property [httpPiiBlockingPatterns] {RegExp[]}` - defaults see below; allows you to specify RegEx patterns for what PII information should be removed from JSON request and response data for the value in a key value pair
76
77
  - `@property [fuzzyFieldsToRedact] {string[]}` - defaults see below; allows you to specify fuzzy strings for what PII information should be removed from JSON request and response data based on the key in a key value pair
@@ -87,6 +88,7 @@ Example:
87
88
  ```js
88
89
  setupNoibu({
89
90
  domain: 'react-native-app.myshop.com',
91
+ enableWebViewCapture: false,
90
92
  enableHttpDataCollection: true,
91
93
  listOfUrlsToCollectHttpDataFrom: ['https://react-native-app.myshop.com/backend', 'https://example.com/some-path/'],
92
94
  blockedElements: ['sensitive-info'],
@@ -66,5 +66,5 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
66
66
  dependencies {
67
67
  implementation "com.facebook.react:react-native:+"
68
68
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
69
- implementation "com.noibu:sessionreplay-recorder:1.0.5-rc.2"
69
+ implementation "com.noibu:sessionreplay-recorder:1.0.5-rc.3"
70
70
  }
@@ -15,6 +15,8 @@ import com.noibu.mobile.android.sessionreplay.NoibuConfig
15
15
  class NoibuSessionReplayModule(reactContext: ReactApplicationContext) :
16
16
  ReactContextBaseJavaModule(reactContext) {
17
17
 
18
+ private var enableWebViewCapture: Boolean = true
19
+
18
20
  init {
19
21
  NoibuSessionReplayModule.reactContext = reactContext
20
22
  }
@@ -41,6 +43,7 @@ class NoibuSessionReplayModule(reactContext: ReactApplicationContext) :
41
43
  val config = NoibuConfig(
42
44
  sessionReplayEnabled = true,
43
45
  maskAllTextInputs = false,
46
+ enableWebViewCapture = enableWebViewCapture,
44
47
  )
45
48
  Noibu.setup(context, config){ param ->
46
49
  val params = Arguments.createMap()
@@ -51,6 +54,11 @@ class NoibuSessionReplayModule(reactContext: ReactApplicationContext) :
51
54
  promise.resolve(true)
52
55
  }
53
56
 
57
+ @ReactMethod
58
+ fun setEnableWebViewCapture(enabled: Boolean) {
59
+ enableWebViewCapture = enabled
60
+ }
61
+
54
62
  @ReactMethod
55
63
  fun addListener(eventName: String) {
56
64
  // Set up any upstream listeners or background tasks as necessary
@@ -65,4 +73,4 @@ class NoibuSessionReplayModule(reactContext: ReactApplicationContext) :
65
73
  const val NAME = "NoibuSessionRecorder"
66
74
  private var reactContext: ReactApplicationContext? = null
67
75
  }
68
- }
76
+ }
@@ -18,6 +18,7 @@ class NoibuSessionRecorderModule(val reactContext: ReactApplicationContext) : Na
18
18
  }
19
19
 
20
20
  private val eventQueue: ConcurrentLinkedQueue<String> = ConcurrentLinkedQueue()
21
+ private var enableWebViewCapture: Boolean = true
21
22
 
22
23
  init {
23
24
  Log.i(TAG, "[new-arch] Module constructed")
@@ -25,6 +26,10 @@ class NoibuSessionRecorderModule(val reactContext: ReactApplicationContext) : Na
25
26
 
26
27
  override fun getName(): String = "NoibuSessionRecorder"
27
28
 
29
+ override fun setEnableWebViewCapture(enabled: Boolean) {
30
+ enableWebViewCapture = enabled
31
+ }
32
+
28
33
  override fun initialize(promise: Promise) {
29
34
  Log.i(TAG, "[new-arch] initialize() called")
30
35
  try {
@@ -32,6 +37,7 @@ class NoibuSessionRecorderModule(val reactContext: ReactApplicationContext) : Na
32
37
  val config = NoibuConfig(
33
38
  sessionReplayEnabled = true,
34
39
  maskAllTextInputs = false,
40
+ enableWebViewCapture = enableWebViewCapture,
35
41
  )
36
42
  Noibu.setup(context, config) { param ->
37
43
  // Enqueue raw mobile event JSON for JS to consume via TurboModule polling
package/dist/constants.js CHANGED
@@ -24,7 +24,7 @@ const CONTENT_TYPE = 'content-type';
24
24
  * Gets the script id from the cookie object, returns default if cannot be found
25
25
  */
26
26
  function GET_SCRIPT_ID() {
27
- return "1.0.104-rn-sdk-0.2.35-rc.3" ;
27
+ return "1.0.104-rn-sdk-0.2.35-rc.5" ;
28
28
  }
29
29
  /**
30
30
  * Gets the max metro recon number
@@ -42,7 +42,11 @@ const urlConfig = {
42
42
  /** initilializes the script to start executing all of NJS features */
43
43
  function globalInit(customerConfig) {
44
44
  return __awaiter(this, void 0, void 0, function* () {
45
+ var _a;
45
46
  noibuLog('global init started');
47
+ const sessionRecorderConfig = {
48
+ enableWebViewCapture: (_a = customerConfig.enableWebViewCapture) !== null && _a !== void 0 ? _a : true,
49
+ };
46
50
  // if the config url is invalid we block collect from executing
47
51
  if (isInvalidURLConfig(Object.assign(Object.assign({}, urlConfig), { domain: customerConfig.domain }))) {
48
52
  noibuLog('exiting');
@@ -81,7 +85,7 @@ function globalInit(customerConfig) {
81
85
  clickMonitor.monitor();
82
86
  keyboardInputMonitor.monitor();
83
87
  pageMonitor.monitor();
84
- SessionRecorder.getInstance().recordUserSession();
88
+ SessionRecorder.getInstance(sessionRecorderConfig).recordUserSession();
85
89
  // Initialize HTTP data collection and request monitoring if enabled
86
90
  // This is done after other monitors so failures here don't affect session recording
87
91
  if (ClientConfig.getInstance().enableHttpDataCollection) {
@@ -1,5 +1,6 @@
1
1
  import type { TurboModule } from 'react-native';
2
2
  export interface Spec extends TurboModule {
3
+ setEnableWebViewCapture(enabled: boolean): void;
3
4
  initialize(): Promise<boolean>;
4
5
  consumeEvents?(): Promise<string[]>;
5
6
  }
@@ -1,4 +1,4 @@
1
- import { RecorderEvent } from './nativeSessionRecorderSubscription';
1
+ import { RecorderEvent, SessionRecorderConfig } from './nativeSessionRecorderSubscription';
2
2
  import { Singleton } from '../monitors/BaseMonitor';
3
3
  /** Singleton class to record user sessions */
4
4
  export default class SessionRecorder extends Singleton {
@@ -13,7 +13,7 @@ export default class SessionRecorder extends Singleton {
13
13
  private recordStopper;
14
14
  private freezingEvents;
15
15
  /** Setups the SessionRecorder instance for usage */
16
- constructor();
16
+ constructor(config?: SessionRecorderConfig);
17
17
  /** Sets up the page hide handler to try to push remaining video events */
18
18
  setupUnloadHandler(): void;
19
19
  /** Sets up the post metrics handler to potentially log a debug message */
@@ -17,7 +17,7 @@ const MAX_RECORDER_EVENT_BUFFER = 10;
17
17
  /** Singleton class to record user sessions */
18
18
  class SessionRecorder extends Singleton {
19
19
  /** Setups the SessionRecorder instance for usage */
20
- constructor() {
20
+ constructor(config = {}) {
21
21
  super();
22
22
  this.eventBuffer = [];
23
23
  this.vfCounter = 0;
@@ -31,7 +31,7 @@ class SessionRecorder extends Singleton {
31
31
  this.freezingEvents = false;
32
32
  this.setupUnloadHandler();
33
33
  this.setupPostMetricsHandler();
34
- initialize();
34
+ initialize(config);
35
35
  addSafeEventListener(window, 'click', () => this.handleFragPost());
36
36
  }
37
37
  /** Sets up the page hide handler to try to push remaining video events */
@@ -24,19 +24,13 @@ export declare enum LogLevel {
24
24
  * @param maximumDailyNetworkUsageInMB [OPTIONAL default = null] Maximum daily network usage for Noibu - Session recorder (null = No limit). When the limit is reached, Noibu - Session recorder will turn on lean mode.
25
25
  */
26
26
  export interface SessionRecorderConfig {
27
- userId?: string | null;
28
- logLevel?: LogLevel;
29
- allowMeteredNetworkUsage?: boolean;
30
27
  enableWebViewCapture?: boolean;
31
- allowedDomains?: string[];
32
- disableOnLowEndDevices?: boolean;
33
- maximumDailyNetworkUsageInMB?: number;
34
28
  }
35
29
  /**
36
30
  * Initializes the Noibu - Session recording SDK if the API level is supported.
37
31
  * Supports both legacy (bridge) and new architecture (TurboModule) on iOS and Android.
38
32
  */
39
- export declare function initialize(): void;
33
+ export declare function initialize(config?: SessionRecorderConfig): void;
40
34
  export type RecorderEvent = import('./types').RecorderEvent;
41
35
  export type UnsubscribeFn = import('./types').UnsubscribeFn;
42
36
  /**
@@ -12,9 +12,9 @@ const RNModule = (_a = NativeModules.NoibuSessionRecorder) !== null && _a !== vo
12
12
  const NativeSessionRecorder = TurboNativeSessionRecorder !== null && TurboNativeSessionRecorder !== void 0 ? TurboNativeSessionRecorder : RNModule;
13
13
  // Consider new-arch if the resolved module exposes the polling method
14
14
  const isNewArch = typeof (NativeSessionRecorder === null || NativeSessionRecorder === void 0 ? void 0 : NativeSessionRecorder.consumeEvents) === 'function';
15
- const isNewArchIOS = Platform.OS === 'ios' && isNewArch;
16
15
  let nativeModuleEmitter;
17
16
  const SupportedPlatforms = ['android', 'ios'];
17
+ const DEFAULT_ENABLE_WEBVIEW_CAPTURE = true;
18
18
  /** The level of logging to show in the device logcat stream. */
19
19
  // eslint-disable-next-line no-shadow
20
20
  var LogLevel;
@@ -26,15 +26,19 @@ var LogLevel;
26
26
  LogLevel["Error"] = "Error";
27
27
  LogLevel["None"] = "None";
28
28
  })(LogLevel || (LogLevel = {}));
29
+ let sessionRecorderConfig = {
30
+ enableWebViewCapture: DEFAULT_ENABLE_WEBVIEW_CAPTURE,
31
+ };
32
+ function resolveEnableWebViewCapture(config = sessionRecorderConfig) {
33
+ var _a;
34
+ return (_a = config.enableWebViewCapture) !== null && _a !== void 0 ? _a : DEFAULT_ENABLE_WEBVIEW_CAPTURE;
35
+ }
29
36
  /**
30
37
  * Initializes the Noibu - Session recording SDK if the API level is supported.
31
38
  * Supports both legacy (bridge) and new architecture (TurboModule) on iOS and Android.
32
39
  */
33
- function initialize() {
34
- if (Platform.OS === 'ios' && isNewArchIOS) {
35
- // New architecture iOS: initialize native module to start capturing
36
- NativeSessionRecorder.initialize();
37
- }
40
+ function initialize(config = {}) {
41
+ sessionRecorderConfig = Object.assign(Object.assign(Object.assign({}, sessionRecorderConfig), config), { enableWebViewCapture: resolveEnableWebViewCapture(config) });
38
42
  if (!SupportedPlatforms.includes(Platform.OS)) {
39
43
  noibuLog(`Noibu - Session recording supports ${SupportedPlatforms.join(', ')} only for now.`);
40
44
  return;
@@ -53,6 +57,9 @@ function initialize() {
53
57
  }
54
58
  nativeModuleEmitter = new NativeEventEmitter(moduleForEmitter);
55
59
  }
60
+ if (typeof NativeSessionRecorder.setEnableWebViewCapture === 'function') {
61
+ NativeSessionRecorder.setEnableWebViewCapture(resolveEnableWebViewCapture());
62
+ }
56
63
  // Call native initialize only when the method is exposed (new-arch and legacy Android; legacy iOS bridge does not export it)
57
64
  if (typeof NativeSessionRecorder.initialize === 'function') {
58
65
  NativeSessionRecorder.initialize();
@@ -154,7 +161,7 @@ function subscribeToNativeEvent(callback) {
154
161
  };
155
162
  nativeModuleEmitter.addListener('noibuRecordingEvent', handleLegacyPayload);
156
163
  if (Platform.OS === 'ios' && !isIOSInitialized) {
157
- (_a = RNModule === null || RNModule === void 0 ? void 0 : RNModule.startIOS) === null || _a === void 0 ? void 0 : _a.call(RNModule);
164
+ (_a = RNModule === null || RNModule === void 0 ? void 0 : RNModule.startIOS) === null || _a === void 0 ? void 0 : _a.call(RNModule, resolveEnableWebViewCapture());
158
165
  isIOSInitialized = true;
159
166
  }
160
167
  // return () => subscription?.remove();
@@ -2,5 +2,6 @@
2
2
  #import <React/RCTEventEmitter.h>
3
3
 
4
4
  @interface RCT_EXTERN_MODULE(NoibuSessionRecorder, RCTEventEmitter)
5
- RCT_EXTERN_METHOD(startIOS)
6
- @end
5
+ RCT_EXTERN_METHOD(setEnableWebViewCapture:(BOOL)enabled)
6
+ RCT_EXTERN_METHOD(startIOS:(BOOL)webViewCaptureEnabled)
7
+ @end
@@ -6,6 +6,7 @@ import NoibuSDK
6
6
  class NoibuSessionRecorder: RCTEventEmitter {
7
7
 
8
8
  private var hasListeners = false
9
+ private var enableWebViewCapture = true
9
10
 
10
11
  override init() {
11
12
  super.init()
@@ -27,11 +28,17 @@ class NoibuSessionRecorder: RCTEventEmitter {
27
28
  hasListeners = false
28
29
  }
29
30
 
30
- @objc func startIOS() {
31
+ @objc func setEnableWebViewCapture(_ enabled: Bool) {
32
+ enableWebViewCapture = enabled
33
+ }
34
+
35
+ @objc func startIOS(_ webViewCaptureEnabled: Bool) {
36
+ enableWebViewCapture = webViewCaptureEnabled
31
37
  let NOIBU_API_KEY = "NOIBU_API_KEY"
32
38
  let NOIBU_HOST = "https://noibu.com/"
33
39
 
34
40
  let config = NoibuConfig(apiKey: NOIBU_API_KEY, host: NOIBU_HOST)
41
+ config.sessionReplayConfig.enableWebViewCapture = enableWebViewCapture
35
42
  // config.debug = true // Enable debug logging to see emitted events
36
43
 
37
44
  config.onReactNativeCallback = { [weak self] mobileEvents in
@@ -15,11 +15,22 @@
15
15
  @end
16
16
 
17
17
  @implementation RCTNoibuSessionRecorder
18
+ {
19
+ BOOL _enableWebViewCapture;
20
+ }
18
21
 
19
22
  RCT_EXPORT_MODULE(NoibuSessionRecorder)
20
23
 
21
24
  + (BOOL)requiresMainQueueSetup { return NO; }
22
25
 
26
+ - (instancetype)init
27
+ {
28
+ if ((self = [super init])) {
29
+ _enableWebViewCapture = YES;
30
+ }
31
+ return self;
32
+ }
33
+
23
34
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
24
35
  (const facebook::react::ObjCTurboModule::InitParams &)params
25
36
  {
@@ -60,6 +71,11 @@ static NSArray<NSString *> *drain_queue(NSUInteger maxCount) {
60
71
  return result ?: @[];
61
72
  }
62
73
 
74
+ - (void)setEnableWebViewCapture:(BOOL)enabled
75
+ {
76
+ _enableWebViewCapture = enabled;
77
+ }
78
+
63
79
  - (void)initialize:(RCTPromiseResolveBlock)resolve
64
80
  reject:(RCTPromiseRejectBlock)reject
65
81
  {
@@ -74,6 +90,7 @@ static NSArray<NSString *> *drain_queue(NSUInteger maxCount) {
74
90
  NoibuConfig *config = [[NoibuConfig alloc] apiKey:apiKey host:host];
75
91
  // Enable session replay by default, leave other options as defaults
76
92
  // Bridge callback to enqueue raw mobile events for JS polling
93
+ config.sessionReplayConfig.enableWebViewCapture = _enableWebViewCapture;
77
94
 
78
95
  config.onReactNativeCallback = ^(NSArray<NSDictionary *> *mobileEvents) {
79
96
  for (id item in mobileEvents) {
@@ -37,7 +37,7 @@ Pod::Spec.new do |s|
37
37
  #s.vendored_frameworks = "ios/SessionRecorder.xcframework"
38
38
  #s.vendored_frameworks = "ios/Noibu.xcframework"
39
39
 
40
- s.dependency 'NoibuSDK', '0.0.13'
40
+ s.dependency 'NoibuSDK', '0.0.14'
41
41
  s.pod_target_xcconfig = {
42
42
  "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/noibu-react-native/ios/**\""
43
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noibu-react-native",
3
- "version": "0.2.35-rc.3",
3
+ "version": "0.2.35-rc.5",
4
4
  "targetNjsVersion": "1.0.104",
5
5
  "description": "React-Native SDK for NoibuJS to collect errors in React-Native applications",
6
6
  "main": "dist/entry/index.js",
@@ -2,9 +2,10 @@ import type {TurboModule} from 'react-native';
2
2
  import {TurboModuleRegistry} from 'react-native';
3
3
 
4
4
  export interface Spec extends TurboModule {
5
+ setEnableWebViewCapture(enabled: boolean): void;
5
6
  initialize(): Promise<boolean>;
6
7
  // Returns an array of raw mobile event JSON strings and clears native queue
7
8
  consumeEvents?(): Promise<string[]>;
8
9
  }
9
10
 
10
- export default TurboModuleRegistry.get<Spec>('NoibuSessionRecorder');
11
+ export default TurboModuleRegistry.get<Spec>('NoibuSessionRecorder');