@multiplayer-app/session-recorder-react-native 0.0.1 → 1.0.0-beta.1

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 (229) hide show
  1. package/README.md +708 -83
  2. package/SessionRecorderNative.podspec +26 -0
  3. package/android/build.gradle +34 -0
  4. package/copy-react-native-dist.sh +34 -16
  5. package/dist/components/ScreenRecorderView/ScreenRecorderView.js +1 -1
  6. package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -1
  7. package/dist/components/SessionRecorderWidget/ErrorBanner.d.ts +7 -0
  8. package/dist/components/SessionRecorderWidget/ErrorBanner.js +1 -0
  9. package/dist/components/SessionRecorderWidget/ErrorBanner.js.map +1 -0
  10. package/dist/components/SessionRecorderWidget/FinalPopover.d.ts +12 -0
  11. package/dist/components/SessionRecorderWidget/FinalPopover.js +1 -0
  12. package/dist/components/SessionRecorderWidget/FinalPopover.js.map +1 -0
  13. package/dist/components/SessionRecorderWidget/FloatingButton.d.ts +8 -0
  14. package/dist/components/SessionRecorderWidget/FloatingButton.js +1 -0
  15. package/dist/components/SessionRecorderWidget/FloatingButton.js.map +1 -0
  16. package/dist/components/SessionRecorderWidget/InitialPopover.d.ts +16 -0
  17. package/dist/components/SessionRecorderWidget/InitialPopover.js +1 -0
  18. package/dist/components/SessionRecorderWidget/InitialPopover.js.map +1 -0
  19. package/dist/components/SessionRecorderWidget/ModalContainer.d.ts +8 -0
  20. package/dist/components/SessionRecorderWidget/ModalContainer.js +1 -0
  21. package/dist/components/SessionRecorderWidget/ModalContainer.js.map +1 -0
  22. package/dist/components/SessionRecorderWidget/ModalHeader.d.ts +6 -0
  23. package/dist/components/SessionRecorderWidget/ModalHeader.js +1 -0
  24. package/dist/components/SessionRecorderWidget/ModalHeader.js.map +1 -0
  25. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.d.ts +5 -0
  26. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js +1 -0
  27. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -0
  28. package/dist/components/SessionRecorderWidget/icons.d.ts +11 -0
  29. package/dist/components/SessionRecorderWidget/icons.js +1 -0
  30. package/dist/components/SessionRecorderWidget/icons.js.map +1 -0
  31. package/dist/components/SessionRecorderWidget/index.d.ts +2 -0
  32. package/dist/components/SessionRecorderWidget/index.js +1 -0
  33. package/dist/components/SessionRecorderWidget/index.js.map +1 -0
  34. package/dist/components/SessionRecorderWidget/styles.d.ts +165 -0
  35. package/dist/components/SessionRecorderWidget/styles.js +1 -0
  36. package/dist/components/SessionRecorderWidget/styles.js.map +1 -0
  37. package/dist/components/index.d.ts +2 -1
  38. package/dist/components/index.js +1 -1
  39. package/dist/components/index.js.map +1 -1
  40. package/dist/config/constants.js +1 -1
  41. package/dist/config/constants.js.map +1 -1
  42. package/dist/config/defaults.d.ts +4 -4
  43. package/dist/config/defaults.js +1 -1
  44. package/dist/config/defaults.js.map +1 -1
  45. package/dist/config/masking.d.ts +2 -2
  46. package/dist/config/masking.js +1 -1
  47. package/dist/config/masking.js.map +1 -1
  48. package/dist/config/session-recorder.js +1 -1
  49. package/dist/config/session-recorder.js.map +1 -1
  50. package/dist/config/validators.d.ts +1 -1
  51. package/dist/config/validators.js +1 -1
  52. package/dist/config/validators.js.map +1 -1
  53. package/dist/config/widget.d.ts +9 -0
  54. package/dist/config/widget.js +1 -0
  55. package/dist/config/widget.js.map +1 -0
  56. package/dist/context/SessionRecorderContext.d.ts +12 -3
  57. package/dist/context/SessionRecorderContext.js +1 -1
  58. package/dist/context/SessionRecorderContext.js.map +1 -1
  59. package/dist/context/SessionRecorderStore.d.ts +12 -0
  60. package/dist/context/SessionRecorderStore.js +1 -0
  61. package/dist/context/SessionRecorderStore.js.map +1 -0
  62. package/dist/context/useSessionRecorderStore.d.ts +8 -0
  63. package/dist/context/useSessionRecorderStore.js +1 -0
  64. package/dist/context/useSessionRecorderStore.js.map +1 -0
  65. package/dist/context/useStoreSelector.d.ts +4 -0
  66. package/dist/context/useStoreSelector.js +1 -0
  67. package/dist/context/useStoreSelector.js.map +1 -0
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.js +1 -1
  70. package/dist/index.js.map +1 -1
  71. package/dist/native/GestureRecorderNative.d.ts +57 -0
  72. package/dist/native/GestureRecorderNative.js +1 -0
  73. package/dist/native/GestureRecorderNative.js.map +1 -0
  74. package/dist/native/SessionRecorderNative.d.ts +33 -0
  75. package/dist/native/SessionRecorderNative.js +1 -0
  76. package/dist/native/SessionRecorderNative.js.map +1 -0
  77. package/dist/native/index.d.ts +2 -0
  78. package/dist/native/index.js +1 -0
  79. package/dist/native/index.js.map +1 -0
  80. package/dist/otel/index.js +1 -1
  81. package/dist/otel/index.js.map +1 -1
  82. package/dist/patch/xhr.js +1 -1
  83. package/dist/patch/xhr.js.map +1 -1
  84. package/dist/recorder/eventExporter.d.ts +4 -1
  85. package/dist/recorder/eventExporter.js +1 -1
  86. package/dist/recorder/eventExporter.js.map +1 -1
  87. package/dist/recorder/gestureRecorder.d.ts +28 -62
  88. package/dist/recorder/gestureRecorder.js +1 -1
  89. package/dist/recorder/gestureRecorder.js.map +1 -1
  90. package/dist/recorder/index.d.ts +2 -0
  91. package/dist/recorder/index.js +1 -1
  92. package/dist/recorder/index.js.map +1 -1
  93. package/dist/recorder/navigationTracker.d.ts +4 -19
  94. package/dist/recorder/navigationTracker.js +1 -1
  95. package/dist/recorder/navigationTracker.js.map +1 -1
  96. package/dist/recorder/screenRecorder.d.ts +11 -5
  97. package/dist/recorder/screenRecorder.js +1 -1
  98. package/dist/recorder/screenRecorder.js.map +1 -1
  99. package/dist/services/api.service.d.ts +12 -3
  100. package/dist/services/api.service.js +1 -1
  101. package/dist/services/api.service.js.map +1 -1
  102. package/dist/services/network.service.d.ts +46 -0
  103. package/dist/services/network.service.js +1 -0
  104. package/dist/services/network.service.js.map +1 -0
  105. package/dist/services/screenMaskingService.d.ts +47 -0
  106. package/dist/services/screenMaskingService.js +1 -0
  107. package/dist/services/screenMaskingService.js.map +1 -0
  108. package/dist/services/storage.service.d.ts +18 -2
  109. package/dist/services/storage.service.js +1 -1
  110. package/dist/services/storage.service.js.map +1 -1
  111. package/dist/session-recorder.d.ts +18 -33
  112. package/dist/session-recorder.js +1 -1
  113. package/dist/session-recorder.js.map +1 -1
  114. package/dist/types/configs.d.ts +85 -0
  115. package/dist/types/configs.js +1 -0
  116. package/dist/types/configs.js.map +1 -0
  117. package/dist/types/index.d.ts +1 -0
  118. package/dist/types/index.js +1 -1
  119. package/dist/types/index.js.map +1 -1
  120. package/dist/types/session-recorder.d.ts +105 -132
  121. package/dist/types/session-recorder.js +1 -1
  122. package/dist/types/session-recorder.js.map +1 -1
  123. package/dist/utils/constants.optional.d.ts +21 -0
  124. package/dist/utils/constants.optional.expo.d.ts +3 -0
  125. package/dist/utils/constants.optional.expo.js +1 -0
  126. package/dist/utils/constants.optional.expo.js.map +1 -0
  127. package/dist/utils/constants.optional.js +1 -0
  128. package/dist/utils/constants.optional.js.map +1 -0
  129. package/dist/utils/createStore.d.ts +8 -0
  130. package/dist/utils/createStore.js +1 -0
  131. package/dist/utils/createStore.js.map +1 -0
  132. package/dist/utils/logger.d.ts +2 -7
  133. package/dist/utils/logger.js +1 -1
  134. package/dist/utils/logger.js.map +1 -1
  135. package/dist/utils/platform.d.ts +11 -0
  136. package/dist/utils/platform.js +1 -1
  137. package/dist/utils/platform.js.map +1 -1
  138. package/dist/utils/rrweb-events.d.ts +4 -3
  139. package/dist/utils/rrweb-events.js +1 -1
  140. package/dist/utils/rrweb-events.js.map +1 -1
  141. package/dist/utils/session.d.ts +2 -1
  142. package/dist/utils/session.js +1 -1
  143. package/dist/utils/session.js.map +1 -1
  144. package/dist/utils/shallowEqual.d.ts +1 -0
  145. package/dist/utils/shallowEqual.js +1 -0
  146. package/dist/utils/shallowEqual.js.map +1 -0
  147. package/dist/version.d.ts +1 -1
  148. package/dist/version.js +1 -1
  149. package/dist/version.js.map +1 -1
  150. package/ios/GestureRecorderNative.m +21 -0
  151. package/ios/GestureRecorderNative.swift +316 -0
  152. package/ios/SessionRecorderNative.m +17 -0
  153. package/ios/SessionRecorderNative.podspec +26 -0
  154. package/ios/SessionRecorderNative.swift +599 -0
  155. package/package.json +15 -16
  156. package/react-native.config.js +12 -0
  157. package/RRWEB_INTEGRATION.md +0 -336
  158. package/VIEWSHOT_INTEGRATION_TEST.md +0 -123
  159. package/babel.config.js +0 -13
  160. package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.d.ts +0 -6
  161. package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js +0 -1
  162. package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js.map +0 -1
  163. package/dist/components/GestureCaptureWrapper/index.d.ts +0 -1
  164. package/dist/components/GestureCaptureWrapper/index.js +0 -1
  165. package/dist/components/GestureCaptureWrapper/index.js.map +0 -1
  166. package/dist/components/GestureCaptureWrapper.d.ts +0 -6
  167. package/dist/components/GestureCaptureWrapper.js +0 -1
  168. package/dist/components/GestureCaptureWrapper.js.map +0 -1
  169. package/dist/expo.d.ts +0 -7
  170. package/dist/expo.js +0 -1
  171. package/dist/expo.js.map +0 -1
  172. package/dist/otel/instrumentations/gestureInstrumentation.d.ts +0 -15
  173. package/dist/otel/instrumentations/gestureInstrumentation.js +0 -1
  174. package/dist/otel/instrumentations/gestureInstrumentation.js.map +0 -1
  175. package/dist/otel/instrumentations/reactNativeInstrumentation.d.ts +0 -8
  176. package/dist/otel/instrumentations/reactNativeInstrumentation.js +0 -1
  177. package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +0 -1
  178. package/dist/otel/instrumentations/reactNavigationInstrumentation.d.ts +0 -13
  179. package/dist/otel/instrumentations/reactNavigationInstrumentation.js +0 -1
  180. package/dist/otel/instrumentations/reactNavigationInstrumentation.js.map +0 -1
  181. package/dist/recorder/gestureHandlerRecorder.d.ts +0 -19
  182. package/dist/recorder/gestureHandlerRecorder.js +0 -1
  183. package/dist/recorder/gestureHandlerRecorder.js.map +0 -1
  184. package/dist/types/rrweb.d.ts +0 -118
  185. package/dist/types/rrweb.js +0 -1
  186. package/dist/types/rrweb.js.map +0 -1
  187. package/scripts/generate-app-metadata.js +0 -173
  188. package/src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx +0 -86
  189. package/src/components/GestureCaptureWrapper/index.ts +0 -1
  190. package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +0 -72
  191. package/src/components/ScreenRecorderView/index.ts +0 -1
  192. package/src/components/index.ts +0 -1
  193. package/src/config/constants.ts +0 -60
  194. package/src/config/defaults.ts +0 -82
  195. package/src/config/index.ts +0 -6
  196. package/src/config/masking.ts +0 -27
  197. package/src/config/session-recorder.ts +0 -55
  198. package/src/config/validators.ts +0 -31
  199. package/src/context/SessionRecorderContext.tsx +0 -75
  200. package/src/expo.ts +0 -11
  201. package/src/index.ts +0 -17
  202. package/src/otel/helpers.ts +0 -275
  203. package/src/otel/index.ts +0 -138
  204. package/src/otel/instrumentations/index.ts +0 -115
  205. package/src/patch/index.ts +0 -1
  206. package/src/patch/xhr.ts +0 -142
  207. package/src/recorder/eventExporter.ts +0 -141
  208. package/src/recorder/gestureRecorder.ts +0 -498
  209. package/src/recorder/index.ts +0 -179
  210. package/src/recorder/navigationTracker.ts +0 -449
  211. package/src/recorder/screenRecorder.ts +0 -498
  212. package/src/services/api.service.ts +0 -203
  213. package/src/services/storage.service.ts +0 -158
  214. package/src/session-recorder.ts +0 -600
  215. package/src/types/expo.d.ts +0 -23
  216. package/src/types/index.ts +0 -28
  217. package/src/types/session-recorder.ts +0 -423
  218. package/src/types/session.ts +0 -65
  219. package/src/utils/app-metadata.ts +0 -31
  220. package/src/utils/index.ts +0 -8
  221. package/src/utils/logger.ts +0 -225
  222. package/src/utils/platform.ts +0 -384
  223. package/src/utils/request-utils.ts +0 -61
  224. package/src/utils/rrweb-events.ts +0 -309
  225. package/src/utils/session.ts +0 -18
  226. package/src/utils/time.ts +0 -17
  227. package/src/utils/type-utils.ts +0 -75
  228. package/src/version.ts +0 -1
  229. package/tsconfig.json +0 -24
package/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Multiplayer Session Recorder for React Native
2
2
 
3
- The Multiplayer Session Recorder for React Native provides session recording capabilities for React Native applications, including gesture tracking, navigation monitoring, and screen recording. It also includes full support for Expo applications.
3
+ The Multiplayer Session Recorder for React Native provides comprehensive session recording capabilities for React Native applications, including gesture tracking, navigation monitoring, screen recording, and full-stack debugging. It includes full support for both bare React Native and Expo applications.
4
+
5
+ ## ⚠️ Important: Web Platform Limitations
6
+
7
+ **This package does NOT support React Native Web.** The session recorder relies on native modules for core functionality:
8
+
9
+ - **Screen Recording**: Requires native screen capture capabilities
10
+ - **Gesture Recording**: Uses native gesture detection systems
11
+ - **Native Module Dependencies**: Core features depend on iOS/Android native modules
12
+
13
+ If you need web support, consider using the browser-specific session recorder package instead.
4
14
 
5
15
  ## Installation
6
16
 
@@ -15,44 +25,223 @@ yarn add @multiplayer-app/session-recorder-react-native
15
25
  This package requires the following dependencies to be installed in your React Native application:
16
26
 
17
27
  ```bash
18
- npm install @react-native-async-storage/async-storage @react-native-community/netinfo react-native-mmkv
28
+ npm install @react-native-async-storage/async-storage @react-native-community/netinfo react-native-svg react-native-safe-area-context
19
29
  # or
20
- yarn add @react-native-async-storage/async-storage @react-native-community/netinfo react-native-mmkv
30
+ yarn add @react-native-async-storage/async-storage @react-native-community/netinfo react-native-svg react-native-safe-area-context
21
31
  ```
22
32
 
23
- **Note**: If these dependencies are not installed, the session recorder will throw clear error messages indicating which dependencies are missing.
33
+ **Important**: Native modules must be installed directly in your app's `package.json`. React Native autolinking only links native modules that are declared by the app itself, not modules pulled in transitively by libraries. If you don't add them directly, you may see errors like "NativeModule: AsyncStorage is null" or SVGs not rendering.
34
+
35
+ #### Bare React Native projects
36
+
37
+ ```bash
38
+ # Install native dependencies in your app
39
+ npm install @react-native-async-storage/async-storage @react-native-community/netinfo react-native-svg react-native-safe-area-context
40
+
41
+ # iOS: Install pods from your app's ios directory
42
+ cd ios && pod install && cd -
43
+
44
+ # Android: Clean and rebuild
45
+ cd android && ./gradlew clean && cd -
46
+ ```
24
47
 
25
- ### Expo Installation
48
+ #### Expo projects
26
49
 
27
- For Expo applications, the package automatically detects the Expo environment and provides Expo-specific optimizations:
50
+ Use Expo's version-aware installer so versions match the SDK:
28
51
 
29
52
  ```bash
30
- npx expo install @multiplayer-app/session-recorder-react-native
53
+ npx expo install @react-native-async-storage/async-storage @react-native-community/netinfo react-native-svg react-native-safe-area-context
54
+ ```
55
+
56
+ If you use Expo Router or a managed workflow, no extra autolinking steps are required beyond installing the packages.
57
+
58
+ #### Why direct install is required
59
+
60
+ - Autolinking scans only the app's `package.json`
61
+ - iOS CocoaPods/Android Gradle include native modules only when the app declares them
62
+ - Libraries should list native requirements as `peerDependencies` and document installation
63
+
64
+ <!-- Removed separate Expo Installation block to avoid duplication. Expo users should install native deps with `expo install` as shown above. -->
65
+
66
+ ### Troubleshooting AsyncStorage
67
+
68
+ If you encounter:
69
+
31
70
  ```
71
+ [@RNC/AsyncStorage]: NativeModule: AsyncStorage is null
72
+ ```
73
+
74
+ 1. Ensure `@react-native-async-storage/async-storage` is installed in your app (not only in this library)
75
+ 2. iOS: run `cd ios && pod install`, then rebuild the app
76
+ 3. Clear Metro cache: `npm start -- --reset-cache` (or `expo start -c`)
77
+ 4. Clean builds: uninstall the app from device/simulator and rebuild
78
+
79
+ ## Quick Start
32
80
 
33
- The package will automatically detect if you're running in an Expo environment and provide the appropriate configuration.
81
+ ### ⚠️ Important: SessionRecorderProvider Required
34
82
 
35
- ## Setup
83
+ **The `SessionRecorderProvider` is required for the session recorder to work properly.** It provides:
84
+
85
+ - Context for session state management
86
+ - Widget modal functionality
87
+ - React hooks for session control
88
+ - Store management for session state
89
+
90
+ ### Minimal Setup (Recommended for getting started)
91
+
92
+ #### For Basic React Native Apps (App.tsx)
93
+
94
+ ```javascript
95
+ import React from 'react'
96
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
97
+
98
+ // Initialize with minimal required options
99
+ SessionRecorder.init({
100
+ application: 'my-react-native-app',
101
+ version: '1.0.0',
102
+ environment: 'production',
103
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY'
104
+ })
105
+
106
+ export default function App() {
107
+ return <SessionRecorderProvider>{/* Your app content */}</SessionRecorderProvider>
108
+ }
109
+ ```
110
+
111
+ #### For Expo Apps (\_layout.tsx)
112
+
113
+ ```javascript
114
+ import React from 'react'
115
+ import { Stack } from 'expo-router'
116
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
117
+
118
+ // Initialize with minimal required options
119
+ SessionRecorder.init({
120
+ application: 'my-expo-app',
121
+ version: '1.0.0',
122
+ environment: 'production',
123
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY'
124
+ })
125
+
126
+ export default function RootLayout() {
127
+ return (
128
+ <SessionRecorderProvider>
129
+ <Stack />
130
+ </SessionRecorderProvider>
131
+ )
132
+ }
133
+ ```
134
+
135
+ This minimal setup will:
136
+
137
+ - ✅ Record gestures and navigation automatically
138
+ - ✅ Enable HTTP request/response monitoring
139
+ - ✅ Provide basic session recording capabilities
140
+ - ✅ Screen recording enabled (captures app UI)
36
141
 
37
142
  ### Basic Configuration
38
143
 
144
+ #### For Basic React Native Apps (App.tsx)
145
+
39
146
  ```javascript
40
- import SessionRecorder from '@multiplayer-app/session-recorder-react-native'
147
+ import React from 'react'
148
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
41
149
 
42
150
  SessionRecorder.init({
43
151
  application: 'my-react-native-app',
44
152
  version: '1.0.0',
45
153
  environment: 'production',
46
- apiKey: 'MULTIPLAYER_OTLP_KEY',
154
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
155
+ recordGestures: true, // default is true
156
+ recordNavigation: true, // default is true
157
+ recordScreen: true // default is true
158
+ })
159
+
160
+ export default function App() {
161
+ return <SessionRecorderProvider>{/* Your app content */}</SessionRecorderProvider>
162
+ }
163
+ ```
164
+
165
+ #### For Expo Apps (\_layout.tsx)
166
+
167
+ ```javascript
168
+ import React from 'react'
169
+ import { Stack } from 'expo-router'
170
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
171
+
172
+ SessionRecorder.init({
173
+ application: 'my-expo-app',
174
+ version: '1.0.0',
175
+ environment: 'production',
176
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
177
+ recordGestures: true, // default is true
178
+ recordNavigation: true, // default is true
179
+ recordScreen: true // default is true
180
+ })
181
+
182
+ export default function RootLayout() {
183
+ return (
184
+ <SessionRecorderProvider>
185
+ <Stack />
186
+ </SessionRecorderProvider>
187
+ )
188
+ }
189
+ ```
190
+
191
+ ### Complete App Integration Example
192
+
193
+ Here's a complete example showing how to integrate the session recorder in your React Native app:
194
+
195
+ ```javascript
196
+ import React, { useEffect, useRef } from 'react'
197
+ import { NavigationContainer } from '@react-navigation/native'
198
+ import { SafeAreaProvider } from 'react-native-safe-area-context'
199
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
200
+ import { AppNavigator } from './navigation/AppNavigator'
201
+
202
+ // Initialize session recorder
203
+ SessionRecorder.init({
204
+ application: 'my-react-native-app',
205
+ version: '1.0.0',
206
+ environment: __DEV__ ? 'development' : 'production',
207
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
47
208
  recordGestures: true,
48
209
  recordNavigation: true,
49
- recordScreen: false // Requires additional permissions
210
+ recordScreen: false // Enable after adding permissions
50
211
  })
212
+
213
+ export default function App() {
214
+ const navigationRef = useRef(null)
215
+
216
+ useEffect(() => {
217
+ // Set session attributes for better debugging context
218
+ SessionRecorder.setSessionAttributes({
219
+ userId: 'user123',
220
+ userType: 'premium',
221
+ appVersion: '1.0.0'
222
+ })
223
+ }, [])
224
+
225
+ return (
226
+ <SessionRecorderProvider>
227
+ <SafeAreaProvider>
228
+ <NavigationContainer
229
+ ref={navigationRef}
230
+ onReady={() => {
231
+ SessionRecorder.setNavigationRef(navigationRef.current)
232
+ }}
233
+ >
234
+ <AppNavigator />
235
+ </NavigationContainer>
236
+ </SafeAreaProvider>
237
+ </SessionRecorderProvider>
238
+ )
239
+ }
51
240
  ```
52
241
 
53
242
  ### Expo Configuration
54
243
 
55
- For Expo applications, the package automatically detects the Expo environment. You can also explicitly specify the platform:
244
+ For Expo applications, the package automatically detects the Expo environment:
56
245
 
57
246
  ```javascript
58
247
  import SessionRecorder from '@multiplayer-app/session-recorder-react-native'
@@ -61,11 +250,10 @@ SessionRecorder.init({
61
250
  application: 'my-expo-app',
62
251
  version: '1.0.0',
63
252
  environment: 'production',
64
- apiKey: 'MULTIPLAYER_OTLP_KEY',
65
- platform: 'expo', // Optional: explicitly set platform
253
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
66
254
  recordGestures: true,
67
255
  recordNavigation: true,
68
- recordScreen: false
256
+ recordScreen: true
69
257
  })
70
258
  ```
71
259
 
@@ -75,148 +263,585 @@ The package will automatically:
75
263
  - Add Expo-specific attributes to traces
76
264
  - Optimize performance for Expo runtime
77
265
 
78
- ### React Navigation Integration
266
+ ### Navigation Integration
79
267
 
80
- ```javascript
268
+ #### Expo Router (Recommended for Expo apps)
269
+
270
+ Expo Router already manages the NavigationContainer. Don't add your own.
271
+
272
+ ```tsx
273
+ import { useEffect } from 'react'
274
+ import { Stack, useNavigationContainerRef } from 'expo-router'
275
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
276
+
277
+ export default function RootLayout() {
278
+ const navigationRef = useNavigationContainerRef()
279
+
280
+ useEffect(() => {
281
+ const unsub = navigationRef.addListener?.('state', () => {
282
+ SessionRecorder.setNavigationRef(navigationRef)
283
+ unsub?.()
284
+ })
285
+ return unsub
286
+ }, [navigationRef])
287
+
288
+ return (
289
+ <SessionRecorderProvider>
290
+ <Stack />
291
+ </SessionRecorderProvider>
292
+ )
293
+ }
294
+ ```
295
+
296
+ #### Classic React Navigation (Bare React Native)
297
+
298
+ If you own the `NavigationContainer`, set the ref in `onReady`:
299
+
300
+ ```tsx
81
301
  import { NavigationContainer } from '@react-navigation/native'
82
- import SessionRecorder from '@multiplayer-app/session-recorder-react-native'
302
+ import { useRef } from 'react'
303
+ import { SessionRecorderProvider, SessionRecorder } from '@multiplayer-app/session-recorder-react-native'
83
304
 
84
305
  export default function App() {
85
- const navigationRef = useRef(null)
306
+ const navigationRef = useRef<any>(null)
86
307
 
87
308
  return (
88
- <NavigationContainer
89
- ref={navigationRef}
90
- onReady={() => {
91
- SessionRecorder.setNavigationRef(navigationRef.current)
92
- }}
93
- >
94
- {/* Your navigation stack */}
95
- </NavigationContainer>
309
+ <SessionRecorderProvider>
310
+ <NavigationContainer
311
+ ref={navigationRef}
312
+ onReady={() => {
313
+ SessionRecorder.setNavigationRef(navigationRef.current)
314
+ }}
315
+ >
316
+ {/* Your navigation stack */}
317
+ </NavigationContainer>
318
+ </SessionRecorderProvider>
96
319
  )
97
320
  }
98
321
  ```
99
322
 
100
- ### Manual Control
323
+ ### Manual Session Control
101
324
 
102
325
  ```javascript
103
- // Start recording
326
+ // Start a new recording session
104
327
  SessionRecorder.start()
105
328
 
106
- // Pause recording
329
+ // Pause current recording
107
330
  SessionRecorder.pause()
108
331
 
109
- // Resume recording
332
+ // Resume paused recording
110
333
  SessionRecorder.resume()
111
334
 
112
- // Stop recording
335
+ // Stop recording with optional reason
113
336
  SessionRecorder.stop('Session completed')
114
337
 
115
- // Save continuous recording
338
+ // Save continuous recording (for continuous mode)
116
339
  SessionRecorder.save()
340
+
341
+ // Set session attributes for better context
342
+ SessionRecorder.setSessionAttributes({
343
+ userId: 'user123',
344
+ feature: 'checkout',
345
+ version: '2.1.0'
346
+ })
347
+ ```
348
+
349
+ ## Session Provider & Hooks
350
+
351
+ ### Disable Widget Button
352
+
353
+ To hide the floating widget button but keep the modal functionality:
354
+
355
+ ```javascript
356
+ SessionRecorder.init({
357
+ application: 'my-app',
358
+ version: '1.0.0',
359
+ environment: 'production',
360
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
361
+
362
+ // Disable the floating button
363
+ widget: {
364
+ enabled: true,
365
+ button: {
366
+ visible: false // Hide the floating button
367
+ }
368
+ }
369
+ })
370
+ ```
371
+
372
+ ### Programmatic Widget Control
373
+
374
+ Use the `useSessionRecorder` hook to control the widget modal programmatically:
375
+
376
+ ```javascript
377
+ import React from 'react'
378
+ import { View, Button } from 'react-native'
379
+ import { useSessionRecorder } from '@multiplayer-app/session-recorder-react-native'
380
+
381
+ function MyComponent() {
382
+ const { openWidgetModal, closeWidgetModal } = useSessionRecorder()
383
+
384
+ return (
385
+ <View>
386
+ <Button title='Open Session Recorder' onPress={openWidgetModal} />
387
+ <Button title='Close Session Recorder' onPress={closeWidgetModal} />
388
+ </View>
389
+ )
390
+ }
391
+ ```
392
+
393
+ ### Session Control with Hooks
394
+
395
+ ```javascript
396
+ import React from 'react'
397
+ import { View, Button } from 'react-native'
398
+ import { useSessionRecorder } from '@multiplayer-app/session-recorder-react-native'
399
+
400
+ function SessionControls() {
401
+ const { startSession, stopSession, pauseSession, resumeSession, saveSession } = useSessionRecorder()
402
+
403
+ return (
404
+ <View>
405
+ <Button title='Start Session' onPress={() => startSession()} />
406
+ <Button title='Pause Session' onPress={() => pauseSession()} />
407
+ <Button title='Resume Session' onPress={() => resumeSession()} />
408
+ <Button title='Stop Session' onPress={() => stopSession('User completed')} />
409
+ <Button title='Save Session' onPress={() => saveSession()} />
410
+ </View>
411
+ )
412
+ }
413
+ ```
414
+
415
+ ### Session State with Hooks
416
+
417
+ ```javascript
418
+ import React from 'react'
419
+ import { View, Text } from 'react-native'
420
+ import { useSessionRecorderStore } from '@multiplayer-app/session-recorder-react-native'
421
+
422
+ function SessionStatus() {
423
+ const sessionType = useSessionRecorderStore((s) => s.sessionType)
424
+ const isWidgetModalVisible = useSessionRecorderStore((s) => s.isWidgetModalVisible)
425
+ const sessionState = useSessionRecorderStore((s) => s.sessionState)
426
+ const isOnline = useSessionRecorderStore((s) => s.isOnline)
427
+
428
+ return (
429
+ <View>
430
+ <Text>Session State: {sessionState}</Text>
431
+ <Text>Session Type: {sessionType}</Text>
432
+ <Text>Widget Visible: {isWidgetModalVisible ? 'Yes' : 'No'}</Text>
433
+ <Text>Online: {isOnline ? 'Yes' : 'No'}</Text>
434
+ </View>
435
+ )
436
+ }
437
+ ```
438
+
439
+ ### Complete Example with Custom UI
440
+
441
+ ```javascript
442
+ import React, { useEffect } from 'react'
443
+ import { View, Button, Text, Alert } from 'react-native'
444
+ import {
445
+ SessionRecorderProvider,
446
+ useSessionRecorder,
447
+ useSessionRecorderStore
448
+ } from '@multiplayer-app/session-recorder-react-native'
449
+
450
+ function SessionRecorderUI() {
451
+ const { startSession, stopSession, openWidgetModal } = useSessionRecorder()
452
+ const { sessionState, isWidgetModalVisible } = useSessionRecorderStore((state) => ({
453
+ sessionState: state.sessionState,
454
+ isWidgetModalVisible: state.isWidgetModalVisible
455
+ }))
456
+
457
+ const handleStartRecording = async () => {
458
+ try {
459
+ await startSession()
460
+ Alert.alert('Success', 'Session recording started')
461
+ } catch (error) {
462
+ Alert.alert('Error', 'Failed to start recording')
463
+ }
464
+ }
465
+
466
+ const handleStopRecording = async () => {
467
+ try {
468
+ await stopSession('User manually stopped')
469
+ Alert.alert('Success', 'Session recording stopped')
470
+ } catch (error) {
471
+ Alert.alert('Error', 'Failed to stop recording')
472
+ }
473
+ }
474
+
475
+ return (
476
+ <View style={{ padding: 20 }}>
477
+ <Text>Session State: {sessionState}</Text>
478
+ <Text>Widget Modal: {isWidgetModalVisible ? 'Open' : 'Closed'}</Text>
479
+
480
+ <Button title='Start Recording' onPress={handleStartRecording} />
481
+ <Button title='Stop Recording' onPress={handleStopRecording} />
482
+ <Button title='Open Widget' onPress={openWidgetModal} />
483
+ </View>
484
+ )
485
+ }
486
+
487
+ export default function App() {
488
+ return (
489
+ <SessionRecorderProvider>
490
+ <SessionRecorderUI />
491
+ </SessionRecorderProvider>
492
+ )
493
+ }
117
494
  ```
118
495
 
119
496
  ## Features
120
497
 
121
- - **Gesture Recording**: Track taps, swipes, and other touch interactions
122
- - **Navigation Tracking**: Monitor screen transitions and navigation state
123
- - **Screen Recording**: Capture periodic screenshots (requires permissions)
124
- - **OpenTelemetry Integration**: Correlate with backend traces
125
- - **HTTP Masking**: Protect sensitive data in request/response headers and bodies
126
- - **Session Management**: Start, pause, resume, and stop sessions
127
- - **Expo Support**: Full compatibility with Expo applications including automatic environment detection
498
+ - **🎯 Gesture Recording**: Track taps, swipes, and other touch interactions with target element information
499
+ - **🧭 Navigation Tracking**: Monitor screen transitions and navigation state changes
500
+ - **📱 Screen Recording**: Capture periodic screenshots (requires permissions)
501
+ - **🔗 OpenTelemetry Integration**: Correlate frontend actions with backend traces
502
+ - **🔒 HTTP Masking**: Protect sensitive data in request/response headers and bodies
503
+ - **⚡ Session Management**: Start, pause, resume, and stop sessions programmatically
504
+ - **📦 Expo Support**: Full compatibility with Expo applications including automatic environment detection
505
+ - **🎨 Session Widget**: Built-in UI widget for user-initiated session recording
506
+ - **📊 Continuous Recording**: Background recording with automatic error capture
507
+ - **🌐 Network Monitoring**: Track HTTP requests and responses with correlation
508
+
509
+ ## Gesture Recording & Target Element Information
510
+
511
+ The session recorder automatically captures target element information for all gesture interactions, enriching your OpenTelemetry traces with valuable context about what users are interacting with.
128
512
 
129
- ## Permissions
513
+ ### Captured Attributes
130
514
 
131
- For screen recording, you'll need to add permissions to your app:
515
+ When users interact with elements, the following attributes are automatically added to gesture spans:
132
516
 
133
- ### iOS (Info.plist)
517
+ | Attribute | Description | Example |
518
+ | ------------------------ | ----------------------------------------- | ----------------- |
519
+ | `gesture.target` | Primary identifier for the target element | `"Submit Button"` |
520
+ | `gesture.target.label` | Accessibility label of the element | `"Submit form"` |
521
+ | `gesture.target.role` | Accessibility role of the element | `"button"` |
522
+ | `gesture.target.test_id` | Test ID of the element | `"submit-btn"` |
523
+ | `gesture.target.text` | Text content of the element | `"Submit"` |
134
524
 
135
- ```xml
136
- <key>NSCameraUsageDescription</key>
137
- <string>This app needs camera access to record screen interactions</string>
525
+ ### How Target Information is Extracted
526
+
527
+ The recorder automatically extracts target information from React Native elements using the following priority:
528
+
529
+ 1. **`accessibilityLabel`** - Explicit accessibility label (highest priority)
530
+ 2. **Text content** - Text from child elements
531
+ 3. **`testID`** - Test identifier (lowest priority)
532
+
533
+ ### Best Practices for Better Trace Information
534
+
535
+ To get the most useful target information in your traces, follow these practices:
536
+
537
+ #### 1. Use Accessibility Labels
538
+
539
+ ```jsx
540
+ <TouchableOpacity accessibilityLabel='Submit user registration form' accessibilityRole='button' onPress={handleSubmit}>
541
+ <Text>Submit</Text>
542
+ </TouchableOpacity>
543
+ ```
544
+
545
+ #### 2. Add Test IDs for Testing Context
546
+
547
+ ```jsx
548
+ <TouchableOpacity testID='registration-submit-btn' accessibilityLabel='Submit registration' onPress={handleSubmit}>
549
+ <Text>Submit</Text>
550
+ </TouchableOpacity>
138
551
  ```
139
552
 
140
- ### Android (AndroidManifest.xml)
553
+ #### 3. Use Semantic Text Content
554
+
555
+ ```jsx
556
+ <TouchableOpacity onPress={handleSubmit}>
557
+ <Text>Submit Registration</Text> {/* Clear, descriptive text */}
558
+ </TouchableOpacity>
559
+ ```
141
560
 
142
- ```xml
143
- <uses-permission android:name="android.permission.CAMERA" />
144
- <uses-permission android:name="android.permission.RECORD_AUDIO" />
561
+ #### 4. Avoid Generic Labels
562
+
563
+ ```jsx
564
+ // ❌ Poor trace information
565
+ <TouchableOpacity accessibilityLabel="Button" onPress={handleSubmit}>
566
+ <Text>Click</Text>
567
+ </TouchableOpacity>
568
+
569
+ // ✅ Rich trace information
570
+ <TouchableOpacity
571
+ accessibilityLabel="Submit user registration form"
572
+ testID="registration-submit"
573
+ onPress={handleSubmit}
574
+ >
575
+ <Text>Submit Registration</Text>
576
+ </TouchableOpacity>
577
+ ```
578
+
579
+ ### Example Trace Output
580
+
581
+ With proper element labeling, your gesture traces will include rich context:
582
+
583
+ ```json
584
+ {
585
+ "spanName": "Gesture.tap",
586
+ "attributes": {
587
+ "gesture.type": "tap",
588
+ "gesture.platform": "react-native",
589
+ "gesture.coordinates.x": 150.5,
590
+ "gesture.coordinates.y": 200.3,
591
+ "gesture.target": "Submit user registration form",
592
+ "gesture.target.label": "Submit user registration form",
593
+ "gesture.target.role": "button",
594
+ "gesture.target.test_id": "registration-submit",
595
+ "gesture.target.text": "Submit Registration"
596
+ }
597
+ }
145
598
  ```
146
599
 
600
+ This rich context helps you:
601
+
602
+ - **Debug user interactions** more effectively
603
+ - **Understand user behavior** patterns
604
+ - **Identify UI issues** faster
605
+ - **Correlate frontend actions** with backend events
606
+
607
+ ## Screen Recording
608
+
609
+ The session recorder captures your app's UI using `react-native-view-shot`, which:
610
+
611
+ - ✅ **No permissions required** - Captures only your app's interface
612
+ - ✅ **Works out of the box** - No additional setup needed
613
+ - ✅ **Privacy-friendly** - Only captures your app's content, not system UI
614
+ - ❌ **App-only** - Cannot capture other apps or system screens
615
+
616
+ This is different from system-wide screen recording which would require permissions.
617
+
147
618
  ## Configuration Options
148
619
 
149
- | Option | Type | Default | Description |
150
- | ------------------ | ------- | ------- | --------------------------------------- |
151
- | `apiKey` | string | - | Your Multiplayer API key |
152
- | `application` | string | - | Application name |
153
- | `version` | string | - | Application version |
154
- | `environment` | string | - | Environment (production, staging, etc.) |
155
- | `platform` | string | auto | Platform ('react-native' or 'expo') |
156
- | `recordGestures` | boolean | true | Enable gesture recording |
157
- | `recordNavigation` | boolean | true | Enable navigation tracking |
158
- | `recordScreen` | boolean | false | Enable screen recording |
159
- | `sampleTraceRatio` | number | 0.15 | Trace sampling ratio |
160
- | `captureBody` | boolean | true | Capture request/response bodies |
161
- | `captureHeaders` | boolean | true | Capture request/response headers |
162
- | `httpMasking` | object | - | HTTP masking configuration |
620
+ ### Required Options
621
+
622
+ | Option | Type | Description |
623
+ | ------------- | ------ | ------------------------------ |
624
+ | `apiKey` | string | Your Multiplayer API key |
625
+ | `application` | string | Application name |
626
+ | `version` | string | Application version |
627
+ | `environment` | string | Environment (production, etc.) |
628
+
629
+ ### Optional Options
630
+
631
+ | Option | Type | Default | Description |
632
+ | ------------------------------ | ------- | ------- | -------------------------------------- |
633
+ | `recordGestures` | boolean | true | Enable gesture recording |
634
+ | `recordNavigation` | boolean | true | Enable navigation tracking |
635
+ | `recordScreen` | boolean | true | Enable screen recording |
636
+ | `sampleTraceRatio` | number | 0.15 | Trace sampling ratio (0.0-1.0) |
637
+ | `captureBody` | boolean | true | Capture request/response bodies |
638
+ | `captureHeaders` | boolean | true | Capture request/response headers |
639
+ | `masking` | object | - | Data masking configuration |
640
+ | `ignoreUrls` | array | [] | URLs to exclude from monitoring |
641
+ | `propagateTraceHeaderCorsUrls` | array | [] | URLs for CORS trace header propagation |
642
+ | `showContinuousRecording` | boolean | true | Show continuous recording option |
643
+ | `widget` | object | - | Session widget configuration |
163
644
 
164
645
  ## Advanced Configuration
165
646
 
647
+ ### Full Configuration Example
648
+
166
649
  ```javascript
167
650
  SessionRecorder.init({
651
+ // Required options
168
652
  application: 'my-app',
169
653
  version: '1.0.0',
170
654
  environment: 'production',
171
- apiKey: 'MULTIPLAYER_OTLP_KEY',
655
+ apiKey: 'YOUR_MULTIPLAYER_API_KEY',
172
656
 
173
657
  // Recording options
174
658
  recordGestures: true,
175
659
  recordNavigation: true,
176
- recordScreen: false,
660
+ recordScreen: true, // Captures app UI automatically
177
661
 
178
662
  // Network monitoring
179
- ignoreUrls: [/https:\/\/analytics\.example\.com/],
663
+ // NOTE: if frontend domain doesn't match to backend one, set backend domain to `propagateTraceHeaderCorsUrls` parameter
664
+ propagateTraceHeaderCorsUrls: [
665
+ new RegExp('https://your.backend.api.domain', 'i'), // can be regex or string
666
+ new RegExp('https://another.backend.api.domain', 'i')
667
+ ],
668
+ ignoreUrls: [/https:\/\/analytics\.example\.com/, /https:\/\/crashlytics\.com/],
180
669
  captureBody: true,
181
670
  captureHeaders: true,
182
671
  maxCapturingHttpPayloadSize: 100000,
183
672
 
184
- // HTTP masking
185
- httpMasking: {
673
+ // Data masking for sensitive information
674
+ masking: {
186
675
  isContentMaskingEnabled: true,
187
676
  maskHeadersList: ['authorization', 'cookie', 'x-api-key'],
188
- maskBodyFieldsList: ['password', 'token', 'secret']
677
+ maskBodyFieldsList: ['password', 'token', 'secret', 'creditCard'],
678
+ maskTextInputs: true,
679
+ maskImages: false,
680
+ maskButtons: false
189
681
  },
190
682
 
191
- // Session attributes
192
- sessionAttributes: {
193
- userId: '12345',
194
- userType: 'premium'
195
- }
683
+ // Session widget configuration
684
+ widget: {
685
+ enabled: true,
686
+ button: {
687
+ visible: true,
688
+ placement: 'bottomRight' // or 'bottomLeft'
689
+ }
690
+ },
691
+
692
+ // Continuous recording
693
+ showContinuousRecording: true
196
694
  })
197
695
  ```
198
696
 
697
+ ### Environment-Specific Configuration
698
+
699
+ ```javascript
700
+ import { SessionRecorder, LogLevel } from '@multiplayer-app/session-recorder-react-native'
701
+
702
+ const config = {
703
+ application: 'my-app',
704
+ version: '1.0.0',
705
+ apiKey: process.env.MULTIPLAYER_API_KEY,
706
+
707
+ // Development-specific options
708
+ ...(__DEV__ && {
709
+ logger: {
710
+ enabled: true,
711
+ level: LogLevel.DEBUG
712
+ }
713
+ })
714
+ }
715
+
716
+ SessionRecorder.init(config)
717
+ ```
718
+
199
719
  ## Troubleshooting
200
720
 
201
721
  ### Common Issues
202
722
 
203
- 1. **Screen recording not working**: Ensure you have the necessary permissions
204
- 2. **Navigation tracking not working**: Make sure you've set the navigation ref
205
- 3. **Gesture recording issues**: Check that react-native-gesture-handler is properly configured
206
- 4. **Expo environment not detected**: Ensure `expo-constants` is installed and accessible
207
- 5. **Expo build issues**: Make sure you're using the correct entry point for Expo applications
723
+ #### 1. AsyncStorage Errors
724
+
725
+ ```
726
+ [@RNC/AsyncStorage]: NativeModule: AsyncStorage is null
727
+ ```
728
+
729
+ **Solution:**
730
+
731
+ - Ensure `@react-native-async-storage/async-storage` is installed in your app
732
+ - iOS: Run `cd ios && pod install`
733
+ - Clear Metro cache: `npm start -- --reset-cache`
734
+ - Clean builds: Uninstall app and rebuild
735
+
736
+ #### 2. Screen Recording Not Working
737
+
738
+ - Ensure `recordScreen: true` in configuration
739
+ - Check that `react-native-view-shot` is properly installed
740
+ - Verify the app has a valid view to capture
741
+ - Check console logs for capture errors
742
+
743
+ #### 3. Navigation Tracking Not Working
744
+
745
+ - Make sure you've set the navigation ref: `SessionRecorder.setNavigationRef(navigationRef)`
746
+ - For Expo Router: Use `useNavigationContainerRef()` hook
747
+ - For React Navigation: Set ref in `onReady` callback
748
+
749
+ #### 4. Gesture Recording Issues
750
+
751
+ - Gesture recording uses native modules and should work automatically
752
+ - Check that `recordGestures: true` is set
753
+ - Ensure app is not in background mode
754
+
755
+ #### 5. Expo Environment Not Detected
756
+
757
+ - Ensure `expo-constants` is installed: `npx expo install expo-constants`
758
+ - Check that you're using the correct Expo SDK version
759
+
760
+ #### 6. Build Issues
761
+
762
+ - **iOS**: Run `cd ios && pod install` after installing dependencies
763
+ - **Android**: Run `cd android && ./gradlew clean`
764
+ - Clear Metro cache: `npm start -- --reset-cache`
208
765
 
209
766
  ### Debug Mode
210
767
 
211
- Enable debug logging:
768
+ Enable debug logging to troubleshoot issues:
212
769
 
213
770
  ```javascript
771
+ import { SessionRecorder, LogLevel } from '@multiplayer-app/session-recorder-react-native'
772
+
214
773
  SessionRecorder.init({
215
774
  // ... other config
216
- debug: true
775
+ logger: {
776
+ enabled: true,
777
+ level: LogLevel.DEBUG
778
+ }
217
779
  })
218
780
  ```
219
781
 
782
+ ## Examples
783
+
784
+ Check out the complete example applications in the `examples/` directory:
785
+
786
+ - **Bare React Native**: `examples/example-app/` - Full React Native app with session recording
787
+ - **Expo App**: `examples/example-app-expo/` - Expo app with session recording
788
+
789
+ Both examples include:
790
+
791
+ - Complete setup and configuration
792
+ - Navigation integration
793
+ - Session management
794
+ - Error handling
795
+ - Best practices
796
+
797
+ ## API Reference
798
+
799
+ ### SessionRecorder Methods
800
+
801
+ | Method | Description | Parameters |
802
+ | ----------------------------- | ------------------------------- | ------------------------ |
803
+ | `init(options)` | Initialize the session recorder | `SessionRecorderOptions` |
804
+ | `start()` | Start a new recording session | - |
805
+ | `stop(reason?)` | Stop current recording | `string?` |
806
+ | `pause()` | Pause current recording | - |
807
+ | `resume()` | Resume paused recording | - |
808
+ | `save()` | Save continuous recording | - |
809
+ | `setNavigationRef(ref)` | Set navigation reference | `NavigationContainerRef` |
810
+ | `setSessionAttributes(attrs)` | Set session metadata | `Record<string, any>` |
811
+
812
+ ### Configuration Types
813
+
814
+ ```typescript
815
+ interface SessionRecorderOptions {
816
+ // Required
817
+ apiKey: string
818
+ application: string
819
+ version: string
820
+ environment: string
821
+
822
+ // Optional
823
+ exporterEndpoint?: string
824
+ apiBaseUrl?: string
825
+ recordGestures?: boolean
826
+ recordNavigation?: boolean
827
+ recordScreen?: boolean
828
+ sampleTraceRatio?: number
829
+ captureBody?: boolean
830
+ captureHeaders?: boolean
831
+ maxCapturingHttpPayloadSize?: number
832
+ masking?: MaskingOptions
833
+ ignoreUrls?: Array<string | RegExp>
834
+ propagateTraceHeaderCorsUrls?: PropagateTraceHeaderCorsUrls
835
+ showContinuousRecording?: boolean
836
+ schemifyDocSpanPayload?: boolean
837
+ widget?: WidgetConfig
838
+ logger?: {
839
+ level?: number
840
+ enabled?: boolean
841
+ }
842
+ }
843
+ ```
844
+
220
845
  ## Contributing
221
846
 
222
847
  Please read our contributing guidelines before submitting pull requests.