@rejourneyco/react-native 1.0.0 → 1.0.2
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 +29 -0
- package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +47 -30
- package/android/src/main/java/com/rejourney/capture/CaptureEngine.kt +25 -1
- package/android/src/main/java/com/rejourney/capture/CaptureHeuristics.kt +70 -32
- package/android/src/main/java/com/rejourney/core/Constants.kt +4 -4
- package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +14 -0
- package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +9 -0
- package/ios/Capture/RJCaptureEngine.m +72 -34
- package/ios/Capture/RJCaptureHeuristics.h +7 -5
- package/ios/Capture/RJCaptureHeuristics.m +138 -112
- package/ios/Capture/RJVideoEncoder.m +0 -26
- package/ios/Core/Rejourney.mm +64 -102
- package/ios/Utils/RJPerfTiming.m +0 -5
- package/ios/Utils/RJWindowUtils.m +0 -1
- package/lib/commonjs/components/Mask.js +1 -6
- package/lib/commonjs/index.js +12 -101
- package/lib/commonjs/sdk/autoTracking.js +55 -353
- package/lib/commonjs/sdk/constants.js +2 -13
- package/lib/commonjs/sdk/errorTracking.js +1 -29
- package/lib/commonjs/sdk/metricsTracking.js +3 -24
- package/lib/commonjs/sdk/navigation.js +3 -42
- package/lib/commonjs/sdk/networkInterceptor.js +7 -49
- package/lib/commonjs/sdk/utils.js +0 -5
- package/lib/module/components/Mask.js +1 -6
- package/lib/module/index.js +11 -105
- package/lib/module/sdk/autoTracking.js +55 -354
- package/lib/module/sdk/constants.js +2 -13
- package/lib/module/sdk/errorTracking.js +1 -29
- package/lib/module/sdk/index.js +0 -2
- package/lib/module/sdk/metricsTracking.js +3 -24
- package/lib/module/sdk/navigation.js +3 -42
- package/lib/module/sdk/networkInterceptor.js +7 -49
- package/lib/module/sdk/utils.js +0 -5
- package/lib/typescript/NativeRejourney.d.ts +2 -0
- package/lib/typescript/sdk/autoTracking.d.ts +5 -6
- package/lib/typescript/types/index.d.ts +0 -1
- package/package.json +11 -3
- package/src/NativeRejourney.ts +4 -0
- package/src/components/Mask.tsx +0 -3
- package/src/index.ts +11 -88
- package/src/sdk/autoTracking.ts +72 -331
- package/src/sdk/constants.ts +13 -13
- package/src/sdk/errorTracking.ts +1 -17
- package/src/sdk/index.ts +0 -2
- package/src/sdk/metricsTracking.ts +5 -33
- package/src/sdk/navigation.ts +8 -29
- package/src/sdk/networkInterceptor.ts +9 -33
- package/src/sdk/utils.ts +0 -5
- package/src/types/index.ts +0 -29
package/lib/commonjs/index.js
CHANGED
|
@@ -175,13 +175,10 @@ function getReactNative() {
|
|
|
175
175
|
return null;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
-
|
|
179
|
-
// Lazy-loaded logger
|
|
180
178
|
let _logger = null;
|
|
181
179
|
function getLogger() {
|
|
182
180
|
if (_logger) return _logger;
|
|
183
181
|
if (_sdkDisabled) {
|
|
184
|
-
// Return a no-op logger if SDK is disabled
|
|
185
182
|
return {
|
|
186
183
|
debug: () => {},
|
|
187
184
|
info: console.log.bind(console, '[Rejourney]'),
|
|
@@ -260,7 +257,7 @@ const noopAutoTracking = {
|
|
|
260
257
|
notifyStateChange: () => {},
|
|
261
258
|
getSessionMetrics: () => ({}),
|
|
262
259
|
resetMetrics: () => {},
|
|
263
|
-
collectDeviceInfo: () => ({}),
|
|
260
|
+
collectDeviceInfo: async () => ({}),
|
|
264
261
|
ensurePersistentAnonymousId: async () => 'anonymous'
|
|
265
262
|
};
|
|
266
263
|
function getAutoTracking() {
|
|
@@ -276,7 +273,6 @@ function getAutoTracking() {
|
|
|
276
273
|
}
|
|
277
274
|
|
|
278
275
|
// State
|
|
279
|
-
const USER_IDENTITY_KEY = '@rejourney_user_identity';
|
|
280
276
|
let _isInitialized = false;
|
|
281
277
|
let _isRecording = false;
|
|
282
278
|
let _initializationFailed = false;
|
|
@@ -291,23 +287,18 @@ let _lastScrollOffset = 0;
|
|
|
291
287
|
const SCROLL_THROTTLE_MS = 100;
|
|
292
288
|
|
|
293
289
|
// Helper to save/load user identity
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if (identity) {
|
|
298
|
-
await AsyncStorage.setItem(USER_IDENTITY_KEY, identity);
|
|
299
|
-
} else {
|
|
300
|
-
await AsyncStorage.removeItem(USER_IDENTITY_KEY);
|
|
301
|
-
}
|
|
302
|
-
} catch (e) {
|
|
303
|
-
// Ignore storage errors
|
|
304
|
-
}
|
|
290
|
+
// NOW HANDLED NATIVELY - No-op on JS side to avoid unnecessary bridge calls
|
|
291
|
+
async function persistUserIdentity(_identity) {
|
|
292
|
+
// Native module handles persistence automatically in setUserIdentity
|
|
305
293
|
}
|
|
306
294
|
async function loadPersistedUserIdentity() {
|
|
307
295
|
try {
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
296
|
+
const nativeModule = getRejourneyNative();
|
|
297
|
+
if (!nativeModule) return null;
|
|
298
|
+
|
|
299
|
+
// NATIVE STORAGE: Read directly from SharedPreferences/NSUserDefaults
|
|
300
|
+
return await nativeModule.getUserIdentity();
|
|
301
|
+
} catch {
|
|
311
302
|
return null;
|
|
312
303
|
}
|
|
313
304
|
}
|
|
@@ -327,9 +318,7 @@ let _runtimeReady = false;
|
|
|
327
318
|
function isRuntimeReady() {
|
|
328
319
|
if (_runtimeReady) return true;
|
|
329
320
|
try {
|
|
330
|
-
// Try to access a core module to verify runtime is ready
|
|
331
321
|
const RN = require('react-native');
|
|
332
|
-
// If we can access NativeModules without error, runtime is ready
|
|
333
322
|
if (RN.NativeModules) {
|
|
334
323
|
_runtimeReady = true;
|
|
335
324
|
return true;
|
|
@@ -412,12 +401,9 @@ function getRejourneyNative() {
|
|
|
412
401
|
}
|
|
413
402
|
}
|
|
414
403
|
} catch (error) {
|
|
415
|
-
// If any access fails, log and return null
|
|
416
404
|
getLogger().warn('Rejourney: Failed to access native modules:', error);
|
|
417
405
|
_rejourneyNative = null;
|
|
418
406
|
}
|
|
419
|
-
|
|
420
|
-
// Ensure we never return undefined - convert to null
|
|
421
407
|
if (_rejourneyNative === undefined) {
|
|
422
408
|
_rejourneyNative = null;
|
|
423
409
|
}
|
|
@@ -559,7 +545,7 @@ const Rejourney = {
|
|
|
559
545
|
// Collect and log device info
|
|
560
546
|
if (_storedConfig?.collectDeviceInfo !== false) {
|
|
561
547
|
try {
|
|
562
|
-
const deviceInfo = getAutoTracking().collectDeviceInfo();
|
|
548
|
+
const deviceInfo = await getAutoTracking().collectDeviceInfo();
|
|
563
549
|
this.logEvent('device_info', deviceInfo);
|
|
564
550
|
} catch (deviceError) {
|
|
565
551
|
getLogger().warn('Failed to collect device info:', deviceError);
|
|
@@ -577,15 +563,10 @@ const Rejourney = {
|
|
|
577
563
|
ignoreUrls,
|
|
578
564
|
captureSizes: _storedConfig?.networkCaptureSizes !== false
|
|
579
565
|
});
|
|
580
|
-
|
|
581
|
-
// logger.debug('Network interception enabled');
|
|
582
566
|
} catch (networkError) {
|
|
583
567
|
getLogger().warn('Failed to setup network interception:', networkError);
|
|
584
568
|
}
|
|
585
569
|
}
|
|
586
|
-
|
|
587
|
-
// logger.debug('Auto tracking enabled');
|
|
588
|
-
|
|
589
570
|
return true;
|
|
590
571
|
} catch (error) {
|
|
591
572
|
getLogger().error('Failed to start recording:', error);
|
|
@@ -602,17 +583,13 @@ const Rejourney = {
|
|
|
602
583
|
return;
|
|
603
584
|
}
|
|
604
585
|
try {
|
|
605
|
-
// Get session metrics before stopping
|
|
606
586
|
const metrics = getAutoTracking().getSessionMetrics();
|
|
607
587
|
this.logEvent('session_metrics', metrics);
|
|
608
|
-
|
|
609
|
-
// Cleanup
|
|
610
588
|
getNetworkInterceptor().disableNetworkInterceptor();
|
|
611
589
|
getAutoTracking().cleanupAutoTracking();
|
|
612
590
|
getAutoTracking().resetMetrics();
|
|
613
591
|
await safeNativeCall('stopSession', () => getRejourneyNative().stopSession(), undefined);
|
|
614
592
|
_isRecording = false;
|
|
615
|
-
// Use lifecycle log for session end - only shown in dev builds
|
|
616
593
|
getLogger().logSessionEnd('current');
|
|
617
594
|
} catch (error) {
|
|
618
595
|
getLogger().error('Failed to stop recording:', error);
|
|
@@ -644,9 +621,6 @@ const Rejourney = {
|
|
|
644
621
|
setUserIdentity(userId) {
|
|
645
622
|
_userIdentity = userId;
|
|
646
623
|
persistUserIdentity(userId).catch(() => {});
|
|
647
|
-
// logger.debug(`User identity set: ${userId}`);
|
|
648
|
-
|
|
649
|
-
// If recording is active, update the native module immediately
|
|
650
624
|
if (_isRecording && getRejourneyNative()) {
|
|
651
625
|
safeNativeCallSync('setUserIdentity', () => {
|
|
652
626
|
getRejourneyNative().setUserIdentity(userId).catch(() => {});
|
|
@@ -660,9 +634,6 @@ const Rejourney = {
|
|
|
660
634
|
clearUserIdentity() {
|
|
661
635
|
_userIdentity = null;
|
|
662
636
|
persistUserIdentity(null).catch(() => {});
|
|
663
|
-
// logger.debug('User identity cleared');
|
|
664
|
-
|
|
665
|
-
// If recording is active, update the native module immediately
|
|
666
637
|
if (_isRecording && getRejourneyNative()) {
|
|
667
638
|
safeNativeCallSync('setUserIdentity', () => {
|
|
668
639
|
getRejourneyNative().setUserIdentity('anonymous').catch(() => {});
|
|
@@ -676,10 +647,7 @@ const Rejourney = {
|
|
|
676
647
|
* @param params - Optional screen parameters
|
|
677
648
|
*/
|
|
678
649
|
tagScreen(screenName, _params) {
|
|
679
|
-
// Track screen for metrics and funnel tracking
|
|
680
650
|
getAutoTracking().trackScreen(screenName);
|
|
681
|
-
|
|
682
|
-
// Notify state change (kept for API compatibility)
|
|
683
651
|
getAutoTracking().notifyStateChange();
|
|
684
652
|
safeNativeCallSync('tagScreen', () => {
|
|
685
653
|
getRejourneyNative().screenChanged(screenName).catch(() => {});
|
|
@@ -857,10 +825,6 @@ const Rejourney = {
|
|
|
857
825
|
getAutoTracking().trackScroll();
|
|
858
826
|
await safeNativeCall('onScroll', () => getRejourneyNative().onScroll(scrollOffset), undefined);
|
|
859
827
|
},
|
|
860
|
-
// ========================================================================
|
|
861
|
-
// OAuth / External URL Tracking
|
|
862
|
-
// ========================================================================
|
|
863
|
-
|
|
864
828
|
/**
|
|
865
829
|
* Notify the SDK that an OAuth flow is starting
|
|
866
830
|
*
|
|
@@ -996,10 +960,6 @@ const Rejourney = {
|
|
|
996
960
|
getRejourneyNative().logEvent('network_request', networkEvent).catch(() => {});
|
|
997
961
|
}, undefined);
|
|
998
962
|
},
|
|
999
|
-
// ========================================================================
|
|
1000
|
-
// SDK Telemetry / Observability
|
|
1001
|
-
// ========================================================================
|
|
1002
|
-
|
|
1003
963
|
/**
|
|
1004
964
|
* Get SDK telemetry metrics for observability
|
|
1005
965
|
*
|
|
@@ -1047,10 +1007,6 @@ const Rejourney = {
|
|
|
1047
1007
|
getLogger().warn('debugTriggerANR is only available in development mode');
|
|
1048
1008
|
}
|
|
1049
1009
|
},
|
|
1050
|
-
// ========================================================================
|
|
1051
|
-
// Privacy / View Masking
|
|
1052
|
-
// ========================================================================
|
|
1053
|
-
|
|
1054
1010
|
/**
|
|
1055
1011
|
* Mask a view by its nativeID prop (will be occluded in recordings)
|
|
1056
1012
|
*
|
|
@@ -1086,10 +1042,6 @@ const Rejourney = {
|
|
|
1086
1042
|
}
|
|
1087
1043
|
};
|
|
1088
1044
|
|
|
1089
|
-
// =============================================================================
|
|
1090
|
-
// Automatic Lifecycle Management
|
|
1091
|
-
// =============================================================================
|
|
1092
|
-
|
|
1093
1045
|
/**
|
|
1094
1046
|
* Handle app state changes for automatic session management
|
|
1095
1047
|
* - Pauses recording when app goes to background
|
|
@@ -1120,20 +1072,13 @@ function setupLifecycleManagement() {
|
|
|
1120
1072
|
if (_sdkDisabled) return;
|
|
1121
1073
|
const RN = getReactNative();
|
|
1122
1074
|
if (!RN) return;
|
|
1123
|
-
|
|
1124
|
-
// Remove any existing subscription
|
|
1125
1075
|
if (_appStateSubscription) {
|
|
1126
1076
|
_appStateSubscription.remove();
|
|
1127
1077
|
_appStateSubscription = null;
|
|
1128
1078
|
}
|
|
1129
1079
|
try {
|
|
1130
|
-
// Get current app state
|
|
1131
1080
|
_currentAppState = RN.AppState.currentState || 'active';
|
|
1132
|
-
|
|
1133
|
-
// Subscribe to app state changes
|
|
1134
1081
|
_appStateSubscription = RN.AppState.addEventListener('change', handleAppStateChange);
|
|
1135
|
-
|
|
1136
|
-
// Setup auth error listener from native module
|
|
1137
1082
|
setupAuthErrorListener();
|
|
1138
1083
|
getLogger().debug('Lifecycle management enabled');
|
|
1139
1084
|
} catch (error) {
|
|
@@ -1156,9 +1101,6 @@ function setupAuthErrorListener() {
|
|
|
1156
1101
|
try {
|
|
1157
1102
|
const nativeModule = getRejourneyNative();
|
|
1158
1103
|
if (nativeModule) {
|
|
1159
|
-
// RN warns if a non-null module is passed without addListener/removeListeners.
|
|
1160
|
-
// Our native module may not implement these no-op methods yet, so only pass
|
|
1161
|
-
// the module when those hooks exist; otherwise use the global emitter.
|
|
1162
1104
|
const maybeAny = nativeModule;
|
|
1163
1105
|
const hasEventEmitterHooks = typeof maybeAny?.addListener === 'function' && typeof maybeAny?.removeListeners === 'function';
|
|
1164
1106
|
const eventEmitter = hasEventEmitterHooks ? new RN.NativeEventEmitter(maybeAny) : new RN.NativeEventEmitter();
|
|
@@ -1169,11 +1111,7 @@ function setupAuthErrorListener() {
|
|
|
1169
1111
|
} else if (error?.code === 404) {
|
|
1170
1112
|
getLogger().logInvalidProjectKey();
|
|
1171
1113
|
}
|
|
1172
|
-
|
|
1173
|
-
// Update SDK state - recording has been stopped by native
|
|
1174
1114
|
_isRecording = false;
|
|
1175
|
-
|
|
1176
|
-
// Call user's error handler if provided
|
|
1177
1115
|
if (_storedConfig?.onAuthError) {
|
|
1178
1116
|
try {
|
|
1179
1117
|
_storedConfig.onAuthError(error);
|
|
@@ -1184,7 +1122,6 @@ function setupAuthErrorListener() {
|
|
|
1184
1122
|
});
|
|
1185
1123
|
}
|
|
1186
1124
|
} catch (error) {
|
|
1187
|
-
// Event emitter not available on this platform - that's OK
|
|
1188
1125
|
getLogger().debug('Auth error listener not available:', error);
|
|
1189
1126
|
}
|
|
1190
1127
|
}
|
|
@@ -1203,10 +1140,6 @@ function cleanupLifecycleManagement() {
|
|
|
1203
1140
|
}
|
|
1204
1141
|
}
|
|
1205
1142
|
|
|
1206
|
-
// =============================================================================
|
|
1207
|
-
// Simple Initialization API
|
|
1208
|
-
// =============================================================================
|
|
1209
|
-
|
|
1210
1143
|
/**
|
|
1211
1144
|
* Initialize Rejourney SDK - STEP 1 of 3
|
|
1212
1145
|
*
|
|
@@ -1236,14 +1169,11 @@ function cleanupLifecycleManagement() {
|
|
|
1236
1169
|
* ```
|
|
1237
1170
|
*/
|
|
1238
1171
|
function initRejourney(publicRouteKey, options) {
|
|
1239
|
-
// Validate public route key
|
|
1240
1172
|
if (!publicRouteKey || typeof publicRouteKey !== 'string') {
|
|
1241
1173
|
getLogger().warn('Rejourney: Invalid public route key provided. SDK will be disabled.');
|
|
1242
1174
|
_initializationFailed = true;
|
|
1243
1175
|
return;
|
|
1244
1176
|
}
|
|
1245
|
-
|
|
1246
|
-
// Store config for later use
|
|
1247
1177
|
_storedConfig = {
|
|
1248
1178
|
...options,
|
|
1249
1179
|
publicRouteKey
|
|
@@ -1297,8 +1227,6 @@ function startRejourney() {
|
|
|
1297
1227
|
}
|
|
1298
1228
|
getLogger().logRecordingStart();
|
|
1299
1229
|
getLogger().debug('Starting session...');
|
|
1300
|
-
|
|
1301
|
-
// Fire and forget - don't block the caller
|
|
1302
1230
|
(async () => {
|
|
1303
1231
|
try {
|
|
1304
1232
|
const started = await Rejourney._startSession();
|
|
@@ -1329,12 +1257,7 @@ function stopRejourney() {
|
|
|
1329
1257
|
getLogger().warn('Error stopping Rejourney:', error);
|
|
1330
1258
|
}
|
|
1331
1259
|
}
|
|
1332
|
-
var _default = exports.default = Rejourney;
|
|
1333
|
-
// Export auto tracking utilities for advanced usage
|
|
1334
|
-
// These are used internally but can be called manually if needed
|
|
1335
|
-
// Navigation
|
|
1336
|
-
// Re-export LogLevel enum from utils
|
|
1337
|
-
// Note: This is safe because the enum itself doesn't trigger react-native imports
|
|
1260
|
+
var _default = exports.default = Rejourney;
|
|
1338
1261
|
/**
|
|
1339
1262
|
* Configure SDK log verbosity.
|
|
1340
1263
|
*
|
|
@@ -1366,16 +1289,4 @@ var _default = exports.default = Rejourney; // Export types
|
|
|
1366
1289
|
function setLogLevel(level) {
|
|
1367
1290
|
getLogger().setLogLevel(level);
|
|
1368
1291
|
}
|
|
1369
|
-
|
|
1370
|
-
// Note: Components and hooks removed in new engine
|
|
1371
|
-
// Session replay now handled by dashboard web UI
|
|
1372
|
-
// export { RejourneyReplay } from './components/replay/RejourneyReplay';
|
|
1373
|
-
// export { GestureTracker } from './components/GestureTracker';
|
|
1374
|
-
// export { SessionList } from './components/SessionList';
|
|
1375
|
-
// export { useRejourney } from './hooks/useRejourney';
|
|
1376
|
-
// export { useReplay } from './hooks/useReplay';
|
|
1377
|
-
|
|
1378
|
-
// Note: SDK managers removed in new engine - all functionality handled by native module
|
|
1379
|
-
|
|
1380
|
-
// Export Mask component
|
|
1381
1292
|
//# sourceMappingURL=index.js.map
|