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 +2 -0
- package/android/build.gradle +1 -1
- package/android/src/legacy/java/com/noibu/sessionreplay/reactnative/NoibuSessionReplayModule.kt +9 -1
- package/android/src/newarch/java/com/noibu/sessionreplay/reactnative/NoibuSessionRecorderModule.kt +6 -0
- package/dist/constants.js +1 -1
- package/dist/entry/init.js +5 -1
- package/dist/native/NativeNoibuSessionRecorder.d.ts +1 -0
- package/dist/sessionRecorder/SessionRecorder.d.ts +2 -2
- package/dist/sessionRecorder/SessionRecorder.js +2 -2
- package/dist/sessionRecorder/nativeSessionRecorderSubscription.d.ts +1 -7
- package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +14 -7
- package/ios/IOSPocEmitter.m +3 -2
- package/ios/IOSPocEmitter.swift +8 -1
- package/ios/RCTNoibuSessionRecorder.mm +17 -0
- package/noibu-react-native.podspec +1 -1
- package/package.json +1 -1
- package/specs/NativeSessionRecorder.ts +2 -1
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'],
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
69
|
+
implementation "com.noibu:sessionreplay-recorder:1.0.5-rc.3"
|
|
70
70
|
}
|
package/android/src/legacy/java/com/noibu/sessionreplay/reactnative/NoibuSessionReplayModule.kt
CHANGED
|
@@ -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
|
+
}
|
package/android/src/newarch/java/com/noibu/sessionreplay/reactnative/NoibuSessionRecorderModule.kt
CHANGED
|
@@ -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.
|
|
27
|
+
return "1.0.104-rn-sdk-0.2.35-rc.5" ;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Gets the max metro recon number
|
package/dist/entry/init.js
CHANGED
|
@@ -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,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
|
-
|
|
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();
|
package/ios/IOSPocEmitter.m
CHANGED
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
#import <React/RCTEventEmitter.h>
|
|
3
3
|
|
|
4
4
|
@interface RCT_EXTERN_MODULE(NoibuSessionRecorder, RCTEventEmitter)
|
|
5
|
-
RCT_EXTERN_METHOD(
|
|
6
|
-
|
|
5
|
+
RCT_EXTERN_METHOD(setEnableWebViewCapture:(BOOL)enabled)
|
|
6
|
+
RCT_EXTERN_METHOD(startIOS:(BOOL)webViewCaptureEnabled)
|
|
7
|
+
@end
|
package/ios/IOSPocEmitter.swift
CHANGED
|
@@ -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
|
|
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.
|
|
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
|
@@ -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');
|