@rejourneyco/react-native 1.0.7

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 (105) hide show
  1. package/README.md +29 -0
  2. package/android/build.gradle.kts +135 -0
  3. package/android/consumer-rules.pro +10 -0
  4. package/android/proguard-rules.pro +1 -0
  5. package/android/src/main/AndroidManifest.xml +15 -0
  6. package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +860 -0
  7. package/android/src/main/java/com/rejourney/engine/DeviceRegistrar.kt +290 -0
  8. package/android/src/main/java/com/rejourney/engine/DiagnosticLog.kt +385 -0
  9. package/android/src/main/java/com/rejourney/engine/RejourneyImpl.kt +512 -0
  10. package/android/src/main/java/com/rejourney/platform/OEMDetector.kt +173 -0
  11. package/android/src/main/java/com/rejourney/platform/PerfTiming.kt +384 -0
  12. package/android/src/main/java/com/rejourney/platform/SessionLifecycleService.kt +160 -0
  13. package/android/src/main/java/com/rejourney/platform/Telemetry.kt +301 -0
  14. package/android/src/main/java/com/rejourney/platform/WindowUtils.kt +100 -0
  15. package/android/src/main/java/com/rejourney/recording/AnrSentinel.kt +129 -0
  16. package/android/src/main/java/com/rejourney/recording/EventBuffer.kt +330 -0
  17. package/android/src/main/java/com/rejourney/recording/InteractionRecorder.kt +519 -0
  18. package/android/src/main/java/com/rejourney/recording/ReplayOrchestrator.kt +740 -0
  19. package/android/src/main/java/com/rejourney/recording/SegmentDispatcher.kt +559 -0
  20. package/android/src/main/java/com/rejourney/recording/StabilityMonitor.kt +238 -0
  21. package/android/src/main/java/com/rejourney/recording/TelemetryPipeline.kt +633 -0
  22. package/android/src/main/java/com/rejourney/recording/ViewHierarchyScanner.kt +232 -0
  23. package/android/src/main/java/com/rejourney/recording/VisualCapture.kt +474 -0
  24. package/android/src/main/java/com/rejourney/utility/DataCompression.kt +63 -0
  25. package/android/src/main/java/com/rejourney/utility/ImageBlur.kt +412 -0
  26. package/android/src/main/java/com/rejourney/utility/ViewIdentifier.kt +169 -0
  27. package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +232 -0
  28. package/android/src/newarch/java/com/rejourney/RejourneyPackage.kt +40 -0
  29. package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +268 -0
  30. package/android/src/oldarch/java/com/rejourney/RejourneyPackage.kt +23 -0
  31. package/ios/Engine/DeviceRegistrar.swift +288 -0
  32. package/ios/Engine/DiagnosticLog.swift +387 -0
  33. package/ios/Engine/RejourneyImpl.swift +719 -0
  34. package/ios/Recording/AnrSentinel.swift +142 -0
  35. package/ios/Recording/EventBuffer.swift +326 -0
  36. package/ios/Recording/InteractionRecorder.swift +428 -0
  37. package/ios/Recording/ReplayOrchestrator.swift +624 -0
  38. package/ios/Recording/SegmentDispatcher.swift +492 -0
  39. package/ios/Recording/StabilityMonitor.swift +223 -0
  40. package/ios/Recording/TelemetryPipeline.swift +547 -0
  41. package/ios/Recording/ViewHierarchyScanner.swift +156 -0
  42. package/ios/Recording/VisualCapture.swift +675 -0
  43. package/ios/Rejourney.h +38 -0
  44. package/ios/Rejourney.mm +375 -0
  45. package/ios/Utility/DataCompression.swift +55 -0
  46. package/ios/Utility/ImageBlur.swift +89 -0
  47. package/ios/Utility/RuntimeMethodSwap.swift +41 -0
  48. package/ios/Utility/ViewIdentifier.swift +37 -0
  49. package/lib/commonjs/NativeRejourney.js +40 -0
  50. package/lib/commonjs/components/Mask.js +88 -0
  51. package/lib/commonjs/index.js +1443 -0
  52. package/lib/commonjs/sdk/autoTracking.js +1087 -0
  53. package/lib/commonjs/sdk/constants.js +166 -0
  54. package/lib/commonjs/sdk/errorTracking.js +187 -0
  55. package/lib/commonjs/sdk/index.js +50 -0
  56. package/lib/commonjs/sdk/metricsTracking.js +205 -0
  57. package/lib/commonjs/sdk/navigation.js +128 -0
  58. package/lib/commonjs/sdk/networkInterceptor.js +375 -0
  59. package/lib/commonjs/sdk/utils.js +433 -0
  60. package/lib/commonjs/sdk/version.js +13 -0
  61. package/lib/commonjs/types/expo-router.d.js +2 -0
  62. package/lib/commonjs/types/index.js +2 -0
  63. package/lib/module/NativeRejourney.js +38 -0
  64. package/lib/module/components/Mask.js +83 -0
  65. package/lib/module/index.js +1341 -0
  66. package/lib/module/sdk/autoTracking.js +1059 -0
  67. package/lib/module/sdk/constants.js +154 -0
  68. package/lib/module/sdk/errorTracking.js +177 -0
  69. package/lib/module/sdk/index.js +26 -0
  70. package/lib/module/sdk/metricsTracking.js +187 -0
  71. package/lib/module/sdk/navigation.js +120 -0
  72. package/lib/module/sdk/networkInterceptor.js +364 -0
  73. package/lib/module/sdk/utils.js +412 -0
  74. package/lib/module/sdk/version.js +7 -0
  75. package/lib/module/types/expo-router.d.js +2 -0
  76. package/lib/module/types/index.js +2 -0
  77. package/lib/typescript/NativeRejourney.d.ts +160 -0
  78. package/lib/typescript/components/Mask.d.ts +54 -0
  79. package/lib/typescript/index.d.ts +117 -0
  80. package/lib/typescript/sdk/autoTracking.d.ts +226 -0
  81. package/lib/typescript/sdk/constants.d.ts +138 -0
  82. package/lib/typescript/sdk/errorTracking.d.ts +47 -0
  83. package/lib/typescript/sdk/index.d.ts +24 -0
  84. package/lib/typescript/sdk/metricsTracking.d.ts +75 -0
  85. package/lib/typescript/sdk/navigation.d.ts +48 -0
  86. package/lib/typescript/sdk/networkInterceptor.d.ts +62 -0
  87. package/lib/typescript/sdk/utils.d.ts +193 -0
  88. package/lib/typescript/sdk/version.d.ts +6 -0
  89. package/lib/typescript/types/index.d.ts +618 -0
  90. package/package.json +122 -0
  91. package/rejourney.podspec +23 -0
  92. package/src/NativeRejourney.ts +185 -0
  93. package/src/components/Mask.tsx +93 -0
  94. package/src/index.ts +1555 -0
  95. package/src/sdk/autoTracking.ts +1245 -0
  96. package/src/sdk/constants.ts +155 -0
  97. package/src/sdk/errorTracking.ts +231 -0
  98. package/src/sdk/index.ts +25 -0
  99. package/src/sdk/metricsTracking.ts +227 -0
  100. package/src/sdk/navigation.ts +152 -0
  101. package/src/sdk/networkInterceptor.ts +423 -0
  102. package/src/sdk/utils.ts +442 -0
  103. package/src/sdk/version.ts +6 -0
  104. package/src/types/expo-router.d.ts +7 -0
  105. package/src/types/index.ts +709 -0
package/package.json ADDED
@@ -0,0 +1,122 @@
1
+ {
2
+ "name": "@rejourneyco/react-native",
3
+ "version": "1.0.7",
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
+ "verify:package": "./scripts/verify-package-content.sh",
44
+ "test:ios-install": "./scripts/test-ios-install.sh",
45
+ "test:android-install": "./scripts/test-android-install.sh",
46
+ "audit:deps": "depcruise src --config .dependency-cruiser.js"
47
+ },
48
+ "keywords": [
49
+ "react-native",
50
+ "session-replay",
51
+ "observability",
52
+ "error-tracking",
53
+ "crash-reporting",
54
+ "anr-reporting",
55
+ "api-monitoring",
56
+ "alerting",
57
+ "mobile-analytics",
58
+ "mobile-observability",
59
+ "mobile-error-tracking",
60
+ "mobile-crash-reporting",
61
+ "mobile-anr-reporting",
62
+ "mobile-api-monitoring",
63
+ "mobile-performance-monitoring",
64
+ "mobile-user-behavior-analytics"
65
+ ],
66
+ "repository": {
67
+ "type": "git",
68
+ "url": "https://github.com/rejourneyco/rejourney"
69
+ },
70
+ "author": "Rejourney",
71
+ "license": "Apache-2.0",
72
+ "devDependencies": {
73
+ "@eslint/js": "^9.15.0",
74
+ "@types/react": "*",
75
+ "@types/react-native": "*",
76
+ "@typescript-eslint/eslint-plugin": "^8.15.0",
77
+ "@typescript-eslint/parser": "^8.15.0",
78
+ "@vitest/coverage-v8": "^2.1.0",
79
+ "dependency-cruiser": "^16.10.4",
80
+ "@react-navigation/native": "*",
81
+ "expo-router": "*",
82
+ "eslint": "^9.39.2",
83
+ "react": "*",
84
+ "react-native": "*",
85
+ "react-native-builder-bob": "^0.23.0",
86
+ "typescript": "^5.0.0",
87
+ "vitest": "^2.1.0"
88
+ },
89
+ "peerDependencies": {
90
+ "react": "*",
91
+ "react-native": "*",
92
+ "@react-navigation/native": ">=6.0.0",
93
+ "expo-router": ">=3.0.0"
94
+ },
95
+ "codegenConfig": {
96
+ "name": "RejourneySpec",
97
+ "type": "modules",
98
+ "jsSrcsDir": "src",
99
+ "android": {
100
+ "javaPackageName": "com.rejourney"
101
+ },
102
+ "ios": {
103
+ "modulesProvider": {
104
+ "Rejourney": "Rejourney"
105
+ }
106
+ }
107
+ },
108
+ "react-native-builder-bob": {
109
+ "source": "src",
110
+ "output": "lib",
111
+ "targets": [
112
+ "commonjs",
113
+ "module",
114
+ [
115
+ "typescript",
116
+ {
117
+ "project": "tsconfig.json"
118
+ }
119
+ ]
120
+ ]
121
+ }
122
+ }
@@ -0,0 +1,23 @@
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,swift}"
17
+ s.swift_version = "5.0"
18
+ s.exclude_files = "ios/build/**/*"
19
+ s.library = "z"
20
+
21
+ # Dependencies
22
+ install_modules_dependencies(s)
23
+ end
@@ -0,0 +1,185 @@
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
+ getUserIdentity(): Promise<string | null>;
154
+
155
+ setDebugMode(enabled: boolean): Promise<{ success: boolean }>;
156
+
157
+ /**
158
+ * Set SDK version from JS (called during init with version from package.json)
159
+ */
160
+ setSDKVersion(version: string): void;
161
+
162
+ /**
163
+ * Set remote configuration from backend
164
+ * Called before startSession to apply server-side settings
165
+ */
166
+ setRemoteConfig(
167
+ rejourneyEnabled: boolean,
168
+ recordingEnabled: boolean,
169
+ sampleRate: number,
170
+ maxRecordingMinutes: number
171
+ ): Promise<{ success: boolean }>;
172
+
173
+ getDeviceInfo(): Promise<Object>;
174
+ }
175
+
176
+ /**
177
+ * Default export for Codegen.
178
+ *
179
+ * CRITICAL: This MUST be a direct TurboModuleRegistry.get() call.
180
+ * Codegen parses this file statically and requires this exact pattern.
181
+ *
182
+ * Using getEnforcing() would throw if module not found.
183
+ * Using get() returns null, which is safer during development/testing.
184
+ */
185
+ export default TurboModuleRegistry.get<Spec>('Rejourney');
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Copyright 2026 Rejourney
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Mask Component
19
+ *
20
+ * Wrapper component to mask sensitive content in session replays.
21
+ * All children wrapped in this component will be obscured in recordings.
22
+ *
23
+ * IMPORTANT: This file uses lazy loading to avoid "PlatformConstants could not be found"
24
+ * errors on React Native 0.81+ with New Architecture (Bridgeless).
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * import { Mask } from 'rejourney';
29
+ *
30
+ * // Mask sensitive user ID
31
+ * <Mask>
32
+ * <Text>User ID: {user.id}</Text>
33
+ * </Mask>
34
+ *
35
+ * // Mask credit card info
36
+ * <Mask>
37
+ * <CreditCardDisplay card={card} />
38
+ * </Mask>
39
+ * ```
40
+ */
41
+ import React from 'react';
42
+ import type { ViewProps } from 'react-native';
43
+
44
+ let _RN: typeof import('react-native') | null = null;
45
+
46
+ function getRN(): typeof import('react-native') | null {
47
+ if (_RN) return _RN;
48
+ try {
49
+ _RN = require('react-native');
50
+ return _RN;
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ export interface MaskProps extends ViewProps {
57
+ children: React.ReactNode;
58
+ }
59
+
60
+ /**
61
+ * Wrapper component to mask sensitive content in session replays.
62
+ * All children will be obscured in recordings.
63
+ *
64
+ * Uses accessibilityHint to signal to the native capture engine
65
+ * that this view and its contents should be masked.
66
+ */
67
+ export const Mask: React.FC<MaskProps> = ({ children, style, ...props }) => {
68
+ const RN = getRN();
69
+
70
+ if (!RN) {
71
+ return <>{children}</>;
72
+ }
73
+
74
+ const { View, StyleSheet } = RN;
75
+
76
+ const styles = StyleSheet.create({
77
+ container: {
78
+ },
79
+ });
80
+
81
+ return (
82
+ <View
83
+ {...props}
84
+ style={[styles.container, style]}
85
+ accessibilityHint="rejourney_occlude"
86
+ collapsable={false}
87
+ >
88
+ {children}
89
+ </View>
90
+ );
91
+ };
92
+
93
+ export default Mask;