@multiplayer-app/session-recorder-react-native 1.0.1-beta.4 → 1.0.1-beta.5

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 (165) hide show
  1. package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModule.kt +2 -2
  2. package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -1
  3. package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -1
  4. package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -1
  5. package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -1
  6. package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -1
  7. package/lib/module/config/constants.js.map +1 -1
  8. package/lib/module/config/defaults.js.map +1 -1
  9. package/lib/module/config/masking.js.map +1 -1
  10. package/lib/module/config/session-recorder.js.map +1 -1
  11. package/lib/module/config/validators.js.map +1 -1
  12. package/lib/module/config/widget.js.map +1 -1
  13. package/lib/module/context/SessionRecorderStore.js.map +1 -1
  14. package/lib/module/context/useSessionRecorderStore.js.map +1 -1
  15. package/lib/module/context/useStoreSelector.js.map +1 -1
  16. package/lib/module/native/SessionRecorderNative.js.map +1 -1
  17. package/lib/module/native/index.js.map +1 -1
  18. package/lib/module/otel/helpers.js +1 -1
  19. package/lib/module/otel/helpers.js.map +1 -1
  20. package/lib/module/otel/index.js.map +1 -1
  21. package/lib/module/otel/instrumentations/index.js.map +1 -1
  22. package/lib/module/patch/xhr.js.map +1 -1
  23. package/lib/module/recorder/eventExporter.js.map +1 -1
  24. package/lib/module/recorder/gestureRecorder.js.map +1 -1
  25. package/lib/module/recorder/index.js.map +1 -1
  26. package/lib/module/recorder/navigationTracker.js.map +1 -1
  27. package/lib/module/recorder/screenRecorder.js.map +1 -1
  28. package/lib/module/services/api.service.js.map +1 -1
  29. package/lib/module/services/network.service.js.map +1 -1
  30. package/lib/module/services/screenMaskingService.js.map +1 -1
  31. package/lib/module/services/storage.service.js.map +1 -1
  32. package/lib/module/session-recorder.js.map +1 -1
  33. package/lib/module/types/index.js.map +1 -1
  34. package/lib/module/types/session-recorder.js.map +1 -1
  35. package/lib/module/utils/app-metadata.js +2 -2
  36. package/lib/module/utils/constants.optional.js.map +1 -1
  37. package/lib/module/utils/createStore.js.map +1 -1
  38. package/lib/module/utils/logger.js +0 -8
  39. package/lib/module/utils/logger.js.map +1 -1
  40. package/lib/module/utils/platform.js +1 -1
  41. package/lib/module/utils/platform.js.map +1 -1
  42. package/lib/module/utils/rrweb-events.js.map +1 -1
  43. package/lib/module/utils/session.js.map +1 -1
  44. package/lib/module/utils/shallowEqual.js.map +1 -1
  45. package/lib/module/utils/time.js.map +1 -1
  46. package/lib/module/version.js +1 -1
  47. package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +1 -1
  48. package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -1
  49. package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -1
  50. package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -1
  51. package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -1
  52. package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +1 -1
  53. package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -1
  54. package/lib/typescript/src/components/index.d.ts.map +1 -1
  55. package/lib/typescript/src/config/constants.d.ts.map +1 -1
  56. package/lib/typescript/src/config/defaults.d.ts.map +1 -1
  57. package/lib/typescript/src/config/index.d.ts.map +1 -1
  58. package/lib/typescript/src/config/masking.d.ts.map +1 -1
  59. package/lib/typescript/src/config/session-recorder.d.ts.map +1 -1
  60. package/lib/typescript/src/config/validators.d.ts.map +1 -1
  61. package/lib/typescript/src/config/widget.d.ts +1 -1
  62. package/lib/typescript/src/config/widget.d.ts.map +1 -1
  63. package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -1
  64. package/lib/typescript/src/context/useSessionRecorderStore.d.ts +3 -3
  65. package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -1
  66. package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -1
  67. package/lib/typescript/src/index.d.ts.map +1 -1
  68. package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -1
  69. package/lib/typescript/src/native/index.d.ts +1 -1
  70. package/lib/typescript/src/native/index.d.ts.map +1 -1
  71. package/lib/typescript/src/otel/helpers.d.ts.map +1 -1
  72. package/lib/typescript/src/otel/index.d.ts.map +1 -1
  73. package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -1
  74. package/lib/typescript/src/patch/index.d.ts.map +1 -1
  75. package/lib/typescript/src/patch/xhr.d.ts.map +1 -1
  76. package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -1
  77. package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -1
  78. package/lib/typescript/src/recorder/index.d.ts.map +1 -1
  79. package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -1
  80. package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -1
  81. package/lib/typescript/src/services/api.service.d.ts.map +1 -1
  82. package/lib/typescript/src/services/network.service.d.ts.map +1 -1
  83. package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -1
  84. package/lib/typescript/src/services/storage.service.d.ts.map +1 -1
  85. package/lib/typescript/src/session-recorder.d.ts.map +1 -1
  86. package/lib/typescript/src/types/configs.d.ts.map +1 -1
  87. package/lib/typescript/src/types/index.d.ts.map +1 -1
  88. package/lib/typescript/src/types/session-recorder.d.ts +4 -4
  89. package/lib/typescript/src/types/session-recorder.d.ts.map +1 -1
  90. package/lib/typescript/src/types/session.d.ts.map +1 -1
  91. package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -1
  92. package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -1
  93. package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -1
  94. package/lib/typescript/src/utils/createStore.d.ts.map +1 -1
  95. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  96. package/lib/typescript/src/utils/logger.d.ts +1 -1
  97. package/lib/typescript/src/utils/logger.d.ts.map +1 -1
  98. package/lib/typescript/src/utils/platform.d.ts.map +1 -1
  99. package/lib/typescript/src/utils/request-utils.d.ts.map +1 -1
  100. package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -1
  101. package/lib/typescript/src/utils/session.d.ts.map +1 -1
  102. package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -1
  103. package/lib/typescript/src/utils/time.d.ts.map +1 -1
  104. package/lib/typescript/src/utils/type-utils.d.ts.map +1 -1
  105. package/lib/typescript/src/version.d.ts.map +1 -1
  106. package/package.json +1 -1
  107. package/src/components/ScreenRecorderView/index.ts +1 -1
  108. package/src/components/SessionRecorderWidget/ErrorBanner.tsx +14 -14
  109. package/src/components/SessionRecorderWidget/ModalHeader.tsx +11 -9
  110. package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +70 -56
  111. package/src/components/SessionRecorderWidget/icons.tsx +58 -30
  112. package/src/components/SessionRecorderWidget/index.ts +1 -1
  113. package/src/components/SessionRecorderWidget/styles.ts +17 -18
  114. package/src/components/index.ts +2 -2
  115. package/src/config/constants.ts +19 -20
  116. package/src/config/defaults.ts +35 -31
  117. package/src/config/index.ts +5 -5
  118. package/src/config/masking.ts +44 -18
  119. package/src/config/session-recorder.ts +54 -26
  120. package/src/config/validators.ts +43 -20
  121. package/src/config/widget.ts +24 -15
  122. package/src/context/SessionRecorderStore.ts +19 -18
  123. package/src/context/useSessionRecorderStore.ts +17 -10
  124. package/src/context/useStoreSelector.ts +20 -18
  125. package/src/index.ts +7 -7
  126. package/src/native/SessionRecorderNative.ts +83 -67
  127. package/src/native/index.ts +5 -1
  128. package/src/otel/helpers.ts +109 -93
  129. package/src/otel/index.ts +46 -49
  130. package/src/otel/instrumentations/index.ts +44 -41
  131. package/src/patch/index.ts +1 -1
  132. package/src/patch/xhr.ts +77 -78
  133. package/src/recorder/eventExporter.ts +63 -68
  134. package/src/recorder/gestureRecorder.ts +359 -212
  135. package/src/recorder/index.ts +75 -62
  136. package/src/recorder/navigationTracker.ts +120 -97
  137. package/src/recorder/screenRecorder.ts +214 -163
  138. package/src/services/api.service.ts +49 -48
  139. package/src/services/network.service.ts +67 -58
  140. package/src/services/screenMaskingService.ts +81 -50
  141. package/src/services/storage.service.ts +99 -70
  142. package/src/session-recorder.ts +270 -214
  143. package/src/types/configs.ts +53 -31
  144. package/src/types/expo-constants.d.ts +2 -2
  145. package/src/types/index.ts +16 -18
  146. package/src/types/session-recorder.ts +106 -111
  147. package/src/types/session.ts +45 -45
  148. package/src/utils/app-metadata.ts +9 -9
  149. package/src/utils/constants.optional.expo.ts +3 -3
  150. package/src/utils/constants.optional.ts +14 -12
  151. package/src/utils/createStore.ts +23 -20
  152. package/src/utils/index.ts +7 -7
  153. package/src/utils/logger.ts +87 -58
  154. package/src/utils/platform.ts +149 -118
  155. package/src/utils/request-utils.ts +15 -15
  156. package/src/utils/rrweb-events.ts +47 -34
  157. package/src/utils/session.ts +15 -12
  158. package/src/utils/shallowEqual.ts +16 -10
  159. package/src/utils/time.ts +7 -4
  160. package/src/utils/type-utils.ts +36 -36
  161. package/src/version.ts +1 -1
  162. package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModuleSpec.kt +0 -51
  163. package/android/src/main/java/com/xxx/XxxModule.kt +0 -23
  164. package/ios/Xxx.h +0 -5
  165. package/ios/Xxx.mm +0 -21
@@ -1,164 +1,180 @@
1
-
2
- import { NativeEventEmitter, Platform, TurboModuleRegistry, type TurboModule } from 'react-native';
1
+ import {
2
+ NativeEventEmitter,
3
+ Platform,
4
+ TurboModuleRegistry,
5
+ type TurboModule,
6
+ } from 'react-native';
3
7
 
4
8
  export interface Spec extends TurboModule {
5
9
  /**
6
10
  * Capture the current screen and apply masking to sensitive elements
7
11
  * @returns Promise that resolves to base64 encoded image
8
12
  */
9
- captureAndMask(): Promise<string>
13
+ captureAndMask(): Promise<string>;
10
14
 
11
15
  /**
12
16
  * Capture the current screen and apply masking with custom options
13
17
  * @param options Custom masking options
14
18
  * @returns Promise that resolves to base64 encoded image
15
19
  */
16
- captureAndMaskWithOptions(options: MaskingOptions): Promise<string>
20
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
17
21
 
18
22
  // Gesture recording APIs
19
- startGestureRecording(): Promise<void>
20
- stopGestureRecording(): Promise<void>
21
- isGestureRecordingActive(): Promise<boolean>
22
- setGestureCallback(callback: (event: any) => void): void
23
+ startGestureRecording(): Promise<void>;
24
+ stopGestureRecording(): Promise<void>;
25
+ isGestureRecordingActive(): Promise<boolean>;
26
+ setGestureCallback(callback: (event: any) => void): void;
23
27
  }
24
28
 
25
29
  export interface MaskingOptions {
26
30
  /** Quality of the captured image (0.1 to 1.0, default: 0.3 for smaller file size) */
27
- quality?: number
31
+ quality?: number;
28
32
  /** Scale of the captured image (0.1 to 1.0, default: 1.0) */
29
- scale?: number
33
+ scale?: number;
30
34
  /** Whether to mask text inputs (UITextField, UITextView, React Native text components) */
31
- maskTextInputs?: boolean
35
+ maskTextInputs?: boolean;
32
36
  /** Whether to mask images (UIImageView, React Native Image components) */
33
- maskImages?: boolean
37
+ maskImages?: boolean;
34
38
  /** Whether to mask buttons (UIButton) */
35
- maskButtons?: boolean
39
+ maskButtons?: boolean;
36
40
  /** Whether to mask labels (UILabel) */
37
- maskLabels?: boolean
41
+ maskLabels?: boolean;
38
42
  /** Whether to mask web views (WKWebView) */
39
- maskWebViews?: boolean
43
+ maskWebViews?: boolean;
40
44
  /** Whether to mask sandboxed views (system views that don't belong to current process) */
41
- maskSandboxedViews?: boolean
45
+ maskSandboxedViews?: boolean;
42
46
  }
43
47
 
44
-
45
48
  export interface SessionRecorderNativeModule {
46
49
  /**
47
50
  * Capture the current screen and apply masking to sensitive elements
48
51
  * @returns Promise that resolves to base64 encoded image
49
52
  */
50
- captureAndMask(): Promise<string>
53
+ captureAndMask(): Promise<string>;
51
54
 
52
55
  /**
53
56
  * Capture the current screen and apply masking with custom options
54
57
  * @param options Custom masking options
55
58
  * @returns Promise that resolves to base64 encoded image
56
59
  */
57
- captureAndMaskWithOptions(options: MaskingOptions): Promise<string>
60
+ captureAndMaskWithOptions(options: MaskingOptions): Promise<string>;
58
61
 
59
62
  // Gesture recording APIs
60
- startGestureRecording(): Promise<void>
61
- stopGestureRecording(): Promise<void>
62
- isGestureRecordingActive(): Promise<boolean>
63
- setGestureCallback(callback: (event: any) => void): void
63
+ startGestureRecording(): Promise<void>;
64
+ stopGestureRecording(): Promise<void>;
65
+ isGestureRecordingActive(): Promise<boolean>;
66
+ setGestureCallback(callback: (event: any) => void): void;
64
67
  }
65
68
 
66
69
  // Check if we're on web platform
67
- const isWeb = Platform.OS === 'web'
70
+ const isWeb = Platform.OS === 'web';
68
71
 
69
72
  // Get the Turbo Module
70
- let SessionRecorderNative: Spec | null = null
71
- let eventEmitter: NativeEventEmitter | null = null
73
+ let SessionRecorderNative: Spec | null = null;
74
+ let eventEmitter: NativeEventEmitter | null = null;
72
75
 
73
76
  if (!isWeb) {
74
77
  try {
75
- SessionRecorderNative = TurboModuleRegistry.getEnforcing<Spec>('SessionRecorderNative')
76
- eventEmitter = new NativeEventEmitter(SessionRecorderNative as any)
78
+ SessionRecorderNative = TurboModuleRegistry.getEnforcing<Spec>(
79
+ 'SessionRecorderNative'
80
+ );
81
+ eventEmitter = new NativeEventEmitter(SessionRecorderNative as any);
77
82
  } catch (error) {
78
- console.warn('Failed to access SessionRecorderNative Turbo Module:', error)
83
+ console.warn('Failed to access SessionRecorderNative Turbo Module:', error);
79
84
  }
80
85
  }
81
86
 
82
87
  // Validate that the native module is available
83
88
  if (!SessionRecorderNative && !isWeb) {
84
- console.warn('SessionRecorderNative Turbo Module is not available. Auto-linking may not have completed yet.')
89
+ console.warn(
90
+ 'SessionRecorderNative Turbo Module is not available. Auto-linking may not have completed yet.'
91
+ );
85
92
  } else if (isWeb) {
86
- console.info('SessionRecorderNative: Running on web platform, native module disabled')
93
+ console.info(
94
+ 'SessionRecorderNative: Running on web platform, native module disabled'
95
+ );
87
96
  }
88
97
 
89
98
  // Create a safe wrapper that handles web platform
90
99
  const SafeSessionRecorderNative: Spec = {
91
100
  async captureAndMask(): Promise<string> {
92
101
  if (isWeb || !SessionRecorderNative) {
93
- throw new Error('SessionRecorderNative is not available on web platform')
102
+ throw new Error('SessionRecorderNative is not available on web platform');
94
103
  }
95
- return SessionRecorderNative.captureAndMask()
104
+ return SessionRecorderNative.captureAndMask();
96
105
  },
97
106
 
98
107
  async captureAndMaskWithOptions(options: MaskingOptions): Promise<string> {
99
108
  if (isWeb || !SessionRecorderNative) {
100
- throw new Error('SessionRecorderNative is not available on web platform')
109
+ throw new Error('SessionRecorderNative is not available on web platform');
101
110
  }
102
- return SessionRecorderNative.captureAndMaskWithOptions(options)
111
+ return SessionRecorderNative.captureAndMaskWithOptions(options);
103
112
  },
104
113
 
105
114
  async startGestureRecording(): Promise<void> {
106
115
  if (isWeb || !SessionRecorderNative) {
107
- throw new Error('SessionRecorderNative is not available on web platform')
116
+ throw new Error('SessionRecorderNative is not available on web platform');
108
117
  }
109
- return SessionRecorderNative.startGestureRecording()
118
+ return SessionRecorderNative.startGestureRecording();
110
119
  },
111
120
 
112
121
  async stopGestureRecording(): Promise<void> {
113
122
  if (isWeb || !SessionRecorderNative) {
114
- throw new Error('SessionRecorderNative is not available on web platform')
123
+ throw new Error('SessionRecorderNative is not available on web platform');
115
124
  }
116
- return SessionRecorderNative.stopGestureRecording()
125
+ return SessionRecorderNative.stopGestureRecording();
117
126
  },
118
127
 
119
128
  async isGestureRecordingActive(): Promise<boolean> {
120
129
  if (isWeb || !SessionRecorderNative) {
121
- throw new Error('SessionRecorderNative is not available on web platform')
130
+ throw new Error('SessionRecorderNative is not available on web platform');
122
131
  }
123
- return SessionRecorderNative.isGestureRecordingActive()
132
+ return SessionRecorderNative.isGestureRecordingActive();
124
133
  },
125
134
 
126
135
  setGestureCallback(callback: (event: any) => void): void {
127
136
  if (isWeb || !SessionRecorderNative) {
128
- throw new Error('SessionRecorderNative is not available on web platform')
137
+ throw new Error('SessionRecorderNative is not available on web platform');
129
138
  }
130
139
  // Native side will also invoke callback if provided; also subscribe to events here
131
140
  try {
132
- SessionRecorderNative.setGestureCallback(callback as any)
133
- } catch { }
134
- eventEmitter?.removeAllListeners('onGestureDetected')
135
- eventEmitter?.addListener('onGestureDetected', callback)
136
- }
137
- }
141
+ SessionRecorderNative.setGestureCallback(callback as any);
142
+ } catch {}
143
+ eventEmitter?.removeAllListeners('onGestureDetected');
144
+ eventEmitter?.addListener('onGestureDetected', callback);
145
+ },
146
+ };
138
147
 
139
148
  export interface NativeGestureEvent {
140
- type: 'tap' | 'pan_start' | 'pan_move' | 'pan_end' | 'long_press' | 'pinch' | 'swipe'
141
- timestamp: number
142
- x: number
143
- y: number
144
- target?: string
149
+ type:
150
+ | 'tap'
151
+ | 'pan_start'
152
+ | 'pan_move'
153
+ | 'pan_end'
154
+ | 'long_press'
155
+ | 'pinch'
156
+ | 'swipe';
157
+ timestamp: number;
158
+ x: number;
159
+ y: number;
160
+ target?: string;
145
161
  targetInfo?: {
146
- identifier: string
147
- label?: string
148
- role?: string
149
- testId?: string
150
- text?: string
151
- }
162
+ identifier: string;
163
+ label?: string;
164
+ role?: string;
165
+ testId?: string;
166
+ text?: string;
167
+ };
152
168
  metadata?: {
153
- pressure?: number
154
- velocity?: number
155
- scale?: number
156
- direction?: string
157
- distance?: number
158
- }
169
+ pressure?: number;
170
+ velocity?: number;
171
+ scale?: number;
172
+ direction?: string;
173
+ distance?: number;
174
+ };
159
175
  }
160
176
 
161
- export default SafeSessionRecorderNative
177
+ export default SafeSessionRecorderNative;
162
178
 
163
179
  // Export event emitter for gesture events to maintain previous API
164
- export const gestureEventEmitter = eventEmitter
180
+ export const gestureEventEmitter = eventEmitter;
@@ -1 +1,5 @@
1
- export { default as SessionRecorderNative, gestureEventEmitter, type NativeGestureEvent } from './SessionRecorderNative'
1
+ export {
2
+ default as SessionRecorderNative,
3
+ gestureEventEmitter,
4
+ type NativeGestureEvent,
5
+ } from './SessionRecorderNative';
@@ -1,4 +1,4 @@
1
- import { type Span } from '@opentelemetry/api'
1
+ import { type Span } from '@opentelemetry/api';
2
2
  import {
3
3
  MULTIPLAYER_TRACE_DEBUG_PREFIX,
4
4
  MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX,
@@ -6,24 +6,22 @@ import {
6
6
  ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,
7
7
  ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,
8
8
  ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,
9
- } from '@multiplayer-app/session-recorder-common'
10
- import { logger } from '../utils'
11
- import { type TracerReactNativeConfig } from '../types'
12
-
13
-
9
+ } from '@multiplayer-app/session-recorder-common';
10
+ import { logger } from '../utils';
11
+ import { type TracerReactNativeConfig } from '../types';
14
12
 
15
13
  export interface HttpPayloadData {
16
- requestBody?: any
17
- responseBody?: any
18
- requestHeaders?: Record<string, string>
19
- responseHeaders?: Record<string, string>
14
+ requestBody?: any;
15
+ responseBody?: any;
16
+ requestHeaders?: Record<string, string>;
17
+ responseHeaders?: Record<string, string>;
20
18
  }
21
19
 
22
20
  export interface ProcessedHttpPayload {
23
- requestBody?: string
24
- responseBody?: string
25
- requestHeaders?: string
26
- responseHeaders?: string
21
+ requestBody?: string;
22
+ responseBody?: string;
23
+ requestHeaders?: string;
24
+ responseHeaders?: string;
27
25
  }
28
26
 
29
27
  /**
@@ -33,7 +31,7 @@ export function shouldProcessTrace(traceId: string): boolean {
33
31
  return (
34
32
  traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX) ||
35
33
  traceId.startsWith(MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)
36
- )
34
+ );
37
35
  }
38
36
 
39
37
  /**
@@ -42,22 +40,22 @@ export function shouldProcessTrace(traceId: string): boolean {
42
40
  export function processBody(
43
41
  payload: HttpPayloadData,
44
42
  config: TracerReactNativeConfig,
45
- span: Span,
43
+ span: Span
46
44
  ): { requestBody?: string; responseBody?: string } {
47
- const { captureBody, masking } = config
48
- const traceId = span.spanContext().traceId
45
+ const { captureBody, masking } = config;
46
+ const traceId = span.spanContext().traceId;
49
47
 
50
48
  if (!captureBody) {
51
- return {}
49
+ return {};
52
50
  }
53
51
 
54
- let { requestBody, responseBody } = payload
52
+ let { requestBody, responseBody } = payload;
55
53
 
56
54
  if (requestBody !== undefined && requestBody !== null) {
57
- requestBody = JSON.parse(JSON.stringify(requestBody))
55
+ requestBody = JSON.parse(JSON.stringify(requestBody));
58
56
  }
59
57
  if (responseBody !== undefined && responseBody !== null) {
60
- responseBody = JSON.parse(JSON.stringify(responseBody))
58
+ responseBody = JSON.parse(JSON.stringify(responseBody));
61
59
  }
62
60
 
63
61
  // Apply masking for debug traces
@@ -66,24 +64,24 @@ export function processBody(
66
64
  traceId.startsWith(MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)
67
65
  ) {
68
66
  if (masking.isContentMaskingEnabled) {
69
- requestBody = requestBody && masking.maskBody?.(requestBody, span)
70
- responseBody = responseBody && masking.maskBody?.(responseBody, span)
67
+ requestBody = requestBody && masking.maskBody?.(requestBody, span);
68
+ responseBody = responseBody && masking.maskBody?.(responseBody, span);
71
69
  }
72
70
  }
73
71
 
74
72
  // Convert to string if needed
75
73
  if (typeof requestBody !== 'string') {
76
- requestBody = JSON.stringify(requestBody)
74
+ requestBody = JSON.stringify(requestBody);
77
75
  }
78
76
 
79
77
  if (typeof responseBody !== 'string') {
80
- responseBody = JSON.stringify(responseBody)
78
+ responseBody = JSON.stringify(responseBody);
81
79
  }
82
80
 
83
81
  return {
84
82
  requestBody: requestBody?.length ? requestBody : undefined,
85
83
  responseBody: responseBody?.length ? responseBody : undefined,
86
- }
84
+ };
87
85
  }
88
86
 
89
87
  /**
@@ -92,71 +90,74 @@ export function processBody(
92
90
  export function processHeaders(
93
91
  payload: HttpPayloadData,
94
92
  config: TracerReactNativeConfig,
95
- span: Span,
93
+ span: Span
96
94
  ): { requestHeaders?: string; responseHeaders?: string } {
97
- const { captureHeaders, masking } = config
95
+ const { captureHeaders, masking } = config;
98
96
 
99
97
  if (!captureHeaders) {
100
- return {}
98
+ return {};
101
99
  }
102
100
 
103
- let { requestHeaders = {}, responseHeaders = {} } = payload
101
+ let { requestHeaders = {}, responseHeaders = {} } = payload;
104
102
 
105
103
  // Handle header filtering
106
- if (
107
- !masking.headersToInclude?.length &&
108
- !masking.headersToExclude?.length
109
- ) {
104
+ if (!masking.headersToInclude?.length && !masking.headersToExclude?.length) {
110
105
  // Add null checks to prevent JSON.parse error when headers is undefined
111
106
  if (requestHeaders !== undefined && requestHeaders !== null) {
112
- requestHeaders = JSON.parse(JSON.stringify(requestHeaders))
107
+ requestHeaders = JSON.parse(JSON.stringify(requestHeaders));
113
108
  }
114
109
  if (responseHeaders !== undefined && responseHeaders !== null) {
115
- responseHeaders = JSON.parse(JSON.stringify(responseHeaders))
110
+ responseHeaders = JSON.parse(JSON.stringify(responseHeaders));
116
111
  }
117
112
  } else {
118
113
  if (masking.headersToInclude) {
119
- const _requestHeaders: Record<string, string> = {}
120
- const _responseHeaders: Record<string, string> = {}
114
+ const _requestHeaders: Record<string, string> = {};
115
+ const _responseHeaders: Record<string, string> = {};
121
116
 
122
117
  for (const headerName of masking.headersToInclude) {
123
118
  if (requestHeaders[headerName]) {
124
- _requestHeaders[headerName] = requestHeaders[headerName]
119
+ _requestHeaders[headerName] = requestHeaders[headerName];
125
120
  }
126
121
  if (responseHeaders[headerName]) {
127
- _responseHeaders[headerName] = responseHeaders[headerName]
122
+ _responseHeaders[headerName] = responseHeaders[headerName];
128
123
  }
129
124
  }
130
125
 
131
- requestHeaders = _requestHeaders
132
- responseHeaders = _responseHeaders
126
+ requestHeaders = _requestHeaders;
127
+ responseHeaders = _responseHeaders;
133
128
  }
134
129
 
135
130
  if (masking.headersToExclude?.length) {
136
131
  for (const headerName of masking.headersToExclude) {
137
- delete requestHeaders[headerName]
138
- delete responseHeaders[headerName]
132
+ delete requestHeaders[headerName];
133
+ delete responseHeaders[headerName];
139
134
  }
140
135
  }
141
136
  }
142
137
 
143
138
  // Apply masking
144
- const maskedRequestHeaders = masking.maskHeaders?.(requestHeaders, span) || requestHeaders
145
- const maskedResponseHeaders = masking.maskHeaders?.(responseHeaders, span) || responseHeaders
139
+ const maskedRequestHeaders =
140
+ masking.maskHeaders?.(requestHeaders, span) || requestHeaders;
141
+ const maskedResponseHeaders =
142
+ masking.maskHeaders?.(responseHeaders, span) || responseHeaders;
146
143
 
147
144
  // Convert to string
148
- const requestHeadersStr = typeof maskedRequestHeaders === 'string'
149
- ? maskedRequestHeaders
150
- : JSON.stringify(maskedRequestHeaders)
145
+ const requestHeadersStr =
146
+ typeof maskedRequestHeaders === 'string'
147
+ ? maskedRequestHeaders
148
+ : JSON.stringify(maskedRequestHeaders);
151
149
 
152
- const responseHeadersStr = typeof maskedResponseHeaders === 'string'
153
- ? maskedResponseHeaders
154
- : JSON.stringify(maskedResponseHeaders)
150
+ const responseHeadersStr =
151
+ typeof maskedResponseHeaders === 'string'
152
+ ? maskedResponseHeaders
153
+ : JSON.stringify(maskedResponseHeaders);
155
154
 
156
155
  return {
157
156
  requestHeaders: requestHeadersStr?.length ? requestHeadersStr : undefined,
158
- responseHeaders: responseHeadersStr?.length ? responseHeadersStr : undefined,
159
- }
157
+ responseHeaders: responseHeadersStr?.length
158
+ ? responseHeadersStr
159
+ : undefined,
160
+ };
160
161
  }
161
162
 
162
163
  /**
@@ -165,110 +166,125 @@ export function processHeaders(
165
166
  export function processHttpPayload(
166
167
  payload: HttpPayloadData,
167
168
  config: TracerReactNativeConfig,
168
- span: Span,
169
+ span: Span
169
170
  ): void {
170
- const traceId = span.spanContext().traceId
171
+ const traceId = span.spanContext().traceId;
171
172
 
172
173
  if (!shouldProcessTrace(traceId)) {
173
- return
174
+ return;
174
175
  }
175
176
 
176
- const { requestBody, responseBody } = processBody(payload, config, span)
177
- const { requestHeaders, responseHeaders } = processHeaders(payload, config, span)
177
+ const { requestBody, responseBody } = processBody(payload, config, span);
178
+ const { requestHeaders, responseHeaders } = processHeaders(
179
+ payload,
180
+ config,
181
+ span
182
+ );
178
183
 
179
184
  // Set span attributes
180
185
  if (requestBody) {
181
- span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_BODY, requestBody)
186
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_BODY, requestBody);
182
187
  }
183
188
 
184
189
  if (responseBody) {
185
- span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY, responseBody)
190
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY, responseBody);
186
191
  }
187
192
 
188
193
  if (requestHeaders) {
189
- span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS, requestHeaders)
194
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS, requestHeaders);
190
195
  }
191
196
 
192
197
  if (responseHeaders) {
193
- span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS, responseHeaders)
198
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS, responseHeaders);
194
199
  }
195
200
  }
196
201
 
197
202
  /**
198
203
  * Converts Headers object to plain object
199
204
  */
200
- export function headersToObject(headers: Headers | Record<string, string> | Record<string, string | string[]> | string[][] | undefined): Record<string, string> {
201
- const result: Record<string, string> = {}
205
+ export function headersToObject(
206
+ headers:
207
+ | Headers
208
+ | Record<string, string>
209
+ | Record<string, string | string[]>
210
+ | string[][]
211
+ | undefined
212
+ ): Record<string, string> {
213
+ const result: Record<string, string> = {};
202
214
 
203
215
  if (!headers) {
204
- return result
216
+ return result;
205
217
  }
206
218
 
207
219
  if (headers instanceof Headers) {
208
220
  headers.forEach((value: string, key: string) => {
209
- result[key] = value
210
- })
221
+ result[key] = value;
222
+ });
211
223
  } else if (Array.isArray(headers)) {
212
224
  // Handle array of [key, value] pairs
213
225
  for (const [key, value] of headers) {
214
226
  if (typeof key === 'string' && typeof value === 'string') {
215
- result[key] = value
227
+ result[key] = value;
216
228
  }
217
229
  }
218
230
  } else if (typeof headers === 'object' && !Array.isArray(headers)) {
219
231
  for (const [key, value] of Object.entries(headers)) {
220
232
  if (typeof key === 'string' && typeof value === 'string') {
221
- result[key] = value
233
+ result[key] = value;
222
234
  }
223
235
  }
224
236
  }
225
237
 
226
- return result
238
+ return result;
227
239
  }
228
240
 
229
241
  /**
230
242
  * Extracts response body as string from Response object
231
243
  */
232
- export async function extractResponseBody(response: Response): Promise<string | null> {
244
+ export async function extractResponseBody(
245
+ response: Response
246
+ ): Promise<string | null> {
233
247
  if (!response.body) {
234
- return null
248
+ return null;
235
249
  }
236
250
 
237
251
  try {
238
252
  if (response.body instanceof ReadableStream) {
239
253
  // Check if response body is already consumed
240
254
  if (response.bodyUsed) {
241
- return null
255
+ return null;
242
256
  }
243
257
 
244
- const responseClone = response.clone()
245
- return responseClone.text()
258
+ const responseClone = response.clone();
259
+ return responseClone.text();
246
260
  } else {
247
- return JSON.stringify(response.body)
261
+ return JSON.stringify(response.body);
248
262
  }
249
263
  } catch (error) {
250
264
  // If cloning fails (body already consumed), return null
251
- // eslint-disable-next-line no-console
252
- logger.warn('DEBUGGER_LIB', 'Failed to extract response body', error)
253
- return null
265
+
266
+ logger.warn('DEBUGGER_LIB', 'Failed to extract response body', error);
267
+ return null;
254
268
  }
255
269
  }
256
270
 
257
271
  export const getExporterEndpoint = (exporterEndpoint: string): string => {
258
- const hasPath = exporterEndpoint && (() => {
259
- try {
260
- const url = new URL(exporterEndpoint)
261
- return url.pathname !== '/' && url.pathname !== ''
262
- } catch {
263
- return false
264
- }
265
- })()
272
+ const hasPath =
273
+ exporterEndpoint &&
274
+ (() => {
275
+ try {
276
+ const url = new URL(exporterEndpoint);
277
+ return url.pathname !== '/' && url.pathname !== '';
278
+ } catch {
279
+ return false;
280
+ }
281
+ })();
266
282
 
267
283
  if (hasPath) {
268
- return exporterEndpoint
284
+ return exporterEndpoint;
269
285
  }
270
286
 
271
- const trimmedExporterEndpoint = new URL(exporterEndpoint).origin
287
+ const trimmedExporterEndpoint = new URL(exporterEndpoint).origin;
272
288
 
273
- return `${trimmedExporterEndpoint}/v1/traces`
274
- }
289
+ return `${trimmedExporterEndpoint}/v1/traces`;
290
+ };