@rejourneyco/react-native 1.0.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.
- package/android/build.gradle.kts +135 -0
- package/android/consumer-rules.pro +10 -0
- package/android/proguard-rules.pro +1 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +2981 -0
- package/android/src/main/java/com/rejourney/capture/ANRHandler.kt +206 -0
- package/android/src/main/java/com/rejourney/capture/ActivityTracker.kt +98 -0
- package/android/src/main/java/com/rejourney/capture/CaptureEngine.kt +1553 -0
- package/android/src/main/java/com/rejourney/capture/CaptureHeuristics.kt +375 -0
- package/android/src/main/java/com/rejourney/capture/CrashHandler.kt +153 -0
- package/android/src/main/java/com/rejourney/capture/MotionEvent.kt +215 -0
- package/android/src/main/java/com/rejourney/capture/SegmentUploader.kt +512 -0
- package/android/src/main/java/com/rejourney/capture/VideoEncoder.kt +773 -0
- package/android/src/main/java/com/rejourney/capture/ViewHierarchyScanner.kt +633 -0
- package/android/src/main/java/com/rejourney/capture/ViewSerializer.kt +286 -0
- package/android/src/main/java/com/rejourney/core/Constants.kt +117 -0
- package/android/src/main/java/com/rejourney/core/Logger.kt +93 -0
- package/android/src/main/java/com/rejourney/core/Types.kt +124 -0
- package/android/src/main/java/com/rejourney/lifecycle/SessionLifecycleService.kt +162 -0
- package/android/src/main/java/com/rejourney/network/DeviceAuthManager.kt +747 -0
- package/android/src/main/java/com/rejourney/network/HttpClientProvider.kt +16 -0
- package/android/src/main/java/com/rejourney/network/NetworkMonitor.kt +272 -0
- package/android/src/main/java/com/rejourney/network/UploadManager.kt +1363 -0
- package/android/src/main/java/com/rejourney/network/UploadWorker.kt +492 -0
- package/android/src/main/java/com/rejourney/privacy/PrivacyMask.kt +645 -0
- package/android/src/main/java/com/rejourney/touch/GestureClassifier.kt +233 -0
- package/android/src/main/java/com/rejourney/touch/KeyboardTracker.kt +158 -0
- package/android/src/main/java/com/rejourney/touch/TextInputTracker.kt +181 -0
- package/android/src/main/java/com/rejourney/touch/TouchInterceptor.kt +591 -0
- package/android/src/main/java/com/rejourney/utils/EventBuffer.kt +284 -0
- package/android/src/main/java/com/rejourney/utils/OEMDetector.kt +154 -0
- package/android/src/main/java/com/rejourney/utils/PerfTiming.kt +235 -0
- package/android/src/main/java/com/rejourney/utils/Telemetry.kt +297 -0
- package/android/src/main/java/com/rejourney/utils/WindowUtils.kt +84 -0
- package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +187 -0
- package/android/src/newarch/java/com/rejourney/RejourneyPackage.kt +40 -0
- package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +218 -0
- package/android/src/oldarch/java/com/rejourney/RejourneyPackage.kt +23 -0
- package/ios/Capture/RJANRHandler.h +42 -0
- package/ios/Capture/RJANRHandler.m +328 -0
- package/ios/Capture/RJCaptureEngine.h +275 -0
- package/ios/Capture/RJCaptureEngine.m +2062 -0
- package/ios/Capture/RJCaptureHeuristics.h +80 -0
- package/ios/Capture/RJCaptureHeuristics.m +903 -0
- package/ios/Capture/RJCrashHandler.h +46 -0
- package/ios/Capture/RJCrashHandler.m +313 -0
- package/ios/Capture/RJMotionEvent.h +183 -0
- package/ios/Capture/RJMotionEvent.m +183 -0
- package/ios/Capture/RJPerformanceManager.h +100 -0
- package/ios/Capture/RJPerformanceManager.m +373 -0
- package/ios/Capture/RJPixelBufferDownscaler.h +42 -0
- package/ios/Capture/RJPixelBufferDownscaler.m +85 -0
- package/ios/Capture/RJSegmentUploader.h +146 -0
- package/ios/Capture/RJSegmentUploader.m +778 -0
- package/ios/Capture/RJVideoEncoder.h +247 -0
- package/ios/Capture/RJVideoEncoder.m +1036 -0
- package/ios/Capture/RJViewControllerTracker.h +73 -0
- package/ios/Capture/RJViewControllerTracker.m +508 -0
- package/ios/Capture/RJViewHierarchyScanner.h +215 -0
- package/ios/Capture/RJViewHierarchyScanner.m +1464 -0
- package/ios/Capture/RJViewSerializer.h +119 -0
- package/ios/Capture/RJViewSerializer.m +498 -0
- package/ios/Core/RJConstants.h +124 -0
- package/ios/Core/RJConstants.m +88 -0
- package/ios/Core/RJLifecycleManager.h +85 -0
- package/ios/Core/RJLifecycleManager.m +308 -0
- package/ios/Core/RJLogger.h +61 -0
- package/ios/Core/RJLogger.m +211 -0
- package/ios/Core/RJTypes.h +176 -0
- package/ios/Core/RJTypes.m +66 -0
- package/ios/Core/Rejourney.h +64 -0
- package/ios/Core/Rejourney.mm +2495 -0
- package/ios/Network/RJDeviceAuthManager.h +94 -0
- package/ios/Network/RJDeviceAuthManager.m +967 -0
- package/ios/Network/RJNetworkMonitor.h +68 -0
- package/ios/Network/RJNetworkMonitor.m +267 -0
- package/ios/Network/RJRetryManager.h +73 -0
- package/ios/Network/RJRetryManager.m +325 -0
- package/ios/Network/RJUploadManager.h +267 -0
- package/ios/Network/RJUploadManager.m +2296 -0
- package/ios/Privacy/RJPrivacyMask.h +163 -0
- package/ios/Privacy/RJPrivacyMask.m +922 -0
- package/ios/Rejourney.h +63 -0
- package/ios/Touch/RJGestureClassifier.h +130 -0
- package/ios/Touch/RJGestureClassifier.m +333 -0
- package/ios/Touch/RJTouchInterceptor.h +169 -0
- package/ios/Touch/RJTouchInterceptor.m +772 -0
- package/ios/Utils/RJEventBuffer.h +112 -0
- package/ios/Utils/RJEventBuffer.m +358 -0
- package/ios/Utils/RJGzipUtils.h +33 -0
- package/ios/Utils/RJGzipUtils.m +89 -0
- package/ios/Utils/RJKeychainManager.h +48 -0
- package/ios/Utils/RJKeychainManager.m +111 -0
- package/ios/Utils/RJPerfTiming.h +209 -0
- package/ios/Utils/RJPerfTiming.m +264 -0
- package/ios/Utils/RJTelemetry.h +92 -0
- package/ios/Utils/RJTelemetry.m +320 -0
- package/ios/Utils/RJWindowUtils.h +66 -0
- package/ios/Utils/RJWindowUtils.m +133 -0
- package/lib/commonjs/NativeRejourney.js +40 -0
- package/lib/commonjs/components/Mask.js +79 -0
- package/lib/commonjs/index.js +1381 -0
- package/lib/commonjs/sdk/autoTracking.js +1259 -0
- package/lib/commonjs/sdk/constants.js +151 -0
- package/lib/commonjs/sdk/errorTracking.js +199 -0
- package/lib/commonjs/sdk/index.js +50 -0
- package/lib/commonjs/sdk/metricsTracking.js +204 -0
- package/lib/commonjs/sdk/navigation.js +151 -0
- package/lib/commonjs/sdk/networkInterceptor.js +412 -0
- package/lib/commonjs/sdk/utils.js +363 -0
- package/lib/commonjs/types/expo-router.d.js +2 -0
- package/lib/commonjs/types/index.js +2 -0
- package/lib/module/NativeRejourney.js +38 -0
- package/lib/module/components/Mask.js +72 -0
- package/lib/module/index.js +1284 -0
- package/lib/module/sdk/autoTracking.js +1233 -0
- package/lib/module/sdk/constants.js +145 -0
- package/lib/module/sdk/errorTracking.js +189 -0
- package/lib/module/sdk/index.js +12 -0
- package/lib/module/sdk/metricsTracking.js +187 -0
- package/lib/module/sdk/navigation.js +143 -0
- package/lib/module/sdk/networkInterceptor.js +401 -0
- package/lib/module/sdk/utils.js +342 -0
- package/lib/module/types/expo-router.d.js +2 -0
- package/lib/module/types/index.js +2 -0
- package/lib/typescript/NativeRejourney.d.ts +147 -0
- package/lib/typescript/components/Mask.d.ts +39 -0
- package/lib/typescript/index.d.ts +117 -0
- package/lib/typescript/sdk/autoTracking.d.ts +204 -0
- package/lib/typescript/sdk/constants.d.ts +120 -0
- package/lib/typescript/sdk/errorTracking.d.ts +32 -0
- package/lib/typescript/sdk/index.d.ts +9 -0
- package/lib/typescript/sdk/metricsTracking.d.ts +58 -0
- package/lib/typescript/sdk/navigation.d.ts +33 -0
- package/lib/typescript/sdk/networkInterceptor.d.ts +47 -0
- package/lib/typescript/sdk/utils.d.ts +148 -0
- package/lib/typescript/types/index.d.ts +624 -0
- package/package.json +102 -0
- package/rejourney.podspec +21 -0
- package/src/NativeRejourney.ts +165 -0
- package/src/components/Mask.tsx +80 -0
- package/src/index.ts +1459 -0
- package/src/sdk/autoTracking.ts +1373 -0
- package/src/sdk/constants.ts +134 -0
- package/src/sdk/errorTracking.ts +231 -0
- package/src/sdk/index.ts +11 -0
- package/src/sdk/metricsTracking.ts +232 -0
- package/src/sdk/navigation.ts +157 -0
- package/src/sdk/networkInterceptor.ts +440 -0
- package/src/sdk/utils.ts +369 -0
- package/src/types/expo-router.d.ts +7 -0
- package/src/types/index.ts +739 -0
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rejourneyco/react-native",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Rejourney Session Recording SDK for React Native",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "lib/module/index.js",
|
|
9
|
+
"source": "src/index.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"lib",
|
|
13
|
+
"android",
|
|
14
|
+
"ios",
|
|
15
|
+
"rejourney.podspec",
|
|
16
|
+
"!android/.gradle",
|
|
17
|
+
"!android/.idea",
|
|
18
|
+
"!android/build",
|
|
19
|
+
"!android/local.properties",
|
|
20
|
+
"!android/.settings",
|
|
21
|
+
"!android/*.iml",
|
|
22
|
+
"!ios/build",
|
|
23
|
+
"!ios/DerivedData",
|
|
24
|
+
"!ios/Pods",
|
|
25
|
+
"!ios/*.xcworkspace",
|
|
26
|
+
"!src/__tests__",
|
|
27
|
+
"!src/**/*.test.ts",
|
|
28
|
+
"!src/**/*.spec.ts",
|
|
29
|
+
"!.DS_Store",
|
|
30
|
+
"!**/.DS_Store",
|
|
31
|
+
"!lib/**/*.map"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "npx react-native-builder-bob build",
|
|
35
|
+
"prepack": "npx react-native-builder-bob build",
|
|
36
|
+
"typescript": "tsc --noEmit",
|
|
37
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"test:watch": "vitest",
|
|
40
|
+
"test:coverage": "vitest run --coverage",
|
|
41
|
+
"release": "release-it",
|
|
42
|
+
"verify:ios": "./scripts/verify-ios-structure.sh",
|
|
43
|
+
"test:ios-install": "./scripts/test-ios-install.sh"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"react-native",
|
|
47
|
+
"session-recording",
|
|
48
|
+
"analytics",
|
|
49
|
+
"replay"
|
|
50
|
+
],
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/rejourneyco/rejourney"
|
|
54
|
+
},
|
|
55
|
+
"author": "Rejourney",
|
|
56
|
+
"license": "Apache-2.0",
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@eslint/js": "^9.15.0",
|
|
59
|
+
"@types/react": "*",
|
|
60
|
+
"@types/react-native": "*",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
62
|
+
"@typescript-eslint/parser": "^8.15.0",
|
|
63
|
+
"@vitest/coverage-v8": "^2.1.0",
|
|
64
|
+
"eslint": "^9.39.2",
|
|
65
|
+
"react": "*",
|
|
66
|
+
"react-native": "*",
|
|
67
|
+
"react-native-builder-bob": "^0.23.0",
|
|
68
|
+
"typescript": "^5.0.0",
|
|
69
|
+
"vitest": "^2.1.0"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"react": "*",
|
|
73
|
+
"react-native": "*"
|
|
74
|
+
},
|
|
75
|
+
"codegenConfig": {
|
|
76
|
+
"name": "RejourneySpec",
|
|
77
|
+
"type": "modules",
|
|
78
|
+
"jsSrcsDir": "src",
|
|
79
|
+
"android": {
|
|
80
|
+
"javaPackageName": "com.rejourney"
|
|
81
|
+
},
|
|
82
|
+
"ios": {
|
|
83
|
+
"modulesProvider": {
|
|
84
|
+
"Rejourney": "Rejourney"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"react-native-builder-bob": {
|
|
89
|
+
"source": "src",
|
|
90
|
+
"output": "lib",
|
|
91
|
+
"targets": [
|
|
92
|
+
"commonjs",
|
|
93
|
+
"module",
|
|
94
|
+
[
|
|
95
|
+
"typescript",
|
|
96
|
+
{
|
|
97
|
+
"project": "tsconfig.json"
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "rejourney"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"] || "https://rejourney.co"
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => "13.0" }
|
|
14
|
+
s.source = { :git => package["repository"]["url"], :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm}"
|
|
17
|
+
s.exclude_files = "ios/build/**/*"
|
|
18
|
+
|
|
19
|
+
# Dependencies
|
|
20
|
+
install_modules_dependencies(s)
|
|
21
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboModule spec for Rejourney SDK
|
|
3
|
+
*
|
|
4
|
+
* This file defines the native module interface for React Native's New Architecture.
|
|
5
|
+
* It follows the official React Native TurboModules pattern for Codegen compatibility.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: This spec file is used by Codegen to generate native bindings.
|
|
8
|
+
* The default export MUST be a direct TurboModuleRegistry.get() call.
|
|
9
|
+
*
|
|
10
|
+
* @see https://reactnative.dev/docs/turbo-native-modules-introduction
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { TurboModule } from 'react-native';
|
|
14
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* SDK telemetry metrics for observability
|
|
18
|
+
*/
|
|
19
|
+
export interface SDKMetrics {
|
|
20
|
+
uploadSuccessCount: number;
|
|
21
|
+
uploadFailureCount: number;
|
|
22
|
+
retryAttemptCount: number;
|
|
23
|
+
circuitBreakerOpenCount: number;
|
|
24
|
+
memoryEvictionCount: number;
|
|
25
|
+
offlinePersistCount: number;
|
|
26
|
+
sessionStartCount: number;
|
|
27
|
+
crashCount: number;
|
|
28
|
+
uploadSuccessRate: number;
|
|
29
|
+
avgUploadDurationMs: number;
|
|
30
|
+
currentQueueDepth: number;
|
|
31
|
+
lastUploadTime: number | null;
|
|
32
|
+
lastRetryTime: number | null;
|
|
33
|
+
totalBytesUploaded: number;
|
|
34
|
+
totalBytesEvicted: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Native Rejourney module specification for TurboModules (New Architecture)
|
|
39
|
+
*
|
|
40
|
+
* This interface defines all methods exposed by the native module.
|
|
41
|
+
* Codegen uses this to generate:
|
|
42
|
+
* - iOS: RejourneySpec.h (protocol) and RejourneySpec-generated.mm (JSI bindings)
|
|
43
|
+
* - Android: NativeRejourneySpec.java (interface)
|
|
44
|
+
*/
|
|
45
|
+
export interface Spec extends TurboModule {
|
|
46
|
+
/**
|
|
47
|
+
* Start a recording session
|
|
48
|
+
*/
|
|
49
|
+
startSession(
|
|
50
|
+
userId: string,
|
|
51
|
+
apiUrl: string,
|
|
52
|
+
publicKey: string
|
|
53
|
+
): Promise<{
|
|
54
|
+
success: boolean;
|
|
55
|
+
sessionId: string;
|
|
56
|
+
error?: string;
|
|
57
|
+
}>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Stop the current recording session
|
|
61
|
+
*/
|
|
62
|
+
stopSession(): Promise<{
|
|
63
|
+
success: boolean;
|
|
64
|
+
sessionId: string;
|
|
65
|
+
uploadSuccess?: boolean;
|
|
66
|
+
warning?: string;
|
|
67
|
+
error?: string;
|
|
68
|
+
}>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Log a custom event
|
|
72
|
+
*/
|
|
73
|
+
logEvent(
|
|
74
|
+
eventType: string,
|
|
75
|
+
details: Object
|
|
76
|
+
): Promise<{
|
|
77
|
+
success: boolean;
|
|
78
|
+
}>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Notify of a screen change
|
|
82
|
+
*/
|
|
83
|
+
screenChanged(screenName: string): Promise<{
|
|
84
|
+
success: boolean;
|
|
85
|
+
}>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Report scroll offset for timeline correlation
|
|
89
|
+
*/
|
|
90
|
+
onScroll(offsetY: number): Promise<{
|
|
91
|
+
success: boolean;
|
|
92
|
+
}>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Mark a visual change that should be captured
|
|
96
|
+
*/
|
|
97
|
+
markVisualChange(reason: string, importance: string): Promise<boolean>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Notify that an external URL is being opened
|
|
101
|
+
*/
|
|
102
|
+
onExternalURLOpened(urlScheme: string): Promise<{
|
|
103
|
+
success: boolean;
|
|
104
|
+
}>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Notify that an OAuth flow is starting
|
|
108
|
+
*/
|
|
109
|
+
onOAuthStarted(provider: string): Promise<{
|
|
110
|
+
success: boolean;
|
|
111
|
+
}>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Notify that an OAuth flow has completed
|
|
115
|
+
*/
|
|
116
|
+
onOAuthCompleted(provider: string, success: boolean): Promise<{
|
|
117
|
+
success: boolean;
|
|
118
|
+
}>;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get SDK telemetry metrics for observability
|
|
122
|
+
*/
|
|
123
|
+
getSDKMetrics(): Promise<SDKMetrics>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Trigger a debug crash (Dev only)
|
|
127
|
+
*/
|
|
128
|
+
debugCrash(): void;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Trigger a debug ANR (Dev only)
|
|
132
|
+
* Blocks the main thread for the specified duration
|
|
133
|
+
*/
|
|
134
|
+
debugTriggerANR(durationMs: number): void;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get the current session ID
|
|
138
|
+
*/
|
|
139
|
+
getSessionId(): Promise<string | null>;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Mask a view by its nativeID prop (will be occluded in recordings)
|
|
143
|
+
*/
|
|
144
|
+
maskViewByNativeID(nativeID: string): Promise<{ success: boolean }>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Unmask a view by its nativeID prop
|
|
148
|
+
*/
|
|
149
|
+
unmaskViewByNativeID(nativeID: string): Promise<{ success: boolean }>;
|
|
150
|
+
|
|
151
|
+
setUserIdentity(userId: string): Promise<{ success: boolean }>;
|
|
152
|
+
|
|
153
|
+
setDebugMode(enabled: boolean): Promise<{ success: boolean }>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Default export for Codegen.
|
|
158
|
+
*
|
|
159
|
+
* CRITICAL: This MUST be a direct TurboModuleRegistry.get() call.
|
|
160
|
+
* Codegen parses this file statically and requires this exact pattern.
|
|
161
|
+
*
|
|
162
|
+
* Using getEnforcing() would throw if module not found.
|
|
163
|
+
* Using get() returns null, which is safer during development/testing.
|
|
164
|
+
*/
|
|
165
|
+
export default TurboModuleRegistry.get<Spec>('Rejourney');
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask Component
|
|
3
|
+
*
|
|
4
|
+
* Wrapper component to mask sensitive content in session replays.
|
|
5
|
+
* All children wrapped in this component will be obscured in recordings.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: This file uses lazy loading to avoid "PlatformConstants could not be found"
|
|
8
|
+
* errors on React Native 0.81+ with New Architecture (Bridgeless).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { Mask } from 'rejourney';
|
|
13
|
+
*
|
|
14
|
+
* // Mask sensitive user ID
|
|
15
|
+
* <Mask>
|
|
16
|
+
* <Text>User ID: {user.id}</Text>
|
|
17
|
+
* </Mask>
|
|
18
|
+
*
|
|
19
|
+
* // Mask credit card info
|
|
20
|
+
* <Mask>
|
|
21
|
+
* <CreditCardDisplay card={card} />
|
|
22
|
+
* </Mask>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import React from 'react';
|
|
26
|
+
import type { ViewProps } from 'react-native';
|
|
27
|
+
|
|
28
|
+
// Lazy-loaded React Native modules
|
|
29
|
+
let _RN: typeof import('react-native') | null = null;
|
|
30
|
+
|
|
31
|
+
function getRN(): typeof import('react-native') | null {
|
|
32
|
+
if (_RN) return _RN;
|
|
33
|
+
try {
|
|
34
|
+
_RN = require('react-native');
|
|
35
|
+
return _RN;
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface MaskProps extends ViewProps {
|
|
42
|
+
children: React.ReactNode;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Wrapper component to mask sensitive content in session replays.
|
|
47
|
+
* All children will be obscured in recordings.
|
|
48
|
+
*
|
|
49
|
+
* Uses accessibilityHint to signal to the native capture engine
|
|
50
|
+
* that this view and its contents should be masked.
|
|
51
|
+
*/
|
|
52
|
+
export const Mask: React.FC<MaskProps> = ({ children, style, ...props }) => {
|
|
53
|
+
const RN = getRN();
|
|
54
|
+
|
|
55
|
+
// If RN isn't loaded yet (shouldn't happen in practice), render children directly
|
|
56
|
+
if (!RN) {
|
|
57
|
+
return <>{children}</>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const { View, StyleSheet } = RN;
|
|
61
|
+
|
|
62
|
+
const styles = StyleSheet.create({
|
|
63
|
+
container: {
|
|
64
|
+
// Minimal container style - doesn't affect layout
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<View
|
|
70
|
+
{...props}
|
|
71
|
+
style={[styles.container, style]}
|
|
72
|
+
accessibilityHint="rejourney_occlude"
|
|
73
|
+
collapsable={false}
|
|
74
|
+
>
|
|
75
|
+
{children}
|
|
76
|
+
</View>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default Mask;
|