@multiplayer-app/session-recorder-react-native 0.0.1-alpha.1 → 0.0.1-alpha.10
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/RRWEB_INTEGRATION.md +336 -0
- package/VIEWSHOT_INTEGRATION_TEST.md +123 -0
- package/copy-react-native-dist.sh +38 -0
- package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.d.ts +6 -0
- package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js +1 -0
- package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js.map +1 -0
- package/dist/components/GestureCaptureWrapper/index.d.ts +1 -0
- package/dist/components/GestureCaptureWrapper/index.js +1 -0
- package/dist/components/GestureCaptureWrapper/index.js.map +1 -0
- package/dist/components/GestureCaptureWrapper.d.ts +6 -0
- package/dist/components/GestureCaptureWrapper.js +1 -0
- package/dist/components/GestureCaptureWrapper.js.map +1 -0
- package/dist/components/ScreenRecorderView/ScreenRecorderView.d.ts +5 -0
- package/dist/components/ScreenRecorderView/ScreenRecorderView.js +1 -0
- package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -0
- package/dist/components/ScreenRecorderView/index.d.ts +1 -0
- package/dist/components/ScreenRecorderView/index.js +1 -0
- package/dist/components/ScreenRecorderView/index.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -0
- package/dist/config/constants.d.ts +18 -0
- package/dist/config/constants.js +1 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/defaults.d.ts +4 -0
- package/dist/config/defaults.js +1 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/masking.d.ts +2 -30
- package/dist/config/masking.js +1 -1
- package/dist/config/masking.js.map +1 -1
- package/dist/config/session-recorder.d.ts +2 -0
- package/dist/config/session-recorder.js +1 -0
- package/dist/config/session-recorder.js.map +1 -0
- package/dist/config/validators.d.ts +10 -0
- package/dist/config/validators.js +1 -0
- package/dist/config/validators.js.map +1 -0
- package/dist/context/SessionRecorderContext.d.ts +12 -0
- package/dist/context/SessionRecorderContext.js +1 -0
- package/dist/context/SessionRecorderContext.js.map +1 -0
- package/dist/expo.d.ts +5 -9
- package/dist/expo.js +1 -1
- package/dist/expo.js.map +1 -1
- package/dist/index.d.ts +6 -10
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/otel/helpers.d.ts +45 -3
- package/dist/otel/helpers.js +1 -1
- package/dist/otel/helpers.js.map +1 -1
- package/dist/otel/index.d.ts +4 -25
- package/dist/otel/index.js +1 -1
- package/dist/otel/index.js.map +1 -1
- package/dist/otel/instrumentations/gestureInstrumentation.js +1 -1
- package/dist/otel/instrumentations/gestureInstrumentation.js.map +1 -1
- package/dist/otel/instrumentations/index.d.ts +3 -4
- package/dist/otel/instrumentations/index.js +1 -1
- package/dist/otel/instrumentations/index.js.map +1 -1
- package/dist/otel/instrumentations/reactNativeInstrumentation.js +1 -1
- package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +1 -1
- package/dist/otel/instrumentations/reactNavigationInstrumentation.d.ts +1 -0
- package/dist/otel/instrumentations/reactNavigationInstrumentation.js +1 -1
- package/dist/otel/instrumentations/reactNavigationInstrumentation.js.map +1 -1
- package/dist/patch/index.d.ts +1 -0
- package/dist/patch/index.js +1 -0
- package/dist/patch/index.js.map +1 -0
- package/dist/patch/xhr.d.ts +2 -0
- package/dist/patch/xhr.js +1 -0
- package/dist/patch/xhr.js.map +1 -0
- package/dist/recorder/eventExporter.d.ts +21 -0
- package/dist/recorder/eventExporter.js +1 -0
- package/dist/recorder/eventExporter.js.map +1 -0
- package/dist/recorder/gestureHandlerRecorder.d.ts +19 -0
- package/dist/recorder/gestureHandlerRecorder.js +1 -0
- package/dist/recorder/gestureHandlerRecorder.js.map +1 -0
- package/dist/recorder/gestureRecorder.d.ts +68 -11
- package/dist/recorder/gestureRecorder.js +1 -1
- package/dist/recorder/gestureRecorder.js.map +1 -1
- package/dist/recorder/index.d.ts +60 -6
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.js.map +1 -1
- package/dist/recorder/navigationTracker.js +1 -1
- package/dist/recorder/navigationTracker.js.map +1 -1
- package/dist/recorder/screenRecorder.d.ts +79 -10
- package/dist/recorder/screenRecorder.js +1 -1
- package/dist/recorder/screenRecorder.js.map +1 -1
- package/dist/services/api.service.d.ts +62 -10
- package/dist/services/api.service.js +1 -1
- package/dist/services/api.service.js.map +1 -1
- package/dist/services/storage.service.d.ts +23 -16
- package/dist/services/storage.service.js +1 -1
- package/dist/services/storage.service.js.map +1 -1
- package/dist/session-recorder.d.ts +166 -0
- package/dist/session-recorder.js +1 -0
- package/dist/session-recorder.js.map +1 -0
- package/dist/types/index.d.ts +15 -76
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/rrweb.d.ts +118 -0
- package/dist/types/rrweb.js +1 -0
- package/dist/types/rrweb.js.map +1 -0
- package/dist/types/session-recorder.d.ts +366 -0
- package/dist/types/session-recorder.js +1 -0
- package/dist/types/session-recorder.js.map +1 -0
- package/dist/types/session.d.ts +59 -0
- package/dist/types/session.js +1 -0
- package/dist/types/session.js.map +1 -0
- package/dist/utils/app-metadata.d.ts +16 -0
- package/dist/utils/app-metadata.js +1 -0
- package/dist/utils/app-metadata.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +112 -0
- package/dist/utils/logger.js +1 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/platform.d.ts +37 -0
- package/dist/utils/platform.js +1 -1
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/request-utils.d.ts +21 -0
- package/dist/utils/request-utils.js +1 -0
- package/dist/utils/request-utils.js.map +1 -0
- package/dist/utils/rrweb-events.d.ts +65 -0
- package/dist/utils/rrweb-events.js +1 -0
- package/dist/utils/rrweb-events.js.map +1 -0
- package/dist/utils/session.d.ts +5 -0
- package/dist/utils/session.js +1 -0
- package/dist/utils/session.js.map +1 -0
- package/dist/utils/time.d.ts +4 -0
- package/dist/utils/time.js +1 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/type-utils.d.ts +16 -0
- package/dist/utils/type-utils.js +1 -0
- package/dist/utils/type-utils.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/AUTO_METADATA_DETECTION.md +108 -0
- package/package.json +10 -9
- package/scripts/generate-app-metadata.js +173 -0
- package/src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx +86 -0
- package/src/components/GestureCaptureWrapper/index.ts +1 -0
- package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +72 -0
- package/src/components/ScreenRecorderView/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/config/constants.ts +60 -0
- package/src/config/defaults.ts +82 -0
- package/src/config/index.ts +6 -0
- package/src/config/masking.ts +10 -61
- package/src/config/session-recorder.ts +55 -0
- package/src/config/validators.ts +31 -0
- package/src/context/SessionRecorderContext.tsx +75 -0
- package/src/expo.ts +7 -37
- package/src/index.ts +14 -17
- package/src/otel/helpers.ts +265 -11
- package/src/otel/index.ts +37 -247
- package/src/otel/instrumentations/index.ts +82 -53
- package/src/patch/index.ts +1 -0
- package/src/patch/xhr.ts +142 -0
- package/src/recorder/eventExporter.ts +141 -0
- package/src/recorder/gestureRecorder.ts +194 -125
- package/src/recorder/index.ts +132 -24
- package/src/recorder/navigationTracker.ts +12 -10
- package/src/recorder/screenRecorder.ts +242 -155
- package/src/services/api.service.ts +170 -45
- package/src/services/storage.service.ts +102 -74
- package/src/session-recorder.ts +600 -0
- package/src/types/index.ts +19 -79
- package/src/types/session-recorder.ts +423 -0
- package/src/types/session.ts +65 -0
- package/src/utils/app-metadata.ts +31 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.ts +225 -0
- package/src/utils/platform.ts +321 -6
- package/src/utils/request-utils.ts +61 -0
- package/src/utils/rrweb-events.ts +309 -0
- package/src/utils/session.ts +18 -0
- package/src/utils/time.ts +17 -0
- package/src/utils/type-utils.ts +75 -0
- package/src/version.ts +1 -1
- package/dist/sessionRecorder.d.ts +0 -54
- package/dist/sessionRecorder.js +0 -1
- package/dist/sessionRecorder.js.map +0 -1
- package/examples/sample-expo-app/README.md +0 -142
- package/examples/sample-expo-app/app/(tabs)/_layout.tsx +0 -60
- package/examples/sample-expo-app/app/(tabs)/explore.tsx +0 -110
- package/examples/sample-expo-app/app/(tabs)/index.tsx +0 -125
- package/examples/sample-expo-app/app/(tabs)/posts.tsx +0 -96
- package/examples/sample-expo-app/app/(tabs)/users.tsx +0 -131
- package/examples/sample-expo-app/app/+not-found.tsx +0 -32
- package/examples/sample-expo-app/app/_layout.tsx +0 -53
- package/examples/sample-expo-app/app/post/[id].tsx +0 -199
- package/examples/sample-expo-app/app/user/[id].tsx +0 -270
- package/examples/sample-expo-app/app.json +0 -42
- package/examples/sample-expo-app/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/examples/sample-expo-app/assets/images/adaptive-icon.png +0 -0
- package/examples/sample-expo-app/assets/images/favicon.png +0 -0
- package/examples/sample-expo-app/assets/images/icon.png +0 -0
- package/examples/sample-expo-app/assets/images/partial-react-logo.png +0 -0
- package/examples/sample-expo-app/assets/images/react-logo.png +0 -0
- package/examples/sample-expo-app/assets/images/react-logo@2x.png +0 -0
- package/examples/sample-expo-app/assets/images/react-logo@3x.png +0 -0
- package/examples/sample-expo-app/assets/images/splash-icon.png +0 -0
- package/examples/sample-expo-app/components/Collapsible.tsx +0 -45
- package/examples/sample-expo-app/components/ErrorView.tsx +0 -52
- package/examples/sample-expo-app/components/ExternalLink.tsx +0 -24
- package/examples/sample-expo-app/components/HapticTab.tsx +0 -18
- package/examples/sample-expo-app/components/HelloWave.tsx +0 -40
- package/examples/sample-expo-app/components/LoadingSpinner.tsx +0 -34
- package/examples/sample-expo-app/components/ParallaxScrollView.tsx +0 -82
- package/examples/sample-expo-app/components/ThemedText.tsx +0 -60
- package/examples/sample-expo-app/components/ThemedView.tsx +0 -14
- package/examples/sample-expo-app/components/ui/IconSymbol.ios.tsx +0 -32
- package/examples/sample-expo-app/components/ui/IconSymbol.tsx +0 -41
- package/examples/sample-expo-app/components/ui/TabBarBackground.ios.tsx +0 -19
- package/examples/sample-expo-app/components/ui/TabBarBackground.tsx +0 -6
- package/examples/sample-expo-app/constants/Colors.ts +0 -26
- package/examples/sample-expo-app/eslint.config.js +0 -10
- package/examples/sample-expo-app/hooks/useApi.ts +0 -41
- package/examples/sample-expo-app/hooks/useColorScheme.ts +0 -1
- package/examples/sample-expo-app/hooks/useColorScheme.web.ts +0 -21
- package/examples/sample-expo-app/hooks/useThemeColor.ts +0 -21
- package/examples/sample-expo-app/metro.config.js +0 -26
- package/examples/sample-expo-app/package-lock.json +0 -26296
- package/examples/sample-expo-app/package.json +0 -59
- package/examples/sample-expo-app/scripts/reset-project.js +0 -112
- package/examples/sample-expo-app/services/api.ts +0 -98
- package/examples/sample-expo-app/tsconfig.json +0 -17
- package/examples/sample-expo-app/utils/navigation.ts +0 -19
- package/src/otel/instrumentations/gestureInstrumentation.ts +0 -141
- package/src/otel/instrumentations/reactNativeInstrumentation.ts +0 -164
- package/src/otel/instrumentations/reactNavigationInstrumentation.ts +0 -114
- package/src/sessionRecorder.ts +0 -367
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# RRWeb Integration for React Native Session Recorder
|
|
2
|
+
|
|
3
|
+
This document explains the rrweb-compatible event generation system implemented for React Native session recording.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The React Native session recorder automatically generates rrweb-compatible events that can be replayed using standard rrweb players. **No manual intervention is required** - the system automatically captures:
|
|
8
|
+
|
|
9
|
+
1. **Screen snapshots** as `FullSnapshotEvent` with base64-encoded images (periodic + on interaction)
|
|
10
|
+
2. **Touch interactions** as `IncrementalSnapshotEvent` with `MouseInteraction` data (automatic)
|
|
11
|
+
3. **Navigation events** and other user interactions (automatic)
|
|
12
|
+
|
|
13
|
+
**Recording starts automatically when you call `sessionRecorder.start()` and stops when you call `sessionRecorder.stop()`.**
|
|
14
|
+
|
|
15
|
+
### 🚀 **Smart Change Detection**
|
|
16
|
+
|
|
17
|
+
The system now includes **intelligent change detection** that prevents duplicate events:
|
|
18
|
+
|
|
19
|
+
- **Automatic Comparison**: Each screen capture is compared with the previous one
|
|
20
|
+
- **Hash-Based Detection**: Uses lightweight hashing to detect changes quickly
|
|
21
|
+
- **Skip Unchanged Screens**: Only sends events when the screen actually changes
|
|
22
|
+
- **Touch-Triggered Capture**: Forces capture after touch interactions regardless of change detection
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Core Components
|
|
27
|
+
|
|
28
|
+
1. **RRWeb Types** (`src/types/rrweb.ts`)
|
|
29
|
+
|
|
30
|
+
- Complete TypeScript definitions for rrweb events
|
|
31
|
+
- React Native specific types for screen and touch data
|
|
32
|
+
|
|
33
|
+
2. **SessionRecorder** (`src/session-recorder.ts`)
|
|
34
|
+
|
|
35
|
+
- Main entry point with `recordEvent()` method for custom events
|
|
36
|
+
- Automatic touch recording (internal methods)
|
|
37
|
+
- Automatic screen capture coordination
|
|
38
|
+
|
|
39
|
+
3. **ScreenRecorder** (`src/recorder/screenRecorder.ts`)
|
|
40
|
+
|
|
41
|
+
- Captures screenshots and converts to `FullSnapshotEvent`
|
|
42
|
+
- Creates virtual DOM with `<img>` elements containing base64 screenshots
|
|
43
|
+
|
|
44
|
+
4. **GestureRecorder** (`src/recorder/gestureRecorder.ts`)
|
|
45
|
+
|
|
46
|
+
- Automatically converts touch events to rrweb `MouseInteraction` events
|
|
47
|
+
- Maps React Native coordinates to rrweb format
|
|
48
|
+
- Sets up automatic touch capture on session start
|
|
49
|
+
|
|
50
|
+
5. **TouchEventCapture** (`src/context/SessionRecorderContext.tsx`)
|
|
51
|
+
- React component that automatically captures touch events
|
|
52
|
+
- No manual setup required - works automatically when session is active
|
|
53
|
+
|
|
54
|
+
## Event Types Generated
|
|
55
|
+
|
|
56
|
+
### FullSnapshotEvent
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
{
|
|
60
|
+
type: EventType.FullSnapshot,
|
|
61
|
+
data: {
|
|
62
|
+
node: {
|
|
63
|
+
type: 1, // Element node
|
|
64
|
+
id: 1,
|
|
65
|
+
tagName: 'div',
|
|
66
|
+
attributes: { style: 'width: 375px; height: 667px; position: relative;' },
|
|
67
|
+
childNodes: [{
|
|
68
|
+
type: 1,
|
|
69
|
+
id: 2,
|
|
70
|
+
tagName: 'img',
|
|
71
|
+
attributes: {
|
|
72
|
+
src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...',
|
|
73
|
+
width: '375',
|
|
74
|
+
height: '667',
|
|
75
|
+
style: 'width: 375px; height: 667px;'
|
|
76
|
+
}
|
|
77
|
+
}]
|
|
78
|
+
},
|
|
79
|
+
initialOffset: { left: 0, top: 0 }
|
|
80
|
+
},
|
|
81
|
+
timestamp: 1640995200000
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### IncrementalSnapshotEvent (Touch Interactions)
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
{
|
|
89
|
+
type: EventType.IncrementalSnapshot,
|
|
90
|
+
data: {
|
|
91
|
+
source: IncrementalSource.MouseInteraction,
|
|
92
|
+
type: MouseInteractionType.TouchStart, // or TouchMove, TouchEnd
|
|
93
|
+
id: 2, // References the image node ID
|
|
94
|
+
x: 150,
|
|
95
|
+
y: 200
|
|
96
|
+
},
|
|
97
|
+
timestamp: 1640995201000
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Usage
|
|
102
|
+
|
|
103
|
+
### Basic Setup (Automatic Recording)
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { SessionRecorderProvider } from '@multiplayer-app/session-recorder-react-native'
|
|
107
|
+
|
|
108
|
+
function App() {
|
|
109
|
+
return (
|
|
110
|
+
<SessionRecorderProvider
|
|
111
|
+
options={{
|
|
112
|
+
apiKey: 'your-api-key',
|
|
113
|
+
version: '1.0.0',
|
|
114
|
+
application: 'MyApp',
|
|
115
|
+
environment: 'production',
|
|
116
|
+
recordScreen: true, // Automatic screen capture
|
|
117
|
+
recordGestures: true // Automatic touch recording
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
<YourAppContent />
|
|
121
|
+
</SessionRecorderProvider>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**That's it!** Recording is now automatic. When you start a session, the system will:
|
|
127
|
+
|
|
128
|
+
- Automatically capture screen snapshots periodically
|
|
129
|
+
- Automatically record all touch interactions
|
|
130
|
+
- Generate rrweb-compatible events without any manual intervention
|
|
131
|
+
|
|
132
|
+
### Custom Event Recording (Optional)
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { useSessionRecorder } from '@multiplayer-app/session-recorder-react-native'
|
|
136
|
+
|
|
137
|
+
function MyComponent() {
|
|
138
|
+
const { client } = useSessionRecorder()
|
|
139
|
+
|
|
140
|
+
const handleCustomEvent = () => {
|
|
141
|
+
// Record a custom rrweb event (optional)
|
|
142
|
+
client.recordEvent({
|
|
143
|
+
type: EventType.Custom,
|
|
144
|
+
data: { customData: 'value' },
|
|
145
|
+
timestamp: Date.now()
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return <Button onPress={handleCustomEvent} title='Record Custom Event' />
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Integration Points
|
|
154
|
+
|
|
155
|
+
### Screen Capture Integration
|
|
156
|
+
|
|
157
|
+
The `ScreenRecorder` class now includes **complete react-native-view-shot integration**:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// In screenRecorder.ts - _captureScreenBase64 method
|
|
161
|
+
private async _captureScreenBase64(): Promise<string | null> {
|
|
162
|
+
try {
|
|
163
|
+
if (!this.viewShotRef) {
|
|
164
|
+
console.warn('ViewShot ref not available for screen capture')
|
|
165
|
+
return null
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Capture the screen using react-native-view-shot
|
|
169
|
+
const result = await captureRef(this.viewShotRef, {
|
|
170
|
+
format: this.captureFormat,
|
|
171
|
+
quality: this.captureQuality,
|
|
172
|
+
result: 'base64'
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
return result
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error('Failed to capture screen:', error)
|
|
178
|
+
return null
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**The ViewShot ref is automatically set up** in the `TouchEventCapture` component, so no manual configuration is needed!
|
|
184
|
+
|
|
185
|
+
### Automatic ViewShot Setup
|
|
186
|
+
|
|
187
|
+
The `TouchEventCapture` component automatically sets up the ViewShot ref:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// In SessionRecorderContext.tsx
|
|
191
|
+
const TouchEventCapture: React.FC<{ children: ReactNode }> = ({ children }) => {
|
|
192
|
+
const context = useContext(SessionRecorderContext)
|
|
193
|
+
const viewShotRef = useRef<View>(null)
|
|
194
|
+
|
|
195
|
+
// Callback ref to set the viewshot ref immediately when available
|
|
196
|
+
const setViewShotRef = (ref: View | null) => {
|
|
197
|
+
if (ref && context?.client) {
|
|
198
|
+
context.client.setViewShotRef?.(ref)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<View
|
|
204
|
+
ref={(ref) => {
|
|
205
|
+
viewShotRef.current = ref
|
|
206
|
+
setViewShotRef(ref)
|
|
207
|
+
}}
|
|
208
|
+
style={{ flex: 1 }}
|
|
209
|
+
onTouchStart={handleTouchStart}
|
|
210
|
+
onTouchMove={handleTouchMove}
|
|
211
|
+
onTouchEnd={handleTouchEnd}
|
|
212
|
+
>
|
|
213
|
+
{children}
|
|
214
|
+
</View>
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
This ensures that:
|
|
220
|
+
|
|
221
|
+
- The same View that captures touch events is used for screen capture
|
|
222
|
+
- Perfect synchronization between touch interactions and screen captures
|
|
223
|
+
- No manual ref setup required
|
|
224
|
+
|
|
225
|
+
### Required Dependencies
|
|
226
|
+
|
|
227
|
+
Add these to your `package.json`:
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"dependencies": {
|
|
232
|
+
"react-native-view-shot": "^3.8.0"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Automatic Event Flow
|
|
238
|
+
|
|
239
|
+
1. **Session Start**: `SessionRecorder.start()` automatically initializes all recorders
|
|
240
|
+
2. **Automatic Screen Capture**: `ScreenRecorder` automatically captures screenshots periodically + on interactions
|
|
241
|
+
3. **Automatic Touch Events**: `TouchEventCapture` automatically captures all touch interactions
|
|
242
|
+
4. **Automatic Event Generation**: Touch events are automatically converted to rrweb `MouseInteraction` events
|
|
243
|
+
5. **Automatic Event Recording**: All events are automatically stored and can be exported
|
|
244
|
+
|
|
245
|
+
**No manual intervention required!** The entire process is automatic once you start a session.
|
|
246
|
+
|
|
247
|
+
## Customization
|
|
248
|
+
|
|
249
|
+
### Screen Capture Frequency
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// Adjust capture interval in ScreenRecorder
|
|
253
|
+
screenRecorder.setCaptureInterval(3000) // Capture every 3 seconds
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Change Detection Configuration
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// Enable/disable change detection
|
|
260
|
+
screenRecorder.setChangeDetection(true) // Default: true
|
|
261
|
+
|
|
262
|
+
// Adjust hash sample size for change detection
|
|
263
|
+
screenRecorder.setHashSampleSize(200) // Default: 100 characters
|
|
264
|
+
|
|
265
|
+
// Force capture (bypasses change detection)
|
|
266
|
+
screenRecorder.forceCapture()
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Touch Event Throttling
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
// Adjust gesture throttling in GestureRecorder
|
|
273
|
+
gestureRecorder.setGestureThrottle(100) // Throttle to 100ms
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Event Filtering
|
|
277
|
+
|
|
278
|
+
You can filter events by modifying the `recordEvent` method in `SessionRecorder`:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
recordEvent(event: RRWebEvent): void {
|
|
282
|
+
if (!this._isInitialized || this.sessionState !== SessionState.started) {
|
|
283
|
+
return
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Add custom filtering logic here
|
|
287
|
+
if (event.type === EventType.IncrementalSnapshot) {
|
|
288
|
+
// Filter out certain touch events if needed
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
this._recorder.recordEvent(event)
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Exporting Events
|
|
296
|
+
|
|
297
|
+
To export recorded events for rrweb playback:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
const events = sessionRecorder.getRecordedEvents()
|
|
301
|
+
// Save events to file or send to server
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Troubleshooting
|
|
305
|
+
|
|
306
|
+
### Common Issues
|
|
307
|
+
|
|
308
|
+
1. **Screen capture not working**: Ensure `react-native-view-shot` is properly installed and configured
|
|
309
|
+
2. **Touch events not recorded**: Check that `TouchEventCapture` wraps your app content
|
|
310
|
+
3. **Events not generated**: Verify session is in `started` state
|
|
311
|
+
|
|
312
|
+
### Debug Mode
|
|
313
|
+
|
|
314
|
+
Enable debug logging by setting:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// In your app configuration
|
|
318
|
+
console.log('Recording stats:', sessionRecorder.getRecordingStats())
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Future Enhancements
|
|
322
|
+
|
|
323
|
+
- [ ] Support for multiple screen orientations
|
|
324
|
+
- [ ] Gesture recognition and classification
|
|
325
|
+
- [ ] Performance optimization for large sessions
|
|
326
|
+
- [ ] Integration with additional React Native libraries
|
|
327
|
+
- [ ] Custom event types for React Native specific interactions
|
|
328
|
+
|
|
329
|
+
## Compatibility
|
|
330
|
+
|
|
331
|
+
This implementation is compatible with:
|
|
332
|
+
|
|
333
|
+
- rrweb 1.x and 2.x
|
|
334
|
+
- React Native 0.60+
|
|
335
|
+
- iOS and Android platforms
|
|
336
|
+
- Standard rrweb players and replay tools
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# ViewShot Integration Test
|
|
2
|
+
|
|
3
|
+
This document explains how to test the complete react-native-view-shot integration.
|
|
4
|
+
|
|
5
|
+
## Test Setup
|
|
6
|
+
|
|
7
|
+
1. **Install Dependencies**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install react-native-view-shot
|
|
11
|
+
# For iOS
|
|
12
|
+
cd ios && pod install && cd ..
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
2. **Test the Integration**
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import React from 'react'
|
|
19
|
+
import { View, Text, Button } from 'react-native'
|
|
20
|
+
import { SessionRecorderProvider, useSessionRecorder } from './src/context/SessionRecorderContext'
|
|
21
|
+
|
|
22
|
+
function TestApp() {
|
|
23
|
+
const { client } = useSessionRecorder()
|
|
24
|
+
|
|
25
|
+
const testScreenCapture = async () => {
|
|
26
|
+
// Start session to enable automatic screen capture
|
|
27
|
+
await client.start()
|
|
28
|
+
|
|
29
|
+
// Wait a moment for initial screen capture
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
console.log('Screen capture should have happened automatically!')
|
|
32
|
+
// Check the recorded events
|
|
33
|
+
const events = client.getRecordedEvents?.()
|
|
34
|
+
console.log('Recorded events:', events)
|
|
35
|
+
}, 2000)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<View style={{ flex: 1, padding: 20 }}>
|
|
40
|
+
<Text>ViewShot Integration Test</Text>
|
|
41
|
+
<Button title='Test Screen Capture' onPress={testScreenCapture} />
|
|
42
|
+
<Text>Touch the screen to test touch recording</Text>
|
|
43
|
+
</View>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default function App() {
|
|
48
|
+
return (
|
|
49
|
+
<SessionRecorderProvider
|
|
50
|
+
options={{
|
|
51
|
+
apiKey: 'test-key',
|
|
52
|
+
version: '1.0.0',
|
|
53
|
+
application: 'TestApp',
|
|
54
|
+
environment: 'test',
|
|
55
|
+
recordScreen: true,
|
|
56
|
+
recordGestures: true
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
<TestApp />
|
|
60
|
+
</SessionRecorderProvider>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Expected Behavior
|
|
66
|
+
|
|
67
|
+
When you run this test:
|
|
68
|
+
|
|
69
|
+
1. **Automatic Screen Capture**: The system should automatically capture the screen when the session starts
|
|
70
|
+
2. **Touch Recording**: Touching the screen should generate rrweb MouseInteraction events
|
|
71
|
+
3. **ViewShot Integration**: The same View that handles touch events should be used for screen capture
|
|
72
|
+
4. **Event Generation**: Both FullSnapshotEvent and IncrementalSnapshotEvent should be generated
|
|
73
|
+
|
|
74
|
+
## Verification Steps
|
|
75
|
+
|
|
76
|
+
1. **Check Console Logs**: Look for screen capture success/failure messages
|
|
77
|
+
2. **Verify Events**: Check that `getRecordedEvents()` returns both screen and touch events
|
|
78
|
+
3. **Test Touch Interactions**: Touch the screen and verify touch events are recorded
|
|
79
|
+
4. **Check Event Format**: Ensure events are in proper rrweb format
|
|
80
|
+
|
|
81
|
+
## Troubleshooting
|
|
82
|
+
|
|
83
|
+
### Common Issues
|
|
84
|
+
|
|
85
|
+
1. **"ViewShot ref not available"**: The ref setup might be timing-related
|
|
86
|
+
|
|
87
|
+
- Solution: Ensure the SessionRecorderProvider wraps your app properly
|
|
88
|
+
|
|
89
|
+
2. **Screen capture fails**: react-native-view-shot might not be properly installed
|
|
90
|
+
|
|
91
|
+
- Solution: Check installation and run `pod install` for iOS
|
|
92
|
+
|
|
93
|
+
3. **No events recorded**: Session might not be started
|
|
94
|
+
- Solution: Call `client.start()` before testing
|
|
95
|
+
|
|
96
|
+
### Debug Information
|
|
97
|
+
|
|
98
|
+
Add this to your test component to debug:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const debugInfo = () => {
|
|
102
|
+
console.log('Session State:', client.sessionState)
|
|
103
|
+
console.log('Is Recording:', client.isRecording)
|
|
104
|
+
console.log('Events Count:', client.getRecordedEvents?.()?.length || 0)
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Success Criteria
|
|
109
|
+
|
|
110
|
+
✅ Screen capture works automatically when session starts
|
|
111
|
+
✅ Touch events are recorded automatically
|
|
112
|
+
✅ Events are in proper rrweb format
|
|
113
|
+
✅ No manual ref setup required
|
|
114
|
+
✅ Perfect synchronization between touch and screen events
|
|
115
|
+
|
|
116
|
+
## Next Steps
|
|
117
|
+
|
|
118
|
+
Once the test passes:
|
|
119
|
+
|
|
120
|
+
1. Integrate into your main app
|
|
121
|
+
2. Configure capture intervals and quality as needed
|
|
122
|
+
3. Export events for rrweb playback
|
|
123
|
+
4. Customize event filtering if required
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Exit on any error
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
# Configuration
|
|
7
|
+
SOURCE_DIR="./dist"
|
|
8
|
+
TARGET_DIR="../../../sample-expo-app/node_modules/@multiplayer-app/session-recorder-react-native"
|
|
9
|
+
|
|
10
|
+
echo "📱 Copying React Native dist to sample Expo app..."
|
|
11
|
+
|
|
12
|
+
# Check if source directory exists
|
|
13
|
+
if [ ! -d "$SOURCE_DIR" ]; then
|
|
14
|
+
echo "❌ Source directory does not exist: $SOURCE_DIR"
|
|
15
|
+
echo "💡 Please run 'npm run build' in the session-recorder-react-native package first"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Check if target directory exists
|
|
20
|
+
if [ ! -d "$TARGET_DIR" ]; then
|
|
21
|
+
echo "❌ Target directory does not exist: $TARGET_DIR"
|
|
22
|
+
echo "💡 Please make sure the sample-expo-app is set up and has the package installed"
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Create backup of existing dist if it exists
|
|
27
|
+
if [ -d "$TARGET_DIR/dist" ]; then
|
|
28
|
+
echo "📦 Creating backup of existing dist..."
|
|
29
|
+
cp -r "$TARGET_DIR/dist" "$TARGET_DIR/dist.backup.$(date +%Y%m%d_%H%M%S)"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Copy the dist folder
|
|
33
|
+
echo "🔄 Copying dist folder..."
|
|
34
|
+
cp -r "$SOURCE_DIR" "$TARGET_DIR/"
|
|
35
|
+
|
|
36
|
+
echo "✅ Successfully copied dist folder to sample Expo app!"
|
|
37
|
+
echo "📍 Source: $SOURCE_DIR"
|
|
38
|
+
echo "📍 Target: $TARGET_DIR/dist"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var _typeof=require("@babel/runtime/helpers/typeof");Object.defineProperty(exports,"__esModule",{value:true});exports.GestureCaptureWrapper=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNativeGestureHandler=require("react-native-gesture-handler");var _jsxRuntime=require("react/jsx-runtime");var _this=void 0,_jsxFileName="/Users/gegham/www/multiplayer-debugger-javascript/packages/session-recorder-react-native/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js";function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,"default":e};if(null===e||"object"!=_typeof(e)&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f);}for(var _t2 in e)"default"!==_t2&&{}.hasOwnProperty.call(e,_t2)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,_t2))&&(i.get||i.set)?o(f,_t2,i):f[_t2]=e[_t2]);return f;})(e,t);}var GestureCaptureWrapper=exports.GestureCaptureWrapper=function GestureCaptureWrapper(_ref){var children=_ref.children,onGestureRecord=_ref.onGestureRecord;var recordGesture=(0,_react.useCallback)(function(gestureType,data){onGestureRecord(gestureType,data);},[onGestureRecord]);var tapGesture=(0,_react.useMemo)(function(){return _reactNativeGestureHandler.Gesture.Tap().runOnJS(true).onStart(function(event){recordGesture('tap',{x:event.x,y:event.y,timestamp:Date.now()});});},[recordGesture]);var panGesture=(0,_react.useMemo)(function(){return _reactNativeGestureHandler.Gesture.Pan().runOnJS(true).onStart(function(event){recordGesture('pan_start',{x:event.x,y:event.y,timestamp:Date.now()});}).onUpdate(function(event){recordGesture('pan_update',{x:event.x,y:event.y,translationX:event.translationX,translationY:event.translationY,velocityX:event.velocityX,velocityY:event.velocityY,timestamp:Date.now()});}).onEnd(function(event){recordGesture('pan_end',{x:event.x,y:event.y,translationX:event.translationX,translationY:event.translationY,velocityX:event.velocityX,velocityY:event.velocityY,timestamp:Date.now()});});},[recordGesture]);var longPressGesture=(0,_react.useMemo)(function(){return _reactNativeGestureHandler.Gesture.LongPress().runOnJS(true).minDuration(500).onStart(function(event){recordGesture('long_press',{x:event.x,y:event.y,duration:500,timestamp:Date.now()});});},[recordGesture]);return(0,_jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView,{style:{flex:1},children:(0,_jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector,{gesture:_reactNativeGestureHandler.Gesture.Simultaneous(tapGesture,panGesture,longPressGesture),children:children})});};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GestureCaptureWrapper.js","sourceRoot":"","sources":["../../../src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./GestureCaptureWrapper";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _GestureCaptureWrapper=require("./GestureCaptureWrapper");Object.keys(_GestureCaptureWrapper).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_GestureCaptureWrapper[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _GestureCaptureWrapper[key];}});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/GestureCaptureWrapper/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var _typeof=require("@babel/runtime/helpers/typeof");Object.defineProperty(exports,"__esModule",{value:true});exports.GestureCaptureWrapper=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNativeGestureHandler=require("react-native-gesture-handler");var _jsxRuntime=require("react/jsx-runtime");var _this=void 0,_jsxFileName="/Users/gegham/www/multiplayer-debugger-javascript/packages/session-recorder-react-native/dist/components/GestureCaptureWrapper.js";function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,"default":e};if(null===e||"object"!=_typeof(e)&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f);}for(var _t2 in e)"default"!==_t2&&{}.hasOwnProperty.call(e,_t2)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,_t2))&&(i.get||i.set)?o(f,_t2,i):f[_t2]=e[_t2]);return f;})(e,t);}var GestureCaptureWrapper=exports.GestureCaptureWrapper=function GestureCaptureWrapper(_ref){var children=_ref.children,onGestureRecord=_ref.onGestureRecord;var recordGesture=(0,_react.useCallback)(function(gestureType,data){onGestureRecord(gestureType,data);},[onGestureRecord]);var tapGesture=(0,_react.useMemo)(function(){return _reactNativeGestureHandler.Gesture.Tap().runOnJS(true).onStart(function(event){recordGesture('tap',{x:event.x,y:event.y,timestamp:Date.now()});});},[recordGesture]);var panGesture=(0,_react.useMemo)(function(){return _reactNativeGestureHandler.Gesture.Pan().runOnJS(true).onStart(function(event){recordGesture('pan_start',{x:event.x,y:event.y,timestamp:Date.now()});}).onUpdate(function(event){recordGesture('pan_update',{x:event.x,y:event.y,translationX:event.translationX,translationY:event.translationY,velocityX:event.velocityX,velocityY:event.velocityY,timestamp:Date.now()});}).onEnd(function(event){recordGesture('pan_end',{x:event.x,y:event.y,translationX:event.translationX,translationY:event.translationY,velocityX:event.velocityX,velocityY:event.velocityY,timestamp:Date.now()});});},[recordGesture]);var longPressGesture=(0,_react.useMemo)(function(){return _reactNativeGestureHandler.Gesture.LongPress().runOnJS(true).minDuration(500).onStart(function(event){recordGesture('long_press',{x:event.x,y:event.y,duration:500,timestamp:Date.now()});});},[recordGesture]);return(0,_jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView,{style:{flex:1},children:(0,_jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector,{gesture:_reactNativeGestureHandler.Gesture.Simultaneous(tapGesture,panGesture,longPressGesture),children:children})});};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GestureCaptureWrapper.js","sourceRoot":"","sources":["../../src/components/GestureCaptureWrapper.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");var _typeof=require("@babel/runtime/helpers/typeof");Object.defineProperty(exports,"__esModule",{value:true});exports.ScreenRecorderView=void 0;var _sessionRecorderReactNative=_interopRequireDefault(require("@multiplayer-app/session-recorder-react-native"));var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _types=require("../../types");var _utils=require("../../utils");var _GestureCaptureWrapper=require("../GestureCaptureWrapper");var _jsxRuntime=require("react/jsx-runtime");var _this=void 0,_jsxFileName="/Users/gegham/www/multiplayer-debugger-javascript/packages/session-recorder-react-native/dist/components/ScreenRecorderView/ScreenRecorderView.js";function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,"default":e};if(null===e||"object"!=_typeof(e)&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f);}for(var _t2 in e)"default"!==_t2&&{}.hasOwnProperty.call(e,_t2)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,_t2))&&(i.get||i.set)?o(f,_t2,i):f[_t2]=e[_t2]);return f;})(e,t);}var ScreenRecorderView=exports.ScreenRecorderView=function ScreenRecorderView(_ref){var children=_ref.children;var handleGestureRecord=(0,_react.useCallback)(function(gestureType,data){var _a,_b,_c,_d,_e,_f,_g;if(_sessionRecorderReactNative["default"].sessionState!==_types.SessionState.started){_utils.logger.debug('SessionRecorderContext','Gesture recording skipped',{client:!!_sessionRecorderReactNative["default"].sessionState,sessionState:_sessionRecorderReactNative["default"].sessionState});return;}_utils.logger.debug('SessionRecorderContext','Gesture recorded',{gestureType:gestureType,data:data});try{switch(gestureType){case'tap':_utils.logger.debug('SessionRecorderContext','Recording tap as touch start + end');(_a=_sessionRecorderReactNative["default"].recordTouchStart)===null||_a===void 0?void 0:_a.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);(_b=_sessionRecorderReactNative["default"].recordTouchEnd)===null||_b===void 0?void 0:_b.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);break;case'pan_start':_utils.logger.debug('SessionRecorderContext','Recording pan_start as touch start');(_c=_sessionRecorderReactNative["default"].recordTouchStart)===null||_c===void 0?void 0:_c.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);break;case'pan_update':_utils.logger.debug('SessionRecorderContext','Recording pan_update as touch move');(_d=_sessionRecorderReactNative["default"].recordTouchMove)===null||_d===void 0?void 0:_d.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);break;case'pan_end':_utils.logger.debug('SessionRecorderContext','Recording pan_end as touch end');(_e=_sessionRecorderReactNative["default"].recordTouchEnd)===null||_e===void 0?void 0:_e.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);break;case'long_press':_utils.logger.debug('SessionRecorderContext','Recording long_press as touch start + end');(_f=_sessionRecorderReactNative["default"].recordTouchStart)===null||_f===void 0?void 0:_f.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);(_g=_sessionRecorderReactNative["default"].recordTouchEnd)===null||_g===void 0?void 0:_g.call(_sessionRecorderReactNative["default"],data.x,data.y,undefined,1.0);break;default:}}catch(error){_utils.logger.error('SessionRecorderContext','Failed to record gesture event',error);}},[]);var setViewShotRef=function setViewShotRef(ref){var _a;if(ref){(_a=_sessionRecorderReactNative["default"].setViewShotRef)===null||_a===void 0?void 0:_a.call(_sessionRecorderReactNative["default"],ref);}};return(0,_jsxRuntime.jsx)(_GestureCaptureWrapper.GestureCaptureWrapper,{onGestureRecord:handleGestureRecord,children:(0,_jsxRuntime.jsx)(_reactNative.View,{ref:setViewShotRef,style:{flex:1},children:children})});};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenRecorderView.js","sourceRoot":"","sources":["../../../src/components/ScreenRecorderView/ScreenRecorderView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ScreenRecorderView";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _ScreenRecorderView=require("./ScreenRecorderView");Object.keys(_ScreenRecorderView).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_ScreenRecorderView[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _ScreenRecorderView[key];}});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ScreenRecorderView/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './GestureCaptureWrapper';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _GestureCaptureWrapper=require("./GestureCaptureWrapper");Object.keys(_GestureCaptureWrapper).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_GestureCaptureWrapper[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _GestureCaptureWrapper[key];}});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const OTEL_MP_SAMPLE_TRACE_RATIO = 0.15;
|
|
2
|
+
export declare const SESSION_ID_PROP_NAME = "multiplayer-session-id";
|
|
3
|
+
export declare const SESSION_SHORT_ID_PROP_NAME = "multiplayer-session-short-id";
|
|
4
|
+
export declare const SESSION_CONTINUOUS_DEBUGGING_PROP_NAME = "multiplayer-session-continuous-debugging";
|
|
5
|
+
export declare const SESSION_STATE_PROP_NAME = "multiplayer-session-state";
|
|
6
|
+
export declare const SESSION_TYPE_PROP_NAME = "multiplayer-session-type";
|
|
7
|
+
export declare const SESSION_PROP_NAME = "multiplayer-session-data";
|
|
8
|
+
export declare const SESSION_STARTED_EVENT = "debug-session:started";
|
|
9
|
+
export declare const SESSION_STOPPED_EVENT = "debug-session:stopped";
|
|
10
|
+
export declare const SESSION_SUBSCRIBE_EVENT = "debug-session:subscribe";
|
|
11
|
+
export declare const SESSION_UNSUBSCRIBE_EVENT = "debug-session:unsubscribe";
|
|
12
|
+
export declare const SESSION_AUTO_CREATED = "debug-session:auto-created";
|
|
13
|
+
export declare const SESSION_ADD_EVENT = "debug-session:rrweb:add-event";
|
|
14
|
+
export declare const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
|
|
15
|
+
export declare const SESSION_RESPONSE = "multiplayer-debug-session-response";
|
|
16
|
+
export declare const CONTINUOUS_DEBUGGING_TIMEOUT = 60000;
|
|
17
|
+
export declare const DEBUG_SESSION_MAX_DURATION_SECONDS: number;
|
|
18
|
+
export declare const OTEL_IGNORE_URLS: RegExp[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SESSION_UNSUBSCRIBE_EVENT=exports.SESSION_TYPE_PROP_NAME=exports.SESSION_SUBSCRIBE_EVENT=exports.SESSION_STOPPED_EVENT=exports.SESSION_STATE_PROP_NAME=exports.SESSION_STARTED_EVENT=exports.SESSION_SHORT_ID_PROP_NAME=exports.SESSION_RESPONSE=exports.SESSION_PROP_NAME=exports.SESSION_ID_PROP_NAME=exports.SESSION_CONTINUOUS_DEBUGGING_PROP_NAME=exports.SESSION_AUTO_CREATED=exports.SESSION_ADD_EVENT=exports.OTEL_MP_SAMPLE_TRACE_RATIO=exports.OTEL_IGNORE_URLS=exports.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE=exports.DEBUG_SESSION_MAX_DURATION_SECONDS=exports.CONTINUOUS_DEBUGGING_TIMEOUT=void 0;var OTEL_MP_SAMPLE_TRACE_RATIO=exports.OTEL_MP_SAMPLE_TRACE_RATIO=0.15;var SESSION_ID_PROP_NAME=exports.SESSION_ID_PROP_NAME='multiplayer-session-id';var SESSION_SHORT_ID_PROP_NAME=exports.SESSION_SHORT_ID_PROP_NAME='multiplayer-session-short-id';var SESSION_CONTINUOUS_DEBUGGING_PROP_NAME=exports.SESSION_CONTINUOUS_DEBUGGING_PROP_NAME='multiplayer-session-continuous-debugging';var SESSION_STATE_PROP_NAME=exports.SESSION_STATE_PROP_NAME='multiplayer-session-state';var SESSION_TYPE_PROP_NAME=exports.SESSION_TYPE_PROP_NAME='multiplayer-session-type';var SESSION_PROP_NAME=exports.SESSION_PROP_NAME='multiplayer-session-data';var SESSION_STARTED_EVENT=exports.SESSION_STARTED_EVENT='debug-session:started';var SESSION_STOPPED_EVENT=exports.SESSION_STOPPED_EVENT='debug-session:stopped';var SESSION_SUBSCRIBE_EVENT=exports.SESSION_SUBSCRIBE_EVENT='debug-session:subscribe';var SESSION_UNSUBSCRIBE_EVENT=exports.SESSION_UNSUBSCRIBE_EVENT='debug-session:unsubscribe';var SESSION_AUTO_CREATED=exports.SESSION_AUTO_CREATED='debug-session:auto-created';var SESSION_ADD_EVENT=exports.SESSION_ADD_EVENT='debug-session:rrweb:add-event';var DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE=exports.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE=100000;var SESSION_RESPONSE=exports.SESSION_RESPONSE='multiplayer-debug-session-response';var CONTINUOUS_DEBUGGING_TIMEOUT=exports.CONTINUOUS_DEBUGGING_TIMEOUT=60000;var DEBUG_SESSION_MAX_DURATION_SECONDS=exports.DEBUG_SESSION_MAX_DURATION_SECONDS=10*60+30;var OTEL_IGNORE_URLS=exports.OTEL_IGNORE_URLS=[/.*\/v1\/traces/,/.*\/v0\/radar\/debug-sessions\/start$/,/.*\/v0\/radar\/debug-sessions\/[^/]+\/stop$/,/.*\/v0\/radar\/debug-sessions\/[^/]+\/cancel$/,/.*\/v0\/radar\/continuous-debug-sessions\/start$/,/.*\/v0\/radar\/continuous-debug-sessions\/[^/]+\/save$/,/.*\/v0\/radar\/continuous-debug-sessions\/[^/]+\/cancel$/,/.*\/v0\/radar\/remote-debug-session\/check$/];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/config/constants.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAA;AAE9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAA;AAE5D,MAAM,CAAC,MAAM,0BAA0B,GAAG,8BAA8B,CAAA;AAExE,MAAM,CAAC,MAAM,sCAAsC,GAAG,0CAA0C,CAAA;AAEhG,MAAM,CAAC,MAAM,uBAAuB,GAAG,2BAA2B,CAAA;AAElE,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAA;AAE3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAE5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAE5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAA;AAEhE,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AAEpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAA4B,CAAA;AAEhE,MAAM,CAAC,MAAM,iBAAiB,GAAG,+BAA+B,CAAA;AAEhE,MAAM,CAAC,MAAM,uCAAuC,GAAG,MAAM,CAAA;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,oCAAoC,CAAA;AAEpE,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAA,CAAC,YAAY;AAE9D,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA,CAAC,wCAAwC;AAEvG,wDAAwD;AACxD,wCAAwC;AACxC,mEAAmE;AAGnE,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,kBAAkB;IAClB,gBAAgB;IAChB,2BAA2B;IAC3B,uCAAuC;IACvC,6CAA6C;IAC7C,+CAA+C;IAE/C,sCAAsC;IACtC,kDAAkD;IAClD,wDAAwD;IACxD,0DAA0D;IAE1D,gCAAgC;IAChC,6CAA6C;IAE7C,iEAAiE;IACjE,sBAAsB;CACvB,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { MaskingConfig, SessionRecorderConfigs, WidgetTextOverridesConfig } from '../types';
|
|
2
|
+
export declare const DEFAULT_MASKING_CONFIG: MaskingConfig;
|
|
3
|
+
export declare const DEFAULT_WIDGET_TEXT_CONFIG: WidgetTextOverridesConfig;
|
|
4
|
+
export declare const BASE_CONFIG: Required<SessionRecorderConfigs>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DEFAULT_WIDGET_TEXT_CONFIG=exports.DEFAULT_MASKING_CONFIG=exports.BASE_CONFIG=void 0;var _sessionRecorderCommon=require("@multiplayer-app/session-recorder-common");var _types=require("../types");var _constants=require("./constants");var mask=_sessionRecorderCommon.SessionRecorderSdk.mask,sensitiveFields=_sessionRecorderCommon.SessionRecorderSdk.sensitiveFields,sensitiveHeaders=_sessionRecorderCommon.SessionRecorderSdk.sensitiveHeaders;var DEFAULT_MASKING_CONFIG=exports.DEFAULT_MASKING_CONFIG={isContentMaskingEnabled:true,maskBody:mask(sensitiveFields),maskHeaders:mask(sensitiveHeaders),maskBodyFieldsList:sensitiveFields,maskHeadersList:sensitiveHeaders,headersToInclude:[],headersToExclude:[]};var DEFAULT_WIDGET_TEXT_CONFIG=exports.DEFAULT_WIDGET_TEXT_CONFIG={initialTitleWithContinuous:'Encountered an issue?',initialTitleWithoutContinuous:'Encountered an issue?',initialDescriptionWithContinuous:'Record your session so we can see the problem and fix it faster.',initialDescriptionWithoutContinuous:'Record your session so we can see the problem and fix it faster.',continuousRecordingLabel:'Continuous recording',startRecordingButtonText:'Start recording',finalTitle:'Done recording?',finalDescription:'You can also add a quick note with extra context, expectations, or questions. Thank you!',commentPlaceholder:'Add a message...',saveButtonText:'Submit recording',cancelButtonText:'Cancel recording',continuousOverlayTitle:'Save time, skip the reproductions',continuousOverlayDescription:'We keep a rolling record of your recent activity. If something doesn’t work as expected, just save the recording and continue working. No need to worry about exceptions and errors - we automatically save recordings for those!',saveLastSnapshotButtonText:'Save recording',submitDialogTitle:'Save recording',submitDialogSubtitle:'This full-stack session recording will be saved directly to your selected Multiplayer project. All data is automatically correlated end-to-end.',submitDialogCommentLabel:'You can also add context, comments, or notes.',submitDialogCommentPlaceholder:'Add a message...',submitDialogSubmitText:'Save',submitDialogCancelText:'Cancel'};var BASE_CONFIG=exports.BASE_CONFIG={apiKey:'',version:'',application:'',environment:'',showWidget:true,showContinuousRecording:true,widgetButtonPlacement:_types.WidgetButtonPlacement.bottomRight,usePostMessageFallback:false,apiBaseUrl:_sessionRecorderCommon.MULTIPLAYER_BASE_API_URL,exporterEndpoint:_sessionRecorderCommon.MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL,schemifyDocSpanPayload:true,ignoreUrls:[],propagateTraceHeaderCorsUrls:[],sampleTraceRatio:_constants.OTEL_MP_SAMPLE_TRACE_RATIO,maxCapturingHttpPayloadSize:_constants.DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE,captureBody:true,captureHeaders:true,masking:DEFAULT_MASKING_CONFIG,widgetTextOverrides:DEFAULT_WIDGET_TEXT_CONFIG,recordScreen:true,recordGestures:true,recordNavigation:true};
|