@multiplayer-app/session-recorder-react-native 0.0.1-alpha.7 → 0.0.1-alpha.9

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 (69) hide show
  1. package/dist/components/GestureCaptureWrapper.d.ts +6 -0
  2. package/dist/components/GestureCaptureWrapper.js +1 -0
  3. package/dist/components/GestureCaptureWrapper.js.map +1 -0
  4. package/dist/context/SessionRecorderContext.d.ts +1 -2
  5. package/dist/context/SessionRecorderContext.js +1 -1
  6. package/dist/context/SessionRecorderContext.js.map +1 -1
  7. package/dist/otel/helpers.js +1 -1
  8. package/dist/otel/helpers.js.map +1 -1
  9. package/dist/otel/instrumentations/index.js +1 -1
  10. package/dist/otel/instrumentations/index.js.map +1 -1
  11. package/dist/otel/instrumentations/reactNativeInstrumentation.js +1 -1
  12. package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +1 -1
  13. package/dist/patch/xhr.js +1 -1
  14. package/dist/patch/xhr.js.map +1 -1
  15. package/dist/recorder/eventExporter.js +1 -1
  16. package/dist/recorder/eventExporter.js.map +1 -1
  17. package/dist/recorder/gestureHandlerRecorder.d.ts +19 -0
  18. package/dist/recorder/gestureHandlerRecorder.js +1 -0
  19. package/dist/recorder/gestureHandlerRecorder.js.map +1 -0
  20. package/dist/recorder/gestureRecorder.d.ts +13 -1
  21. package/dist/recorder/gestureRecorder.js +1 -1
  22. package/dist/recorder/gestureRecorder.js.map +1 -1
  23. package/dist/recorder/index.d.ts +1 -2
  24. package/dist/recorder/index.js +1 -1
  25. package/dist/recorder/index.js.map +1 -1
  26. package/dist/recorder/navigationTracker.js +1 -1
  27. package/dist/recorder/navigationTracker.js.map +1 -1
  28. package/dist/recorder/screenRecorder.d.ts +31 -6
  29. package/dist/recorder/screenRecorder.js +1 -1
  30. package/dist/recorder/screenRecorder.js.map +1 -1
  31. package/dist/session-recorder.d.ts +3 -1
  32. package/dist/session-recorder.js +1 -1
  33. package/dist/session-recorder.js.map +1 -1
  34. package/dist/types/index.d.ts +32 -1
  35. package/dist/types/index.js +1 -1
  36. package/dist/types/index.js.map +1 -1
  37. package/dist/types/rrweb.d.ts +10 -0
  38. package/dist/utils/index.d.ts +2 -0
  39. package/dist/utils/index.js +1 -1
  40. package/dist/utils/index.js.map +1 -1
  41. package/dist/utils/logger.d.ts +112 -0
  42. package/dist/utils/logger.js +1 -0
  43. package/dist/utils/logger.js.map +1 -0
  44. package/dist/utils/rrweb-events.d.ts +65 -0
  45. package/dist/utils/rrweb-events.js +1 -0
  46. package/dist/utils/rrweb-events.js.map +1 -0
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +3 -1
  50. package/src/components/GestureCaptureWrapper.tsx +110 -0
  51. package/src/context/SessionRecorderContext.tsx +76 -81
  52. package/src/otel/helpers.ts +2 -1
  53. package/src/otel/instrumentations/index.ts +5 -4
  54. package/src/otel/instrumentations/reactNativeInstrumentation.ts +2 -1
  55. package/src/patch/xhr.ts +2 -2
  56. package/src/recorder/eventExporter.ts +4 -1
  57. package/src/recorder/gestureHandlerRecorder.ts +157 -0
  58. package/src/recorder/gestureRecorder.ts +93 -19
  59. package/src/recorder/index.ts +16 -18
  60. package/src/recorder/navigationTracker.ts +2 -0
  61. package/src/recorder/screenRecorder.ts +125 -82
  62. package/src/session-recorder.ts +12 -5
  63. package/src/types/index.ts +44 -1
  64. package/src/utils/index.ts +2 -0
  65. package/src/utils/logger.ts +225 -0
  66. package/src/utils/rrweb-events.ts +311 -0
  67. package/src/version.ts +1 -1
  68. package/example-usage.tsx +0 -174
  69. package/src/types/rrweb.ts +0 -122
@@ -1,4 +1,5 @@
1
1
  import { InstrumentationBase } from '@opentelemetry/instrumentation'
2
+ import { logger } from '../../utils'
2
3
  import { trace, SpanStatusCode } from '@opentelemetry/api'
3
4
  import AsyncStorage from '@react-native-async-storage/async-storage'
4
5
 
@@ -18,7 +19,7 @@ export class ReactNativeInstrumentation extends InstrumentationBase {
18
19
  this._wrap(AsyncStorage, 'setItem', this._wrapAsyncStorage)
19
20
  }
20
21
  } catch (error) {
21
- console.warn('@react-native-async-storage/async-storage is not available. AsyncStorage instrumentation will be disabled.')
22
+ logger.warn('DEBUGGER_LIB', '@react-native-async-storage/async-storage is not available. AsyncStorage instrumentation will be disabled.')
22
23
  }
23
24
  }
24
25
 
package/src/patch/xhr.ts CHANGED
@@ -92,7 +92,7 @@ function _tryReadXHRBody({
92
92
 
93
93
  if (
94
94
  requestBody?.length
95
- && new Blob([requestBody]).size <= maxCapturingHttpPayloadSize
95
+ && requestBody.length <= maxCapturingHttpPayloadSize
96
96
  ) {
97
97
  networkRequest.requestBody = requestBody
98
98
  }
@@ -126,7 +126,7 @@ function _tryReadXHRBody({
126
126
 
127
127
  if (
128
128
  responseBody?.length
129
- && new Blob([responseBody]).size <= maxCapturingHttpPayloadSize
129
+ && responseBody.length <= maxCapturingHttpPayloadSize
130
130
  ) {
131
131
  networkRequest.responseBody = responseBody
132
132
  }
@@ -1,6 +1,7 @@
1
1
  import io, { Socket } from 'socket.io-client'
2
2
 
3
3
  import { ISession } from '../types'
4
+ import { logger } from '../utils'
4
5
 
5
6
  import {
6
7
  SESSION_ADD_EVENT,
@@ -45,19 +46,21 @@ export class EventExporter {
45
46
  this.socket.on('ready', () => {
46
47
  this.isConnecting = false
47
48
  this.isConnected = true
48
-
49
+ logger.info('EventExporter', 'Connected to server')
49
50
  this.flushQueue()
50
51
  })
51
52
 
52
53
  this.socket.on('disconnect', (err: any) => {
53
54
  this.isConnecting = false
54
55
  this.isConnected = false
56
+ logger.info('EventExporter', 'Disconnected from server')
55
57
  })
56
58
 
57
59
  this.socket.on('connect_error', (err: any) => {
58
60
  this.isConnecting = false
59
61
  this.isConnected = false
60
62
  this.checkReconnectionAttempts()
63
+ logger.error('EventExporter', 'Error connecting to server', err)
61
64
  })
62
65
 
63
66
  this.socket.on(SESSION_STOPPED_EVENT, (data: any) => {
@@ -0,0 +1,157 @@
1
+ import { Gesture } from 'react-native-gesture-handler'
2
+ import { ReactNode } from 'react'
3
+ import { SessionState } from '../types'
4
+ import { GestureInstrumentation } from '../otel/instrumentations/gestureInstrumentation'
5
+
6
+ export interface GestureHandlerRecorderProps {
7
+ children: ReactNode
8
+ sessionState: SessionState | null
9
+ onGestureRecord: (gestureType: string, data: any) => void
10
+ }
11
+
12
+ export class GestureHandlerRecorder {
13
+ private gestureInstrumentation: GestureInstrumentation
14
+ private onGestureRecord?: (gestureType: string, data: any) => void
15
+
16
+ constructor() {
17
+ this.gestureInstrumentation = new GestureInstrumentation()
18
+ this.gestureInstrumentation.enable()
19
+ }
20
+
21
+ setGestureCallback(callback: (gestureType: string, data: any) => void) {
22
+ this.onGestureRecord = callback
23
+ }
24
+
25
+ // Create tap gesture
26
+ createTapGesture() {
27
+ return Gesture.Tap()
28
+ .onStart((event) => {
29
+ this.recordGesture('tap', {
30
+ x: event.x,
31
+ y: event.y,
32
+ timestamp: Date.now(),
33
+ })
34
+ })
35
+ }
36
+
37
+ // Create pan gesture (for swipes and drags)
38
+ createPanGesture() {
39
+ return Gesture.Pan()
40
+ .onStart((event) => {
41
+ this.recordGesture('pan_start', {
42
+ x: event.x,
43
+ y: event.y,
44
+ timestamp: Date.now(),
45
+ })
46
+ })
47
+ .onUpdate((event) => {
48
+ this.recordGesture('pan_update', {
49
+ x: event.x,
50
+ y: event.y,
51
+ translationX: event.translationX,
52
+ translationY: event.translationY,
53
+ velocityX: event.velocityX,
54
+ velocityY: event.velocityY,
55
+ timestamp: Date.now(),
56
+ })
57
+ })
58
+ .onEnd((event) => {
59
+ this.recordGesture('pan_end', {
60
+ x: event.x,
61
+ y: event.y,
62
+ translationX: event.translationX,
63
+ translationY: event.translationY,
64
+ velocityX: event.velocityX,
65
+ velocityY: event.velocityY,
66
+ timestamp: Date.now(),
67
+ })
68
+ })
69
+ }
70
+
71
+ // Create pinch gesture
72
+ createPinchGesture() {
73
+ return Gesture.Pinch()
74
+ .onStart((event) => {
75
+ this.recordGesture('pinch_start', {
76
+ scale: event.scale,
77
+ focalX: event.focalX,
78
+ focalY: event.focalY,
79
+ timestamp: Date.now(),
80
+ })
81
+ })
82
+ .onUpdate((event) => {
83
+ this.recordGesture('pinch_update', {
84
+ scale: event.scale,
85
+ focalX: event.focalX,
86
+ focalY: event.focalY,
87
+ timestamp: Date.now(),
88
+ })
89
+ })
90
+ .onEnd((event) => {
91
+ this.recordGesture('pinch_end', {
92
+ scale: event.scale,
93
+ focalX: event.focalX,
94
+ focalY: event.focalY,
95
+ timestamp: Date.now(),
96
+ })
97
+ })
98
+ }
99
+
100
+ // Create long press gesture
101
+ createLongPressGesture() {
102
+ return Gesture.LongPress()
103
+ .minDuration(500)
104
+ .onStart((event) => {
105
+ this.recordGesture('long_press', {
106
+ x: event.x,
107
+ y: event.y,
108
+ duration: 500,
109
+ timestamp: Date.now(),
110
+ })
111
+ })
112
+ }
113
+
114
+ private recordGesture(gestureType: string, data: any) {
115
+ // Record with OpenTelemetry
116
+ switch (gestureType) {
117
+ case 'tap':
118
+ this.gestureInstrumentation.recordTap(data.x, data.y)
119
+ break
120
+ case 'pan_start':
121
+ case 'pan_update':
122
+ case 'pan_end':
123
+ this.gestureInstrumentation.recordPan(data.translationX || 0, data.translationY || 0)
124
+ break
125
+ case 'pinch_start':
126
+ case 'pinch_update':
127
+ case 'pinch_end':
128
+ this.gestureInstrumentation.recordPinch(data.scale, undefined)
129
+ break
130
+ case 'long_press':
131
+ this.gestureInstrumentation.recordLongPress(data.duration, undefined)
132
+ break
133
+ }
134
+
135
+ // Record with session recorder
136
+ if (this.onGestureRecord) {
137
+ this.onGestureRecord(gestureType, data)
138
+ }
139
+ }
140
+
141
+ // Create a gesture detector component
142
+ createGestureDetector(children: ReactNode, sessionState: SessionState | null): ReactNode {
143
+ if (sessionState !== SessionState.started) {
144
+ return children
145
+ }
146
+
147
+ const tapGesture = this.createTapGesture()
148
+ const panGesture = this.createPanGesture()
149
+ const pinchGesture = this.createPinchGesture()
150
+ const longPressGesture = this.createLongPressGesture()
151
+
152
+ // Note: This would need to be implemented as a proper React component
153
+ // For now, return children directly - the gesture detection would be handled
154
+ // at the app level by wrapping the entire app with GestureHandlerRootView
155
+ return children
156
+ }
157
+ }
@@ -1,6 +1,7 @@
1
- import { GestureEvent, RecorderConfig, EventType, IncrementalSource, IncrementalSnapshotEvent, MouseInteractionType, EventRecorder } from '../types'
1
+ import { GestureEvent, RecorderConfig, EventType, IncrementalSource, MouseInteractionType, EventRecorder, eventWithTime } from '../types'
2
2
  import { trace, SpanStatusCode } from '@opentelemetry/api'
3
3
  import { Dimensions } from 'react-native'
4
+ import { logger } from '../utils'
4
5
 
5
6
  export class GestureRecorder implements EventRecorder {
6
7
  private config?: RecorderConfig
@@ -10,6 +11,13 @@ export class GestureRecorder implements EventRecorder {
10
11
  private screenDimensions: { width: number; height: number } | null = null
11
12
  private lastGestureTime: number = 0
12
13
  private gestureThrottleMs: number = 50 // Throttle gestures to avoid spam
14
+ private lastTouchTime: number = 0
15
+ private touchThrottleMs: number = 100 // Throttle touch events to max 10 per second
16
+
17
+ // Cyclic call detection
18
+ private isRecordingGesture = false
19
+ private gestureCallStack: string[] = []
20
+ private maxGestureCallDepth = 5
13
21
  private eventRecorder?: EventRecorder
14
22
  private imageNodeId: number = 1 // ID of the image node for touch interactions
15
23
  private screenRecorder?: any // Reference to screen recorder for force capture
@@ -21,6 +29,7 @@ export class GestureRecorder implements EventRecorder {
21
29
  }
22
30
 
23
31
  start(): void {
32
+ logger.info('GestureRecorder', 'Gesture recording started')
24
33
  this.isRecording = true
25
34
  this.events = []
26
35
  this._setupGestureHandlers()
@@ -467,14 +476,41 @@ export class GestureRecorder implements EventRecorder {
467
476
  interactionType: MouseInteractionType,
468
477
  target?: string,
469
478
  ): void {
470
- const incrementalSnapshotEvent: IncrementalSnapshotEvent = {
479
+ const incrementalSnapshotEvent: eventWithTime = {
471
480
  type: EventType.IncrementalSnapshot,
472
481
  data: {
473
482
  source: IncrementalSource.MouseInteraction,
474
483
  type: interactionType,
475
484
  id: this.imageNodeId, // Reference to the image node
476
- x: Math.round(x),
477
- y: Math.round(y),
485
+ x: x, // Preserve decimal precision like web rrweb
486
+ y: y, // Preserve decimal precision like web rrweb
487
+ pointerType: 2, // 2 = Touch for React Native (0=Mouse, 1=Pen, 2=Touch)
488
+ },
489
+ timestamp: Date.now(),
490
+ }
491
+
492
+ this.recordEvent(incrementalSnapshotEvent)
493
+ }
494
+
495
+ /**
496
+ * Create mouse move event with positions array (like web rrweb)
497
+ * @param x - X coordinate
498
+ * @param y - Y coordinate
499
+ * @param target - Target element identifier
500
+ */
501
+ private _createMouseMoveEvent(x: number, y: number, target?: string): void {
502
+ const incrementalSnapshotEvent: eventWithTime = {
503
+ type: EventType.IncrementalSnapshot,
504
+ data: {
505
+ source: IncrementalSource.MouseMove, // Use MouseMove instead of MouseInteraction
506
+ positions: [
507
+ {
508
+ x: x, // Preserve decimal precision like web rrweb
509
+ y: y, // Preserve decimal precision like web rrweb
510
+ id: this.imageNodeId, // Reference to the image node
511
+ timeOffset: 0, // No time offset for single position
512
+ },
513
+ ],
478
514
  },
479
515
  timestamp: Date.now(),
480
516
  }
@@ -490,25 +526,38 @@ export class GestureRecorder implements EventRecorder {
490
526
  * @param pressure - Touch pressure (optional)
491
527
  */
492
528
  recordTouchStart(x: number, y: number, target?: string, pressure?: number): void {
493
- // Record as both gesture event and rrweb event
494
- this.recordTap(x, y, target, pressure)
495
- this._createMouseInteractionEvent(x, y, MouseInteractionType.TouchStart, target)
529
+ // Throttle touch events to prevent spam
530
+ const now = Date.now()
531
+ if (now - this.lastTouchTime < this.touchThrottleMs) {
532
+ logger.debug('GestureRecorder', `Touch start throttled (${now - this.lastTouchTime}ms < ${this.touchThrottleMs}ms)`)
533
+ return
534
+ }
535
+ this.lastTouchTime = now
496
536
 
497
- // Force screen capture after touch interaction
498
- this.screenRecorder?.forceCapture()
537
+ logger.debug('GestureRecorder', 'Touch start recorded', { x, y, target, pressure })
538
+ // Record as MouseDown (type: 1) like web rrweb
539
+ this._createMouseInteractionEvent(x, y, MouseInteractionType.MouseDown, target)
499
540
  }
500
541
 
501
542
  /**
502
- * Record touch move event as rrweb MouseInteraction
543
+ * Record touch move event as rrweb MouseMove with positions array
503
544
  * @param x - X coordinate
504
545
  * @param y - Y coordinate
505
546
  * @param target - Target element identifier
506
547
  * @param pressure - Touch pressure (optional)
507
548
  */
508
549
  recordTouchMove(x: number, y: number, target?: string, pressure?: number): void {
509
- // Record as both gesture event and rrweb event
510
- this.recordPan(x - (this.lastGestureTime || 0), y - (this.lastGestureTime || 0), target)
511
- this._createMouseInteractionEvent(x, y, MouseInteractionType.TouchMove, target)
550
+ // Throttle touch move events more aggressively
551
+ const now = Date.now()
552
+ if (now - this.lastTouchTime < this.touchThrottleMs * 2) { // 200ms throttle for move events
553
+ logger.debug('GestureRecorder', `Touch move throttled (${now - this.lastTouchTime}ms < ${this.touchThrottleMs * 2}ms)`)
554
+ return
555
+ }
556
+ this.lastTouchTime = now
557
+
558
+ logger.debug('GestureRecorder', 'Touch move recorded', { x, y, target, pressure })
559
+ // Record as MouseMove with positions array (like web rrweb)
560
+ this._createMouseMoveEvent(x, y, target)
512
561
  }
513
562
 
514
563
  /**
@@ -519,12 +568,36 @@ export class GestureRecorder implements EventRecorder {
519
568
  * @param pressure - Touch pressure (optional)
520
569
  */
521
570
  recordTouchEnd(x: number, y: number, target?: string, pressure?: number): void {
522
- // Record as both gesture event and rrweb event
523
- this.recordTap(x, y, target, pressure)
524
- this._createMouseInteractionEvent(x, y, MouseInteractionType.TouchEnd, target)
571
+ // Cyclic call detection
572
+ if (this.isRecordingGesture) {
573
+ logger.error('GestureRecorder', 'CYCLIC CALL DETECTED! Already recording gesture', this.gestureCallStack)
574
+ return
575
+ }
576
+
577
+ if (this.gestureCallStack.length >= this.maxGestureCallDepth) {
578
+ logger.error('GestureRecorder', 'MAX GESTURE CALL DEPTH REACHED!', this.gestureCallStack)
579
+ return
580
+ }
525
581
 
526
- // Force screen capture after touch interaction
527
- this.screenRecorder?.forceCapture()
582
+ this.isRecordingGesture = true
583
+ this.gestureCallStack.push('recordTouchEnd')
584
+
585
+ try {
586
+ logger.debug('GestureRecorder', 'Touch end recorded', { x, y, target, pressure })
587
+ // Always record touch end (no throttling for completion)
588
+ this.recordTap(x, y, target, pressure)
589
+ // Record as MouseUp (type: 0) like web rrweb
590
+ this._createMouseInteractionEvent(x, y, MouseInteractionType.MouseUp, target)
591
+ // Also record Click (type: 2) like web rrweb
592
+ this._createMouseInteractionEvent(x, y, MouseInteractionType.Click, target)
593
+
594
+ // Only force screen capture on touch end (not on every touch event)
595
+ logger.debug('GestureRecorder', 'Forcing screen capture after touch end')
596
+ this.screenRecorder?.forceCapture()
597
+ } finally {
598
+ this.isRecordingGesture = false
599
+ this.gestureCallStack.pop()
600
+ }
528
601
  }
529
602
 
530
603
  /**
@@ -534,7 +607,8 @@ export class GestureRecorder implements EventRecorder {
534
607
  * @param target - Target element identifier
535
608
  */
536
609
  recordTouchCancel(x: number, y: number, target?: string): void {
537
- this._createMouseInteractionEvent(x, y, MouseInteractionType.TouchCancel, target)
610
+ // Record as MouseUp (type: 0) like web rrweb for touch cancel
611
+ this._createMouseInteractionEvent(x, y, MouseInteractionType.MouseUp, target)
538
612
  }
539
613
 
540
614
  /**
@@ -1,7 +1,7 @@
1
- import { pack } from '@rrweb/packer'
2
1
  import { SessionType } from '@multiplayer-app/session-recorder-common'
3
-
2
+ // import { pack } from '@rrweb/packer' // Removed to avoid blob creation issues in Hermes
4
3
  import { EventExporter } from './eventExporter'
4
+ import { logger } from '../utils'
5
5
  import { ScreenRecorder } from './screenRecorder'
6
6
  import { GestureRecorder } from './gestureRecorder'
7
7
  import { NavigationTracker } from './navigationTracker'
@@ -9,7 +9,6 @@ import { RecorderConfig, EventRecorder, RRWebEvent } from '../types'
9
9
  export class RecorderReactNativeSDK implements EventRecorder {
10
10
  private isRecording = false
11
11
  private config?: RecorderConfig
12
- private eventRecorder?: EventRecorder
13
12
  private screenRecorder: ScreenRecorder
14
13
  private gestureRecorder: GestureRecorder
15
14
  private navigationTracker: NavigationTracker
@@ -18,15 +17,15 @@ export class RecorderReactNativeSDK implements EventRecorder {
18
17
  private sessionId: string | null = null
19
18
  private sessionType: SessionType = SessionType.PLAIN
20
19
 
20
+
21
21
  constructor() {
22
+ this.screenRecorder = new ScreenRecorder()
22
23
  this.gestureRecorder = new GestureRecorder()
23
24
  this.navigationTracker = new NavigationTracker()
24
- this.screenRecorder = new ScreenRecorder()
25
25
  }
26
26
 
27
- init(config: RecorderConfig, eventRecorder?: EventRecorder): void {
27
+ init(config: RecorderConfig): void {
28
28
  this.config = config
29
- this.eventRecorder = eventRecorder
30
29
  this.gestureRecorder.init(config, this, this.screenRecorder)
31
30
  this.navigationTracker.init(config)
32
31
  this.screenRecorder.init(config, this)
@@ -45,6 +44,12 @@ export class RecorderReactNativeSDK implements EventRecorder {
45
44
  this.sessionType = sessionType
46
45
  this.isRecording = true
47
46
 
47
+ // Emit recording started meta event
48
+
49
+ if (this.config.recordScreen) {
50
+ this.screenRecorder.start()
51
+ }
52
+
48
53
  if (this.config.recordGestures) {
49
54
  this.gestureRecorder.start()
50
55
  }
@@ -53,9 +58,7 @@ export class RecorderReactNativeSDK implements EventRecorder {
53
58
  this.navigationTracker.start()
54
59
  }
55
60
 
56
- if (this.config.recordScreen) {
57
- this.screenRecorder.start()
58
- }
61
+
59
62
  }
60
63
 
61
64
  stop(): void {
@@ -88,23 +91,18 @@ export class RecorderReactNativeSDK implements EventRecorder {
88
91
  return
89
92
  }
90
93
 
91
- // Store the event locally
92
- this.recordedEvents.push(event)
93
94
  if (this.exporter) {
94
- const packedEvent = pack(event)
95
+ logger.debug('RecorderReactNativeSDK', 'Sending to exporter', event)
96
+ // Skip packing to avoid blob creation issues in Hermes
97
+ // const packedEvent = pack(event)
95
98
  this.exporter.send({
96
- event: packedEvent,
99
+ event: event, // Send raw event instead of packed
97
100
  eventType: event.type,
98
101
  timestamp: event.timestamp,
99
102
  debugSessionId: this.sessionId,
100
103
  debugSessionType: this.sessionType,
101
104
  })
102
105
  }
103
-
104
- // Forward to parent event recorder if available
105
- if (this.eventRecorder) {
106
- this.eventRecorder.recordEvent(event)
107
- }
108
106
  }
109
107
 
110
108
  /**
@@ -1,5 +1,6 @@
1
1
  import { NavigationEvent, RecorderConfig } from '../types'
2
2
  import { trace, SpanStatusCode } from '@opentelemetry/api'
3
+ import { logger } from '../utils'
3
4
 
4
5
  export class NavigationTracker {
5
6
  private config?: RecorderConfig
@@ -23,6 +24,7 @@ export class NavigationTracker {
23
24
  }
24
25
 
25
26
  start(): void {
27
+ logger.info('NavigationTracker', 'Navigation tracking started')
26
28
  this.isRecording = true
27
29
  this.events = []
28
30
  this.navigationStack = []