@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
package/src/otel/index.ts CHANGED
@@ -1,55 +1,51 @@
1
- import { resourceFromAttributes } from '@opentelemetry/resources'
2
- import { W3CTraceContextPropagator } from '@opentelemetry/core'
3
- import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'
4
- import * as SemanticAttributes from '@opentelemetry/semantic-conventions'
5
- import { registerInstrumentations } from '@opentelemetry/instrumentation'
1
+ import { resourceFromAttributes } from '@opentelemetry/resources';
2
+ import { W3CTraceContextPropagator } from '@opentelemetry/core';
3
+ import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
4
+ import * as SemanticAttributes from '@opentelemetry/semantic-conventions';
5
+ import { registerInstrumentations } from '@opentelemetry/instrumentation';
6
6
  import {
7
7
  SessionType,
8
8
  ATTR_MULTIPLAYER_SESSION_ID,
9
9
  SessionRecorderIdGenerator,
10
10
  SessionRecorderTraceIdRatioBasedSampler,
11
11
  SessionRecorderBrowserTraceExporter,
12
- } from '@multiplayer-app/session-recorder-common'
13
- import { type TracerReactNativeConfig } from '../types'
14
- import { getInstrumentations } from './instrumentations'
15
- import { getExporterEndpoint } from './helpers'
16
-
17
- import { getPlatformAttributes } from '../utils/platform'
18
- import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'
19
-
20
-
12
+ } from '@multiplayer-app/session-recorder-common';
13
+ import { type TracerReactNativeConfig } from '../types';
14
+ import { getInstrumentations } from './instrumentations';
15
+ import { getExporterEndpoint } from './helpers';
21
16
 
17
+ import { getPlatformAttributes } from '../utils/platform';
18
+ import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
22
19
 
23
20
  export class TracerReactNativeSDK {
24
- private tracerProvider?: WebTracerProvider
25
- private config?: TracerReactNativeConfig
21
+ private tracerProvider?: WebTracerProvider;
22
+ private config?: TracerReactNativeConfig;
26
23
 
27
- private sessionId = ''
28
- private idGenerator?: SessionRecorderIdGenerator
29
- private exporter?: any
24
+ private sessionId = '';
25
+ private idGenerator?: SessionRecorderIdGenerator;
26
+ private exporter?: any;
30
27
 
31
-
32
- constructor() { }
28
+ constructor() {}
33
29
 
34
30
  private _setSessionId(
35
31
  sessionId: string,
36
- sessionType: SessionType = SessionType.PLAIN,
32
+ sessionType: SessionType = SessionType.PLAIN
37
33
  ) {
38
- this.sessionId = sessionId
39
- this.idGenerator?.setSessionId(sessionId, sessionType)
34
+ this.sessionId = sessionId;
35
+ this.idGenerator?.setSessionId(sessionId, sessionType);
40
36
  }
41
37
 
42
38
  init(options: TracerReactNativeConfig): void {
43
- this.config = options
39
+ this.config = options;
44
40
 
45
- const { application, version, environment } = this.config
41
+ const { application, version, environment } = this.config;
46
42
 
47
- this.idGenerator = new SessionRecorderIdGenerator()
43
+ this.idGenerator = new SessionRecorderIdGenerator();
48
44
 
49
45
  this.exporter = new SessionRecorderBrowserTraceExporter({
50
46
  apiKey: options.apiKey,
51
47
  url: getExporterEndpoint(options.exporterEndpoint),
52
- })
48
+ });
53
49
 
54
50
  this.tracerProvider = new WebTracerProvider({
55
51
  resource: resourceFromAttributes({
@@ -59,77 +55,78 @@ export class TracerReactNativeSDK {
59
55
  ...getPlatformAttributes(),
60
56
  }),
61
57
  idGenerator: this.idGenerator,
62
- sampler: new SessionRecorderTraceIdRatioBasedSampler(this.config.sampleTraceRatio || 0.15),
58
+ sampler: new SessionRecorderTraceIdRatioBasedSampler(
59
+ this.config.sampleTraceRatio || 0.15
60
+ ),
63
61
  spanProcessors: [
64
62
  this._getSpanSessionIdProcessor(),
65
63
  new BatchSpanProcessor(this.exporter),
66
64
  ],
67
- })
65
+ });
68
66
 
69
67
  this.tracerProvider.register({
70
68
  propagator: new W3CTraceContextPropagator(),
71
- })
69
+ });
72
70
 
73
71
  // Register instrumentations
74
72
  registerInstrumentations({
75
73
  tracerProvider: this.tracerProvider,
76
74
  instrumentations: getInstrumentations(this.config),
77
- })
78
-
75
+ });
79
76
  }
80
77
 
81
78
  private _getSpanSessionIdProcessor() {
82
79
  return {
83
80
  onStart: (span: any) => {
84
81
  if (this.sessionId) {
85
- span.setAttribute(ATTR_MULTIPLAYER_SESSION_ID, this.sessionId)
82
+ span.setAttribute(ATTR_MULTIPLAYER_SESSION_ID, this.sessionId);
86
83
  }
87
84
  // Add React Native specific attributes
88
- span.setAttribute('platform', 'react-native')
89
- span.setAttribute('timestamp', Date.now())
85
+ span.setAttribute('platform', 'react-native');
86
+ span.setAttribute('timestamp', Date.now());
90
87
  },
91
- onEnd: () => { },
88
+ onEnd: () => {},
92
89
  shutdown: () => Promise.resolve(),
93
90
  forceFlush: () => Promise.resolve(),
94
- }
91
+ };
95
92
  }
96
93
 
97
94
  start(sessionId: string, sessionType: SessionType): void {
98
95
  if (!this.tracerProvider) {
99
96
  throw new Error(
100
- 'Configuration not initialized. Call init() before start().',
101
- )
97
+ 'Configuration not initialized. Call init() before start().'
98
+ );
102
99
  }
103
100
 
104
- this._setSessionId(sessionId, sessionType)
101
+ this._setSessionId(sessionId, sessionType);
105
102
  }
106
103
 
107
104
  stop(): void {
108
105
  if (!this.tracerProvider) {
109
106
  throw new Error(
110
- 'Configuration not initialized. Call init() before start().',
111
- )
107
+ 'Configuration not initialized. Call init() before start().'
108
+ );
112
109
  }
113
110
 
114
- this._setSessionId('')
111
+ this._setSessionId('');
115
112
  }
116
113
 
117
114
  setApiKey(apiKey: string): void {
118
115
  if (!this.exporter) {
119
116
  throw new Error(
120
- 'Configuration not initialized. Call init() before setApiKey().',
121
- )
117
+ 'Configuration not initialized. Call init() before setApiKey().'
118
+ );
122
119
  }
123
120
 
124
- this.exporter.setApiKey?.(apiKey)
121
+ this.exporter.setApiKey?.(apiKey);
125
122
  }
126
123
 
127
124
  setSessionId(sessionId: string, sessionType: SessionType): void {
128
- this._setSessionId(sessionId, sessionType)
125
+ this._setSessionId(sessionId, sessionType);
129
126
  }
130
127
 
131
128
  // Shutdown (React Native specific)
132
129
  shutdown(): Promise<void> {
133
- return Promise.resolve()
130
+ return Promise.resolve();
134
131
  }
135
132
  }
@@ -1,42 +1,44 @@
1
- import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch'
2
- import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request'
3
-
4
- import { logger } from '../../utils'
5
- import { OTEL_IGNORE_URLS } from '../../config'
6
- import { type TracerReactNativeConfig } from '../../types'
7
- import { extractResponseBody, headersToObject, processHttpPayload } from '../helpers'
1
+ import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
2
+ import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
3
+
4
+ import { logger } from '../../utils';
5
+ import { OTEL_IGNORE_URLS } from '../../config';
6
+ import { type TracerReactNativeConfig } from '../../types';
7
+ import {
8
+ extractResponseBody,
9
+ headersToObject,
10
+ processHttpPayload,
11
+ } from '../helpers';
8
12
 
9
13
  export function getInstrumentations(config: TracerReactNativeConfig) {
10
-
11
- const instrumentations = []
14
+ const instrumentations = [];
12
15
 
13
16
  // Fetch instrumentation
14
17
  try {
15
18
  instrumentations.push(
16
19
  new FetchInstrumentation({
17
20
  clearTimingResources: false,
18
- ignoreUrls: [
19
- ...OTEL_IGNORE_URLS,
20
- ...(config.ignoreUrls || []),
21
- ],
21
+ ignoreUrls: [...OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
22
22
  propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
23
23
  applyCustomAttributesOnSpan: async (span, request, response) => {
24
- if (!config) return
24
+ if (!config) return;
25
25
 
26
- const { captureBody, captureHeaders } = config
26
+ const { captureBody, captureHeaders } = config;
27
27
 
28
28
  try {
29
29
  if (!captureBody && !captureHeaders) {
30
- return
30
+ return;
31
31
  }
32
32
 
33
- const requestBody = request.body
34
- const requestHeaders = headersToObject(request.headers)
35
- const responseHeaders = headersToObject(response instanceof Response ? response.headers : undefined)
33
+ const requestBody = request.body;
34
+ const requestHeaders = headersToObject(request.headers);
35
+ const responseHeaders = headersToObject(
36
+ response instanceof Response ? response.headers : undefined
37
+ );
36
38
 
37
- let responseBody: string | null = null
39
+ let responseBody: string | null = null;
38
40
  if (response instanceof Response && response.body) {
39
- responseBody = await extractResponseBody(response)
41
+ responseBody = await extractResponseBody(response);
40
42
  }
41
43
 
42
44
  const payload = {
@@ -44,17 +46,17 @@ export function getInstrumentations(config: TracerReactNativeConfig) {
44
46
  responseBody,
45
47
  requestHeaders,
46
48
  responseHeaders,
47
- }
48
- processHttpPayload(payload, config, span)
49
+ };
50
+ processHttpPayload(payload, config, span);
49
51
  } catch (error) {
50
52
  // eslint-disable-next-line
51
53
  logger.error('DEBUGGER_LIB', 'Failed to capture fetch payload', error)
52
54
  }
53
55
  },
54
56
  })
55
- )
57
+ );
56
58
  } catch (error) {
57
- logger.warn('DEBUGGER_LIB', 'Fetch instrumentation not available', error)
59
+ logger.warn('DEBUGGER_LIB', 'Fetch instrumentation not available', error);
58
60
  }
59
61
 
60
62
  // XMLHttpRequest instrumentation
@@ -62,46 +64,47 @@ export function getInstrumentations(config: TracerReactNativeConfig) {
62
64
  instrumentations.push(
63
65
  new XMLHttpRequestInstrumentation({
64
66
  clearTimingResources: false,
65
- ignoreUrls: [
66
- ...OTEL_IGNORE_URLS,
67
- ...(config.ignoreUrls || []),
68
- ],
67
+ ignoreUrls: [...OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
69
68
  propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
70
69
  applyCustomAttributesOnSpan: (span, xhr) => {
71
- if (!config) return
70
+ if (!config) return;
72
71
 
73
- const { captureBody, captureHeaders } = config
72
+ const { captureBody, captureHeaders } = config;
74
73
 
75
74
  try {
76
75
  if (!captureBody && !captureHeaders) {
77
- return
76
+ return;
78
77
  }
79
78
 
80
79
  // @ts-ignore
81
- const requestBody = xhr.networkRequest.requestBody
80
+ const requestBody = xhr.networkRequest.requestBody;
82
81
  // @ts-ignore
83
- const responseBody = xhr.networkRequest.responseBody
82
+ const responseBody = xhr.networkRequest.responseBody;
84
83
  // @ts-ignore
85
- const requestHeaders = xhr.networkRequest.requestHeaders || {}
84
+ const requestHeaders = xhr.networkRequest.requestHeaders || {};
86
85
  // @ts-ignore
87
- const responseHeaders = xhr.networkRequest.responseHeaders || {}
86
+ const responseHeaders = xhr.networkRequest.responseHeaders || {};
88
87
 
89
88
  const payload = {
90
89
  requestBody,
91
90
  responseBody,
92
91
  requestHeaders,
93
92
  responseHeaders,
94
- }
95
- processHttpPayload(payload, config, span)
93
+ };
94
+ processHttpPayload(payload, config, span);
96
95
  } catch (error) {
97
96
  // eslint-disable-next-line
98
97
  logger.error('DEBUGGER_LIB', 'Failed to capture xml-http payload', error)
99
98
  }
100
99
  },
101
100
  })
102
- )
101
+ );
103
102
  } catch (error) {
104
- logger.warn('DEBUGGER_LIB', 'XMLHttpRequest instrumentation not available', error)
103
+ logger.warn(
104
+ 'DEBUGGER_LIB',
105
+ 'XMLHttpRequest instrumentation not available',
106
+ error
107
+ );
105
108
  }
106
109
 
107
110
  // Custom React Native instrumentations
@@ -111,5 +114,5 @@ export function getInstrumentations(config: TracerReactNativeConfig) {
111
114
  // console.warn('React Native instrumentation not available:', error)
112
115
  // }
113
116
 
114
- return instrumentations
117
+ return instrumentations;
115
118
  }
@@ -1 +1 @@
1
- import './xhr'
1
+ import './xhr';
package/src/patch/xhr.ts CHANGED
@@ -1,149 +1,148 @@
1
- import { Platform } from 'react-native'
2
- import {
3
-
4
- isFormData,
5
- isNullish,
6
- isObject,
7
- isString,
8
- } from '../utils/type-utils'
9
- import { formDataToQuery } from '../utils/request-utils'
10
- import { DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE } from '../config'
1
+ import { Platform } from 'react-native';
2
+ import { isFormData, isNullish, isObject, isString } from '../utils/type-utils';
3
+ import { formDataToQuery } from '../utils/request-utils';
4
+ import { DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE } from '../config';
11
5
 
12
6
  // Check if we're on web platform
13
- const isWeb = Platform.OS === 'web'
14
-
15
- let recordRequestHeaders = true
16
- let recordResponseHeaders = true
17
- let shouldRecordBody = true
18
- let maxCapturingHttpPayloadSize = DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE
19
-
20
- export const setMaxCapturingHttpPayloadSize = (_maxCapturingHttpPayloadSize: number) => {
21
- maxCapturingHttpPayloadSize = _maxCapturingHttpPayloadSize
22
- }
23
-
24
- export const setShouldRecordHttpData = (shouldRecordBody: boolean, shouldRecordHeaders: boolean) => {
25
- recordRequestHeaders = shouldRecordHeaders
26
- recordResponseHeaders = shouldRecordHeaders
27
- shouldRecordBody = shouldRecordBody
28
- }
7
+ const isWeb = Platform.OS === 'web';
8
+
9
+ let recordRequestHeaders = true;
10
+ let recordResponseHeaders = true;
11
+ let shouldRecordBody = true;
12
+ let maxCapturingHttpPayloadSize = DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE;
13
+
14
+ export const setMaxCapturingHttpPayloadSize = (
15
+ _maxCapturingHttpPayloadSize: number
16
+ ) => {
17
+ maxCapturingHttpPayloadSize = _maxCapturingHttpPayloadSize;
18
+ };
19
+
20
+ export const setShouldRecordHttpData = (
21
+ shouldRecordBody: boolean,
22
+ shouldRecordHeaders: boolean
23
+ ) => {
24
+ recordRequestHeaders = shouldRecordHeaders;
25
+ recordResponseHeaders = shouldRecordHeaders;
26
+ shouldRecordBody = shouldRecordBody;
27
+ };
29
28
 
30
29
  function _tryReadXHRBody({
31
30
  body,
32
31
  }: {
33
- body: any | null | undefined
34
- url: string | URL | RequestInfo
32
+ body: any | null | undefined;
33
+ url: string | URL | RequestInfo;
35
34
  }): string | null {
36
-
37
35
  if (isNullish(body)) {
38
- return null
36
+ return null;
39
37
  }
40
38
 
41
39
  if (isString(body)) {
42
- return body
40
+ return body;
43
41
  }
44
42
 
45
43
  if (isFormData(body)) {
46
- return formDataToQuery(body)
44
+ return formDataToQuery(body);
47
45
  }
48
46
 
49
47
  if (isObject(body)) {
50
48
  try {
51
- return JSON.stringify({ ...body })
49
+ return JSON.stringify({ ...body });
52
50
  } catch {
53
- return '[XHR] Failed to stringify response object'
51
+ return '[XHR] Failed to stringify response object';
54
52
  }
55
53
  }
56
54
 
57
- return `[XHR] Cannot read body of type ${Object.prototype.toString.call(body)}`
55
+ return `[XHR] Cannot read body of type ${Object.prototype.toString.call(body)}`;
58
56
  }
59
57
 
60
58
  // Only patch XMLHttpRequest if not on web platform or if XMLHttpRequest is available
61
59
  if (!isWeb && typeof XMLHttpRequest !== 'undefined') {
62
60
  (function (xhr) {
63
- const originalOpen = XMLHttpRequest.prototype.open
61
+ const originalOpen = XMLHttpRequest.prototype.open;
64
62
 
65
63
  xhr.open = function (
66
64
  method: string,
67
65
  url: string | URL,
68
66
  async = true,
69
67
  username?: string | null,
70
- password?: string | null,
68
+ password?: string | null
71
69
  ) {
72
- const xhr = this as XMLHttpRequest
70
+ const xhr = this as XMLHttpRequest;
73
71
  const networkRequest: {
74
- requestHeaders?: any,
75
- requestBody?: any,
76
- responseHeaders?: any,
77
- responseBody?: any,
78
- } = {}
79
-
72
+ requestHeaders?: any;
73
+ requestBody?: any;
74
+ responseHeaders?: any;
75
+ responseBody?: any;
76
+ } = {};
80
77
 
81
78
  // @ts-ignore
82
- const requestHeaders: Record<string, string> = {}
83
- const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr)
79
+ const requestHeaders: Record<string, string> = {};
80
+ const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr);
84
81
  xhr.setRequestHeader = (header: string, value: string) => {
85
- requestHeaders[header] = value
86
- return originalSetRequestHeader(header, value)
87
- }
82
+ requestHeaders[header] = value;
83
+ return originalSetRequestHeader(header, value);
84
+ };
88
85
  if (recordRequestHeaders) {
89
- networkRequest.requestHeaders = requestHeaders
86
+ networkRequest.requestHeaders = requestHeaders;
90
87
  }
91
88
 
92
- const originalSend = xhr.send.bind(xhr)
89
+ const originalSend = xhr.send.bind(xhr);
93
90
  xhr.send = (body) => {
94
91
  if (shouldRecordBody) {
95
- const requestBody = _tryReadXHRBody({ body, url })
92
+ const requestBody = _tryReadXHRBody({ body, url });
96
93
 
97
94
  if (
98
- requestBody?.length
99
- && requestBody.length <= maxCapturingHttpPayloadSize
95
+ requestBody?.length &&
96
+ requestBody.length <= maxCapturingHttpPayloadSize
100
97
  ) {
101
- networkRequest.requestBody = requestBody
98
+ networkRequest.requestBody = requestBody;
102
99
  }
103
100
  }
104
- return originalSend(body)
105
- }
101
+ return originalSend(body);
102
+ };
106
103
 
107
104
  xhr.addEventListener('readystatechange', () => {
108
105
  if (xhr.readyState !== xhr.DONE) {
109
- return
106
+ return;
110
107
  }
111
108
 
112
109
  // @ts-ignore
113
- const responseHeaders: Record<string, string> = {}
114
- const rawHeaders = xhr.getAllResponseHeaders() || ''
115
- const headers = rawHeaders.trim().split(/[\r\n]+/).filter(Boolean)
110
+ const responseHeaders: Record<string, string> = {};
111
+ const rawHeaders = xhr.getAllResponseHeaders() || '';
112
+ const headers = rawHeaders
113
+ .trim()
114
+ .split(/[\r\n]+/)
115
+ .filter(Boolean);
116
116
 
117
117
  headers.forEach((line) => {
118
- const parts = line.split(': ')
119
- const header = parts.shift()
120
- const value = parts.join(': ')
118
+ const parts = line.split(': ');
119
+ const header = parts.shift();
120
+ const value = parts.join(': ');
121
121
  if (header) {
122
- responseHeaders[header] = value
122
+ responseHeaders[header] = value;
123
123
  }
124
- })
124
+ });
125
125
  if (recordResponseHeaders) {
126
- networkRequest.responseHeaders = responseHeaders
126
+ networkRequest.responseHeaders = responseHeaders;
127
127
  }
128
128
  if (shouldRecordBody) {
129
- const responseBody = _tryReadXHRBody({ body: xhr.response, url })
129
+ const responseBody = _tryReadXHRBody({ body: xhr.response, url });
130
130
 
131
131
  if (
132
- responseBody?.length
133
- && responseBody.length <= maxCapturingHttpPayloadSize
132
+ responseBody?.length &&
133
+ responseBody.length <= maxCapturingHttpPayloadSize
134
134
  ) {
135
- networkRequest.responseBody = responseBody
135
+ networkRequest.responseBody = responseBody;
136
136
  }
137
137
  }
138
- })
139
-
138
+ });
140
139
 
141
140
  // @ts-ignore
142
- xhr.networkRequest = networkRequest
141
+ xhr.networkRequest = networkRequest;
143
142
 
144
- originalOpen.call(xhr, method, url as string, async, username, password)
145
- }
146
- })(XMLHttpRequest.prototype)
143
+ originalOpen.call(xhr, method, url as string, async, username, password);
144
+ };
145
+ })(XMLHttpRequest.prototype);
147
146
  } else if (isWeb) {
148
- console.info('XHR patch: Skipping XMLHttpRequest patching on web platform')
147
+ console.info('XHR patch: Skipping XMLHttpRequest patching on web platform');
149
148
  }