@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.
Files changed (152) hide show
  1. package/android/build.gradle.kts +135 -0
  2. package/android/consumer-rules.pro +10 -0
  3. package/android/proguard-rules.pro +1 -0
  4. package/android/src/main/AndroidManifest.xml +15 -0
  5. package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +2981 -0
  6. package/android/src/main/java/com/rejourney/capture/ANRHandler.kt +206 -0
  7. package/android/src/main/java/com/rejourney/capture/ActivityTracker.kt +98 -0
  8. package/android/src/main/java/com/rejourney/capture/CaptureEngine.kt +1553 -0
  9. package/android/src/main/java/com/rejourney/capture/CaptureHeuristics.kt +375 -0
  10. package/android/src/main/java/com/rejourney/capture/CrashHandler.kt +153 -0
  11. package/android/src/main/java/com/rejourney/capture/MotionEvent.kt +215 -0
  12. package/android/src/main/java/com/rejourney/capture/SegmentUploader.kt +512 -0
  13. package/android/src/main/java/com/rejourney/capture/VideoEncoder.kt +773 -0
  14. package/android/src/main/java/com/rejourney/capture/ViewHierarchyScanner.kt +633 -0
  15. package/android/src/main/java/com/rejourney/capture/ViewSerializer.kt +286 -0
  16. package/android/src/main/java/com/rejourney/core/Constants.kt +117 -0
  17. package/android/src/main/java/com/rejourney/core/Logger.kt +93 -0
  18. package/android/src/main/java/com/rejourney/core/Types.kt +124 -0
  19. package/android/src/main/java/com/rejourney/lifecycle/SessionLifecycleService.kt +162 -0
  20. package/android/src/main/java/com/rejourney/network/DeviceAuthManager.kt +747 -0
  21. package/android/src/main/java/com/rejourney/network/HttpClientProvider.kt +16 -0
  22. package/android/src/main/java/com/rejourney/network/NetworkMonitor.kt +272 -0
  23. package/android/src/main/java/com/rejourney/network/UploadManager.kt +1363 -0
  24. package/android/src/main/java/com/rejourney/network/UploadWorker.kt +492 -0
  25. package/android/src/main/java/com/rejourney/privacy/PrivacyMask.kt +645 -0
  26. package/android/src/main/java/com/rejourney/touch/GestureClassifier.kt +233 -0
  27. package/android/src/main/java/com/rejourney/touch/KeyboardTracker.kt +158 -0
  28. package/android/src/main/java/com/rejourney/touch/TextInputTracker.kt +181 -0
  29. package/android/src/main/java/com/rejourney/touch/TouchInterceptor.kt +591 -0
  30. package/android/src/main/java/com/rejourney/utils/EventBuffer.kt +284 -0
  31. package/android/src/main/java/com/rejourney/utils/OEMDetector.kt +154 -0
  32. package/android/src/main/java/com/rejourney/utils/PerfTiming.kt +235 -0
  33. package/android/src/main/java/com/rejourney/utils/Telemetry.kt +297 -0
  34. package/android/src/main/java/com/rejourney/utils/WindowUtils.kt +84 -0
  35. package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +187 -0
  36. package/android/src/newarch/java/com/rejourney/RejourneyPackage.kt +40 -0
  37. package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +218 -0
  38. package/android/src/oldarch/java/com/rejourney/RejourneyPackage.kt +23 -0
  39. package/ios/Capture/RJANRHandler.h +42 -0
  40. package/ios/Capture/RJANRHandler.m +328 -0
  41. package/ios/Capture/RJCaptureEngine.h +275 -0
  42. package/ios/Capture/RJCaptureEngine.m +2062 -0
  43. package/ios/Capture/RJCaptureHeuristics.h +80 -0
  44. package/ios/Capture/RJCaptureHeuristics.m +903 -0
  45. package/ios/Capture/RJCrashHandler.h +46 -0
  46. package/ios/Capture/RJCrashHandler.m +313 -0
  47. package/ios/Capture/RJMotionEvent.h +183 -0
  48. package/ios/Capture/RJMotionEvent.m +183 -0
  49. package/ios/Capture/RJPerformanceManager.h +100 -0
  50. package/ios/Capture/RJPerformanceManager.m +373 -0
  51. package/ios/Capture/RJPixelBufferDownscaler.h +42 -0
  52. package/ios/Capture/RJPixelBufferDownscaler.m +85 -0
  53. package/ios/Capture/RJSegmentUploader.h +146 -0
  54. package/ios/Capture/RJSegmentUploader.m +778 -0
  55. package/ios/Capture/RJVideoEncoder.h +247 -0
  56. package/ios/Capture/RJVideoEncoder.m +1036 -0
  57. package/ios/Capture/RJViewControllerTracker.h +73 -0
  58. package/ios/Capture/RJViewControllerTracker.m +508 -0
  59. package/ios/Capture/RJViewHierarchyScanner.h +215 -0
  60. package/ios/Capture/RJViewHierarchyScanner.m +1464 -0
  61. package/ios/Capture/RJViewSerializer.h +119 -0
  62. package/ios/Capture/RJViewSerializer.m +498 -0
  63. package/ios/Core/RJConstants.h +124 -0
  64. package/ios/Core/RJConstants.m +88 -0
  65. package/ios/Core/RJLifecycleManager.h +85 -0
  66. package/ios/Core/RJLifecycleManager.m +308 -0
  67. package/ios/Core/RJLogger.h +61 -0
  68. package/ios/Core/RJLogger.m +211 -0
  69. package/ios/Core/RJTypes.h +176 -0
  70. package/ios/Core/RJTypes.m +66 -0
  71. package/ios/Core/Rejourney.h +64 -0
  72. package/ios/Core/Rejourney.mm +2495 -0
  73. package/ios/Network/RJDeviceAuthManager.h +94 -0
  74. package/ios/Network/RJDeviceAuthManager.m +967 -0
  75. package/ios/Network/RJNetworkMonitor.h +68 -0
  76. package/ios/Network/RJNetworkMonitor.m +267 -0
  77. package/ios/Network/RJRetryManager.h +73 -0
  78. package/ios/Network/RJRetryManager.m +325 -0
  79. package/ios/Network/RJUploadManager.h +267 -0
  80. package/ios/Network/RJUploadManager.m +2296 -0
  81. package/ios/Privacy/RJPrivacyMask.h +163 -0
  82. package/ios/Privacy/RJPrivacyMask.m +922 -0
  83. package/ios/Rejourney.h +63 -0
  84. package/ios/Touch/RJGestureClassifier.h +130 -0
  85. package/ios/Touch/RJGestureClassifier.m +333 -0
  86. package/ios/Touch/RJTouchInterceptor.h +169 -0
  87. package/ios/Touch/RJTouchInterceptor.m +772 -0
  88. package/ios/Utils/RJEventBuffer.h +112 -0
  89. package/ios/Utils/RJEventBuffer.m +358 -0
  90. package/ios/Utils/RJGzipUtils.h +33 -0
  91. package/ios/Utils/RJGzipUtils.m +89 -0
  92. package/ios/Utils/RJKeychainManager.h +48 -0
  93. package/ios/Utils/RJKeychainManager.m +111 -0
  94. package/ios/Utils/RJPerfTiming.h +209 -0
  95. package/ios/Utils/RJPerfTiming.m +264 -0
  96. package/ios/Utils/RJTelemetry.h +92 -0
  97. package/ios/Utils/RJTelemetry.m +320 -0
  98. package/ios/Utils/RJWindowUtils.h +66 -0
  99. package/ios/Utils/RJWindowUtils.m +133 -0
  100. package/lib/commonjs/NativeRejourney.js +40 -0
  101. package/lib/commonjs/components/Mask.js +79 -0
  102. package/lib/commonjs/index.js +1381 -0
  103. package/lib/commonjs/sdk/autoTracking.js +1259 -0
  104. package/lib/commonjs/sdk/constants.js +151 -0
  105. package/lib/commonjs/sdk/errorTracking.js +199 -0
  106. package/lib/commonjs/sdk/index.js +50 -0
  107. package/lib/commonjs/sdk/metricsTracking.js +204 -0
  108. package/lib/commonjs/sdk/navigation.js +151 -0
  109. package/lib/commonjs/sdk/networkInterceptor.js +412 -0
  110. package/lib/commonjs/sdk/utils.js +363 -0
  111. package/lib/commonjs/types/expo-router.d.js +2 -0
  112. package/lib/commonjs/types/index.js +2 -0
  113. package/lib/module/NativeRejourney.js +38 -0
  114. package/lib/module/components/Mask.js +72 -0
  115. package/lib/module/index.js +1284 -0
  116. package/lib/module/sdk/autoTracking.js +1233 -0
  117. package/lib/module/sdk/constants.js +145 -0
  118. package/lib/module/sdk/errorTracking.js +189 -0
  119. package/lib/module/sdk/index.js +12 -0
  120. package/lib/module/sdk/metricsTracking.js +187 -0
  121. package/lib/module/sdk/navigation.js +143 -0
  122. package/lib/module/sdk/networkInterceptor.js +401 -0
  123. package/lib/module/sdk/utils.js +342 -0
  124. package/lib/module/types/expo-router.d.js +2 -0
  125. package/lib/module/types/index.js +2 -0
  126. package/lib/typescript/NativeRejourney.d.ts +147 -0
  127. package/lib/typescript/components/Mask.d.ts +39 -0
  128. package/lib/typescript/index.d.ts +117 -0
  129. package/lib/typescript/sdk/autoTracking.d.ts +204 -0
  130. package/lib/typescript/sdk/constants.d.ts +120 -0
  131. package/lib/typescript/sdk/errorTracking.d.ts +32 -0
  132. package/lib/typescript/sdk/index.d.ts +9 -0
  133. package/lib/typescript/sdk/metricsTracking.d.ts +58 -0
  134. package/lib/typescript/sdk/navigation.d.ts +33 -0
  135. package/lib/typescript/sdk/networkInterceptor.d.ts +47 -0
  136. package/lib/typescript/sdk/utils.d.ts +148 -0
  137. package/lib/typescript/types/index.d.ts +624 -0
  138. package/package.json +102 -0
  139. package/rejourney.podspec +21 -0
  140. package/src/NativeRejourney.ts +165 -0
  141. package/src/components/Mask.tsx +80 -0
  142. package/src/index.ts +1459 -0
  143. package/src/sdk/autoTracking.ts +1373 -0
  144. package/src/sdk/constants.ts +134 -0
  145. package/src/sdk/errorTracking.ts +231 -0
  146. package/src/sdk/index.ts +11 -0
  147. package/src/sdk/metricsTracking.ts +232 -0
  148. package/src/sdk/navigation.ts +157 -0
  149. package/src/sdk/networkInterceptor.ts +440 -0
  150. package/src/sdk/utils.ts +369 -0
  151. package/src/types/expo-router.d.ts +7 -0
  152. 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;