@multiplayer-app/session-recorder-react-native 0.0.1-beta.7 → 0.0.1-beta.8

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 (74) hide show
  1. package/docs/NATIVE_MODULE_SETUP.md +175 -0
  2. package/ios/SessionRecorderNative.podspec +5 -0
  3. package/package.json +11 -1
  4. package/plugin/package.json +20 -0
  5. package/plugin/src/index.js +42 -0
  6. package/android/src/main/AndroidManifest.xml +0 -2
  7. package/android/src/main/java/com/multiplayer/sessionrecorder/ScreenMaskingModule.kt +0 -202
  8. package/android/src/main/java/com/multiplayer/sessionrecorder/ScreenMaskingPackage.kt +0 -16
  9. package/android/src/main/java/com/multiplayer/sessionrecorder/SessionRecorderModule.kt +0 -202
  10. package/android/src/main/java/com/multiplayer/sessionrecorder/SessionRecorderPackage.kt +0 -16
  11. package/babel.config.js +0 -13
  12. package/docs/AUTO_METADATA_DETECTION.md +0 -108
  13. package/docs/TROUBLESHOOTING.md +0 -168
  14. package/ios/ScreenMasking.m +0 -12
  15. package/ios/ScreenMasking.podspec +0 -21
  16. package/ios/ScreenMasking.swift +0 -205
  17. package/ios/SessionRecorder.podspec +0 -21
  18. package/scripts/generate-app-metadata.js +0 -173
  19. package/src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx +0 -86
  20. package/src/components/GestureCaptureWrapper/index.ts +0 -1
  21. package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +0 -72
  22. package/src/components/ScreenRecorderView/index.ts +0 -1
  23. package/src/components/SessionRecorderWidget/FinalPopover.tsx +0 -62
  24. package/src/components/SessionRecorderWidget/FloatingButton.tsx +0 -136
  25. package/src/components/SessionRecorderWidget/InitialPopover.tsx +0 -89
  26. package/src/components/SessionRecorderWidget/ModalContainer.tsx +0 -128
  27. package/src/components/SessionRecorderWidget/ModalHeader.tsx +0 -24
  28. package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +0 -109
  29. package/src/components/SessionRecorderWidget/icons.tsx +0 -52
  30. package/src/components/SessionRecorderWidget/index.ts +0 -3
  31. package/src/components/SessionRecorderWidget/styles.ts +0 -150
  32. package/src/components/index.ts +0 -3
  33. package/src/config/constants.ts +0 -60
  34. package/src/config/defaults.ts +0 -83
  35. package/src/config/index.ts +0 -6
  36. package/src/config/masking.ts +0 -28
  37. package/src/config/session-recorder.ts +0 -55
  38. package/src/config/validators.ts +0 -31
  39. package/src/context/SessionRecorderContext.tsx +0 -53
  40. package/src/index.ts +0 -9
  41. package/src/native/ScreenMasking.ts +0 -34
  42. package/src/native/SessionRecorderNative.ts +0 -34
  43. package/src/otel/helpers.ts +0 -275
  44. package/src/otel/index.ts +0 -138
  45. package/src/otel/instrumentations/index.ts +0 -115
  46. package/src/patch/index.ts +0 -1
  47. package/src/patch/xhr.ts +0 -141
  48. package/src/recorder/eventExporter.ts +0 -141
  49. package/src/recorder/gestureRecorder.ts +0 -498
  50. package/src/recorder/index.ts +0 -179
  51. package/src/recorder/navigationTracker.ts +0 -449
  52. package/src/recorder/screenRecorder.ts +0 -527
  53. package/src/services/api.service.ts +0 -203
  54. package/src/services/screenMaskingService.ts +0 -118
  55. package/src/services/storage.service.ts +0 -199
  56. package/src/session-recorder.ts +0 -606
  57. package/src/types/expo.d.ts +0 -23
  58. package/src/types/index.ts +0 -28
  59. package/src/types/session-recorder.ts +0 -429
  60. package/src/types/session.ts +0 -65
  61. package/src/utils/app-metadata.ts +0 -31
  62. package/src/utils/index.ts +0 -8
  63. package/src/utils/logger.ts +0 -225
  64. package/src/utils/nativeModuleTest.ts +0 -60
  65. package/src/utils/platform.ts +0 -384
  66. package/src/utils/request-utils.ts +0 -61
  67. package/src/utils/rrweb-events.ts +0 -309
  68. package/src/utils/session.ts +0 -18
  69. package/src/utils/time.ts +0 -17
  70. package/src/utils/type-utils.ts +0 -75
  71. package/src/version.ts +0 -1
  72. package/tsconfig.json +0 -24
  73. /package/ios/{SessionRecorder.m → SessionRecorderNative.m} +0 -0
  74. /package/ios/{SessionRecorder.swift → SessionRecorderNative.swift} +0 -0
@@ -1,449 +0,0 @@
1
- import { NavigationEvent, RecorderConfig } from '../types'
2
- import { trace, SpanStatusCode } from '@opentelemetry/api'
3
- import { logger } from '../utils'
4
-
5
- export class NavigationTracker {
6
- private config?: RecorderConfig
7
- private isRecording = false
8
- private navigationRef: any = null
9
- private events: NavigationEvent[] = []
10
- private navigationListeners: Map<string, any> = new Map()
11
- private currentRoute: string | null = null
12
- private navigationStack: string[] = []
13
- private navigationStartTime: number = 0
14
-
15
- init(config: RecorderConfig): void {
16
- this.config = config
17
- }
18
-
19
- setNavigationRef(ref: any): void {
20
- this.navigationRef = ref
21
- if (this.isRecording) {
22
- this._setupNavigationListener()
23
- }
24
- }
25
-
26
- start(): void {
27
- logger.info('NavigationTracker', 'Navigation tracking started')
28
- this.isRecording = true
29
- this.events = []
30
- this.navigationStack = []
31
- this.navigationStartTime = Date.now()
32
- this._setupNavigationListener()
33
- // Navigation tracking started
34
- }
35
-
36
- stop(): void {
37
- this.isRecording = false
38
- this._removeNavigationListener()
39
- // Navigation tracking stopped
40
- }
41
-
42
- pause(): void {
43
- this.isRecording = false
44
- }
45
-
46
- resume(): void {
47
- this.isRecording = true
48
- this._setupNavigationListener()
49
- }
50
-
51
- private _setupNavigationListener(): void {
52
- if (!this.navigationRef) {
53
- // Navigation ref not set - silently continue
54
- return
55
- }
56
-
57
- try {
58
- // Listen to navigation state changes
59
- const stateListener = this.navigationRef.addListener('state', (e: any) => {
60
- this._recordNavigationEvent('state_change', e.data)
61
- })
62
-
63
- // Listen to focus events
64
- const focusListener = this.navigationRef.addListener('focus', (e: any) => {
65
- this._recordNavigationEvent('focus', e.data)
66
- })
67
-
68
- // Listen to blur events
69
- const blurListener = this.navigationRef.addListener('blur', (e: any) => {
70
- this._recordNavigationEvent('blur', e.data)
71
- })
72
-
73
- // Listen to beforeRemove events
74
- const beforeRemoveListener = this.navigationRef.addListener('beforeRemove', (e: any) => {
75
- this._recordNavigationEvent('beforeRemove', e.data)
76
- })
77
-
78
- // Store listeners for cleanup
79
- this.navigationListeners.set('state', stateListener)
80
- this.navigationListeners.set('focus', focusListener)
81
- this.navigationListeners.set('blur', blurListener)
82
- this.navigationListeners.set('beforeRemove', beforeRemoveListener)
83
-
84
- // Navigation listeners setup complete
85
- } catch (error) {
86
- // Failed to setup navigation listeners - silently continue
87
- }
88
- }
89
-
90
- private _removeNavigationListener(): void {
91
- try {
92
- // Remove all listeners
93
- this.navigationListeners.forEach((listener, key) => {
94
- if (listener && typeof listener.remove === 'function') {
95
- listener.remove()
96
- }
97
- })
98
- this.navigationListeners.clear()
99
- // Navigation listeners removed
100
- } catch (error) {
101
- // Failed to remove navigation listeners - silently continue
102
- }
103
- }
104
-
105
- private _recordNavigationEvent(eventType: string, data: any): void {
106
- if (!this.isRecording) return
107
-
108
- const event: NavigationEvent = {
109
- type: 'navigate', // Default type
110
- timestamp: Date.now(),
111
- metadata: {
112
- eventType,
113
- navigationDuration: Date.now() - this.navigationStartTime,
114
- stackDepth: this.navigationStack.length,
115
- },
116
- }
117
-
118
- if (data) {
119
- if (data.routeName) {
120
- event.routeName = data.routeName
121
- this._updateNavigationStack(data.routeName, eventType)
122
- }
123
- if (data.params) {
124
- event.params = data.params
125
- }
126
- if (data.key) {
127
- event.metadata!.routeKey = data.key
128
- }
129
- }
130
-
131
- this.events.push(event)
132
- this._sendEvent(event)
133
- this._recordOpenTelemetrySpan(event)
134
- }
135
-
136
-
137
-
138
- private _updateNavigationStack(routeName: string, eventType: string): void {
139
- if (eventType === 'focus' || eventType === 'state_change') {
140
- if (this.currentRoute !== routeName) {
141
- this.currentRoute = routeName
142
- this.navigationStack.push(routeName)
143
- }
144
- } else if (eventType === 'blur' || eventType === 'beforeRemove') {
145
- const index = this.navigationStack.indexOf(routeName)
146
- if (index > -1) {
147
- this.navigationStack.splice(index, 1)
148
- }
149
- }
150
- }
151
-
152
- private _sendEvent(event: NavigationEvent): void {
153
- // Navigation event recorded
154
- }
155
-
156
- private _recordOpenTelemetrySpan(event: NavigationEvent): void {
157
- try {
158
- const span = trace.getTracer('navigation').startSpan(`Navigation.${event.type}`, {
159
- attributes: {
160
- 'navigation.system': 'ReactNavigation',
161
- 'navigation.operation': event.type,
162
- 'navigation.type': event.type,
163
- 'navigation.timestamp': event.timestamp,
164
- 'navigation.platform': 'react-native',
165
- },
166
- })
167
-
168
- if (event.routeName) {
169
- span.setAttribute('navigation.route_name', event.routeName)
170
- }
171
- if (event.params) {
172
- span.setAttribute('navigation.params', JSON.stringify(event.params))
173
- }
174
- if (event.metadata) {
175
- Object.entries(event.metadata).forEach(([key, value]) => {
176
- span.setAttribute(`navigation.metadata.${key}`, String(value))
177
- })
178
- }
179
-
180
- span.setStatus({ code: SpanStatusCode.OK })
181
- span.end()
182
- } catch (error) {
183
- // Failed to record OpenTelemetry span for navigation - silently continue
184
- }
185
- }
186
-
187
- // Public methods for manual event recording
188
- recordNavigate(routeName: string, params?: Record<string, any>): void {
189
- const event: NavigationEvent = {
190
- type: 'navigate',
191
- timestamp: Date.now(),
192
- routeName,
193
- params,
194
- metadata: {
195
- navigationDuration: Date.now() - this.navigationStartTime,
196
- stackDepth: this.navigationStack.length,
197
- manual: true,
198
- },
199
- }
200
-
201
- this._updateNavigationStack(routeName, 'focus')
202
- this._recordEvent(event)
203
- }
204
-
205
- recordGoBack(): void {
206
- const event: NavigationEvent = {
207
- type: 'goBack',
208
- timestamp: Date.now(),
209
- metadata: {
210
- navigationDuration: Date.now() - this.navigationStartTime,
211
- stackDepth: this.navigationStack.length,
212
- manual: true,
213
- },
214
- }
215
-
216
- this._recordEvent(event)
217
- }
218
-
219
- recordReset(routes: any[]): void {
220
- const event: NavigationEvent = {
221
- type: 'reset',
222
- timestamp: Date.now(),
223
- metadata: {
224
- navigationDuration: Date.now() - this.navigationStartTime,
225
- routesCount: routes.length,
226
- manual: true,
227
- },
228
- }
229
-
230
- // Update navigation stack
231
- this.navigationStack = routes.map(route => route.name || route.routeName)
232
- if (routes.length > 0) {
233
- this.currentRoute = routes[0].name || routes[0].routeName
234
- }
235
-
236
- this._recordEvent(event)
237
- this._recordEvent(event)
238
- }
239
-
240
- private _recordEvent(event: NavigationEvent): void {
241
- if (!this.isRecording) return
242
-
243
- this.events.push(event)
244
- this._sendEvent(event)
245
- this._recordOpenTelemetrySpan(event)
246
- }
247
-
248
- // Advanced navigation tracking methods
249
- recordDeepLink(url: string, params?: Record<string, any>): void {
250
- const event: NavigationEvent = {
251
- type: 'navigate',
252
- timestamp: Date.now(),
253
- routeName: 'deepLink',
254
- params: { url, ...params },
255
- metadata: {
256
- navigationDuration: Date.now() - this.navigationStartTime,
257
- stackDepth: this.navigationStack.length,
258
- deepLink: true,
259
- },
260
- }
261
-
262
- this._recordEvent(event)
263
- this._recordEvent(event)
264
- }
265
-
266
- recordTabChange(tabName: string, tabIndex: number): void {
267
- const event: NavigationEvent = {
268
- type: 'navigate',
269
- timestamp: Date.now(),
270
- routeName: tabName,
271
- params: { tabIndex },
272
- metadata: {
273
- navigationDuration: Date.now() - this.navigationStartTime,
274
- stackDepth: this.navigationStack.length,
275
- tabChange: true,
276
- tabIndex,
277
- },
278
- }
279
-
280
- this._recordEvent(event)
281
- this._recordEvent(event)
282
- }
283
-
284
- recordModalOpen(modalName: string, params?: Record<string, any>): void {
285
- const event: NavigationEvent = {
286
- type: 'navigate',
287
- timestamp: Date.now(),
288
- routeName: modalName,
289
- params,
290
- metadata: {
291
- navigationDuration: Date.now() - this.navigationStartTime,
292
- stackDepth: this.navigationStack.length,
293
- modal: true,
294
- },
295
- }
296
-
297
- this._recordEvent(event)
298
- this._recordEvent(event)
299
- }
300
-
301
- recordModalClose(modalName: string): void {
302
- const event: NavigationEvent = {
303
- type: 'goBack',
304
- timestamp: Date.now(),
305
- routeName: modalName,
306
- metadata: {
307
- navigationDuration: Date.now() - this.navigationStartTime,
308
- stackDepth: this.navigationStack.length,
309
- modal: true,
310
- modalClose: true,
311
- },
312
- }
313
-
314
- this._recordEvent(event)
315
- this._recordEvent(event)
316
- }
317
-
318
- recordStackPush(routeName: string, params?: Record<string, any>): void {
319
- const event: NavigationEvent = {
320
- type: 'navigate',
321
- timestamp: Date.now(),
322
- routeName,
323
- params,
324
- metadata: {
325
- navigationDuration: Date.now() - this.navigationStartTime,
326
- stackDepth: this.navigationStack.length,
327
- stackOperation: 'push',
328
- },
329
- }
330
-
331
- this._recordEvent(event)
332
- this._recordEvent(event)
333
- }
334
-
335
- recordStackPop(routeName?: string): void {
336
- const event: NavigationEvent = {
337
- type: 'goBack',
338
- timestamp: Date.now(),
339
- routeName,
340
- metadata: {
341
- navigationDuration: Date.now() - this.navigationStartTime,
342
- stackDepth: this.navigationStack.length,
343
- stackOperation: 'pop',
344
- },
345
- }
346
-
347
- this._recordEvent(event)
348
- this._recordEvent(event)
349
- }
350
-
351
- // Performance monitoring
352
- recordNavigationPerformance(routeName: string, loadTime: number): void {
353
- const event: NavigationEvent = {
354
- type: 'navigate',
355
- timestamp: Date.now(),
356
- routeName,
357
- metadata: {
358
- navigationDuration: Date.now() - this.navigationStartTime,
359
- stackDepth: this.navigationStack.length,
360
- performance: 'monitoring',
361
- loadTime,
362
- },
363
- }
364
-
365
- this._recordEvent(event)
366
- this._recordEvent(event)
367
- }
368
-
369
- // Error tracking
370
- recordNavigationError(error: Error, routeName?: string): void {
371
- const event: NavigationEvent = {
372
- type: 'navigate',
373
- timestamp: Date.now(),
374
- routeName,
375
- metadata: {
376
- navigationDuration: Date.now() - this.navigationStartTime,
377
- stackDepth: this.navigationStack.length,
378
- error: true,
379
- errorType: error.name,
380
- errorMessage: error.message,
381
- },
382
- }
383
-
384
- this._recordEvent(event)
385
- this._recordEvent(event)
386
-
387
- // Also record as OpenTelemetry error span
388
- try {
389
- const span = trace.getTracer('navigation').startSpan('Navigation.error', {
390
- attributes: {
391
- 'navigation.system': 'ReactNavigation',
392
- 'navigation.error': true,
393
- 'navigation.error.type': error.name,
394
- 'navigation.error.message': error.message,
395
- 'navigation.route_name': routeName || 'unknown',
396
- 'navigation.timestamp': Date.now(),
397
- },
398
- })
399
-
400
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
401
- span.recordException(error)
402
- span.end()
403
- } catch (spanError) {
404
- // Failed to record error span - silently continue
405
- }
406
- }
407
-
408
- // Get current navigation state
409
- getCurrentRoute(): string | null {
410
- return this.currentRoute
411
- }
412
-
413
- getNavigationStack(): string[] {
414
- return [...this.navigationStack]
415
- }
416
-
417
- getNavigationDepth(): number {
418
- return this.navigationStack.length
419
- }
420
-
421
- // Get recorded events
422
- getEvents(): NavigationEvent[] {
423
- return [...this.events]
424
- }
425
-
426
- // Clear events
427
- clearEvents(): void {
428
- this.events = []
429
- }
430
-
431
- // Get navigation statistics
432
- getNavigationStats(): Record<string, number> {
433
- const stats: Record<string, number> = {}
434
- this.events.forEach(event => {
435
- stats[event.type] = (stats[event.type] || 0) + 1
436
- })
437
- return stats
438
- }
439
-
440
- // Get recording status
441
- isRecordingEnabled(): boolean {
442
- return this.isRecording
443
- }
444
-
445
- // Get navigation duration
446
- getNavigationDuration(): number {
447
- return Date.now() - this.navigationStartTime
448
- }
449
- }