@multiplayer-app/session-recorder-react-native 1.0.1-beta.1 → 1.0.1-beta.11

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 (469) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +296 -156
  3. package/SessionRecorderNative.podspec +35 -14
  4. package/android/build.gradle +50 -54
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeConfig.kt +52 -0
  7. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeModule.kt +861 -0
  8. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativePackage.kt +33 -0
  9. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeSpec.kt +79 -0
  10. package/android/src/main/java/com/sessionrecordernative/model/TargetInfo.kt +9 -0
  11. package/android/src/main/java/com/sessionrecordernative/util/ViewUtils.kt +72 -0
  12. package/ios/GestureTargetFinder.swift +50 -0
  13. package/ios/SessionRecorderNative-Bridging-Header.h +2 -0
  14. package/ios/{GestureRecorderNative.m → SessionRecorderNative.mm} +17 -6
  15. package/ios/SessionRecorderNative.swift +256 -4
  16. package/lib/module/SessionRecorderNativeSpec.js +5 -0
  17. package/lib/module/SessionRecorderNativeSpec.js.map +1 -0
  18. package/lib/module/components/ScreenRecorderView/ScreenRecorderView.js +23 -0
  19. package/lib/module/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -0
  20. package/lib/module/components/ScreenRecorderView/index.js +4 -0
  21. package/lib/module/components/ScreenRecorderView/index.js.map +1 -0
  22. package/lib/module/components/SessionRecorderWidget/ErrorBanner.js +64 -0
  23. package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -0
  24. package/lib/module/components/SessionRecorderWidget/FinalPopover.js +74 -0
  25. package/lib/module/components/SessionRecorderWidget/FinalPopover.js.map +1 -0
  26. package/lib/module/components/SessionRecorderWidget/FloatingButton.js +191 -0
  27. package/lib/module/components/SessionRecorderWidget/FloatingButton.js.map +1 -0
  28. package/lib/module/components/SessionRecorderWidget/InitialPopover.js +138 -0
  29. package/lib/module/components/SessionRecorderWidget/InitialPopover.js.map +1 -0
  30. package/lib/module/components/SessionRecorderWidget/ModalContainer.js +177 -0
  31. package/lib/module/components/SessionRecorderWidget/ModalContainer.js.map +1 -0
  32. package/lib/module/components/SessionRecorderWidget/ModalHeader.js +27 -0
  33. package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -0
  34. package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js +133 -0
  35. package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -0
  36. package/lib/module/components/SessionRecorderWidget/icons.js +93 -0
  37. package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -0
  38. package/lib/module/components/SessionRecorderWidget/index.js +5 -0
  39. package/lib/module/components/SessionRecorderWidget/index.js.map +1 -0
  40. package/lib/module/components/SessionRecorderWidget/styles.js +173 -0
  41. package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -0
  42. package/lib/module/components/index.js +5 -0
  43. package/lib/module/components/index.js.map +1 -0
  44. package/lib/module/config/constants.js +42 -0
  45. package/lib/module/config/constants.js.map +1 -0
  46. package/lib/module/config/defaults.js +81 -0
  47. package/lib/module/config/defaults.js.map +1 -0
  48. package/lib/module/config/index.js +9 -0
  49. package/lib/module/config/index.js.map +1 -0
  50. package/lib/module/config/masking.js +35 -0
  51. package/lib/module/config/masking.js.map +1 -0
  52. package/lib/module/config/session-recorder.js +44 -0
  53. package/lib/module/config/session-recorder.js.map +1 -0
  54. package/lib/module/config/validators.js +28 -0
  55. package/lib/module/config/validators.js.map +1 -0
  56. package/lib/module/config/widget.js +35 -0
  57. package/lib/module/config/widget.js.map +1 -0
  58. package/lib/module/context/SessionRecorderContext.js +93 -0
  59. package/lib/module/context/SessionRecorderContext.js.map +1 -0
  60. package/lib/module/context/SessionRecorderStore.js +12 -0
  61. package/lib/module/context/SessionRecorderStore.js.map +1 -0
  62. package/lib/module/context/useSessionRecorderStore.js +20 -0
  63. package/lib/module/context/useSessionRecorderStore.js.map +1 -0
  64. package/lib/module/context/useStoreSelector.js +27 -0
  65. package/lib/module/context/useStoreSelector.js.map +1 -0
  66. package/lib/module/index.js +16 -0
  67. package/lib/module/index.js.map +1 -0
  68. package/lib/module/native/SessionRecorderNative.js +79 -0
  69. package/lib/module/native/SessionRecorderNative.js.map +1 -0
  70. package/lib/module/native/index.js +4 -0
  71. package/lib/module/native/index.js.map +1 -0
  72. package/lib/module/otel/helpers.js +218 -0
  73. package/lib/module/otel/helpers.js.map +1 -0
  74. package/lib/module/otel/index.js +95 -0
  75. package/lib/module/otel/index.js.map +1 -0
  76. package/lib/module/otel/instrumentations/index.js +102 -0
  77. package/lib/module/otel/instrumentations/index.js.map +1 -0
  78. package/lib/module/package.json +1 -0
  79. package/lib/module/patch/index.js +4 -0
  80. package/lib/module/patch/index.js.map +1 -0
  81. package/lib/module/patch/xhr.js +116 -0
  82. package/lib/module/patch/xhr.js.map +1 -0
  83. package/lib/module/recorder/eventExporter.js +130 -0
  84. package/lib/module/recorder/eventExporter.js.map +1 -0
  85. package/lib/module/recorder/gestureRecorder.js +641 -0
  86. package/lib/module/recorder/gestureRecorder.js.map +1 -0
  87. package/lib/module/recorder/index.js +168 -0
  88. package/lib/module/recorder/index.js.map +1 -0
  89. package/lib/module/recorder/navigationTracker.js +228 -0
  90. package/lib/module/recorder/navigationTracker.js.map +1 -0
  91. package/lib/module/recorder/screenRecorder.js +495 -0
  92. package/lib/module/recorder/screenRecorder.js.map +1 -0
  93. package/lib/module/services/api.service.js +149 -0
  94. package/lib/module/services/api.service.js.map +1 -0
  95. package/lib/module/services/network.service.js +178 -0
  96. package/lib/module/services/network.service.js.map +1 -0
  97. package/lib/module/services/screenMaskingService.js +107 -0
  98. package/lib/module/services/screenMaskingService.js.map +1 -0
  99. package/lib/module/services/storage.service.js +179 -0
  100. package/lib/module/services/storage.service.js.map +1 -0
  101. package/lib/module/session-recorder.js +541 -0
  102. package/lib/module/session-recorder.js.map +1 -0
  103. package/lib/module/types/configs.js +4 -0
  104. package/lib/module/types/configs.js.map +1 -0
  105. package/lib/module/types/expo-constants.d.js +2 -0
  106. package/lib/module/types/expo-constants.d.js.map +1 -0
  107. package/lib/module/types/index.js +11 -0
  108. package/lib/module/types/index.js.map +1 -0
  109. package/lib/module/types/session-recorder.js +68 -0
  110. package/lib/module/types/session-recorder.js.map +1 -0
  111. package/lib/module/types/session.js +9 -0
  112. package/lib/module/types/session.js.map +1 -0
  113. package/lib/module/utils/app-metadata.js +28 -0
  114. package/lib/module/utils/app-metadata.js.map +1 -0
  115. package/lib/module/utils/constants.optional.expo.js +6 -0
  116. package/lib/module/utils/constants.optional.expo.js.map +1 -0
  117. package/lib/module/utils/constants.optional.js +8 -0
  118. package/lib/module/utils/constants.optional.js.map +1 -0
  119. package/lib/module/utils/createStore.js +27 -0
  120. package/lib/module/utils/createStore.js.map +1 -0
  121. package/lib/module/utils/index.js +11 -0
  122. package/lib/module/utils/index.js.map +1 -0
  123. package/lib/module/utils/logger.js +185 -0
  124. package/lib/module/utils/logger.js.map +1 -0
  125. package/lib/module/utils/platform.js +340 -0
  126. package/lib/module/utils/platform.js.map +1 -0
  127. package/lib/module/utils/request-utils.js +58 -0
  128. package/lib/module/utils/request-utils.js.map +1 -0
  129. package/lib/module/utils/rrweb-events.js +276 -0
  130. package/lib/module/utils/rrweb-events.js.map +1 -0
  131. package/lib/module/utils/session.js +21 -0
  132. package/lib/module/utils/session.js.map +1 -0
  133. package/lib/module/utils/shallowEqual.js +17 -0
  134. package/lib/module/utils/shallowEqual.js.map +1 -0
  135. package/lib/module/utils/time.js +17 -0
  136. package/lib/module/utils/time.js.map +1 -0
  137. package/lib/module/utils/type-utils.js +69 -0
  138. package/lib/module/utils/type-utils.js.map +1 -0
  139. package/lib/module/version.js +4 -0
  140. package/lib/module/version.js.map +1 -0
  141. package/lib/typescript/package.json +1 -0
  142. package/{dist/native/SessionRecorderNativeTurboSpec.d.ts → lib/typescript/src/SessionRecorderNativeSpec.d.ts} +14 -6
  143. package/lib/typescript/src/SessionRecorderNativeSpec.d.ts.map +1 -0
  144. package/lib/typescript/src/components/ScreenRecorderView/ScreenRecorderView.d.ts +6 -0
  145. package/lib/typescript/src/components/ScreenRecorderView/ScreenRecorderView.d.ts.map +1 -0
  146. package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +2 -0
  147. package/lib/typescript/src/components/ScreenRecorderView/index.d.ts.map +1 -0
  148. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ErrorBanner.d.ts +1 -0
  149. package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -0
  150. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/FinalPopover.d.ts +2 -1
  151. package/lib/typescript/src/components/SessionRecorderWidget/FinalPopover.d.ts.map +1 -0
  152. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/FloatingButton.d.ts +1 -0
  153. package/lib/typescript/src/components/SessionRecorderWidget/FloatingButton.d.ts.map +1 -0
  154. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/InitialPopover.d.ts +2 -1
  155. package/lib/typescript/src/components/SessionRecorderWidget/InitialPopover.d.ts.map +1 -0
  156. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ModalContainer.d.ts +1 -0
  157. package/lib/typescript/src/components/SessionRecorderWidget/ModalContainer.d.ts.map +1 -0
  158. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ModalHeader.d.ts +1 -0
  159. package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -0
  160. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/SessionRecorderWidget.d.ts +1 -0
  161. package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -0
  162. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/icons.d.ts +1 -0
  163. package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -0
  164. package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +3 -0
  165. package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts.map +1 -0
  166. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/styles.d.ts +4 -3
  167. package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -0
  168. package/lib/typescript/src/components/index.d.ts +3 -0
  169. package/lib/typescript/src/components/index.d.ts.map +1 -0
  170. package/{dist → lib/typescript/src}/config/constants.d.ts +1 -0
  171. package/lib/typescript/src/config/constants.d.ts.map +1 -0
  172. package/{dist → lib/typescript/src}/config/defaults.d.ts +2 -1
  173. package/lib/typescript/src/config/defaults.d.ts.map +1 -0
  174. package/{dist → lib/typescript/src}/config/index.d.ts +1 -0
  175. package/lib/typescript/src/config/index.d.ts.map +1 -0
  176. package/lib/typescript/src/config/masking.d.ts +3 -0
  177. package/lib/typescript/src/config/masking.d.ts.map +1 -0
  178. package/lib/typescript/src/config/session-recorder.d.ts +3 -0
  179. package/lib/typescript/src/config/session-recorder.d.ts.map +1 -0
  180. package/{dist → lib/typescript/src}/config/validators.d.ts +1 -0
  181. package/lib/typescript/src/config/validators.d.ts.map +1 -0
  182. package/{dist → lib/typescript/src}/config/widget.d.ts +2 -1
  183. package/lib/typescript/src/config/widget.d.ts.map +1 -0
  184. package/{dist → lib/typescript/src}/context/SessionRecorderContext.d.ts +3 -2
  185. package/lib/typescript/src/context/SessionRecorderContext.d.ts.map +1 -0
  186. package/{dist → lib/typescript/src}/context/SessionRecorderStore.d.ts +2 -1
  187. package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -0
  188. package/{dist → lib/typescript/src}/context/useSessionRecorderStore.d.ts +4 -3
  189. package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -0
  190. package/{dist → lib/typescript/src}/context/useStoreSelector.d.ts +2 -1
  191. package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -0
  192. package/{dist → lib/typescript/src}/index.d.ts +2 -0
  193. package/lib/typescript/src/index.d.ts.map +1 -0
  194. package/lib/typescript/src/native/SessionRecorderNative.d.ts +27 -0
  195. package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -0
  196. package/lib/typescript/src/native/index.d.ts +2 -0
  197. package/lib/typescript/src/native/index.d.ts.map +1 -0
  198. package/{dist → lib/typescript/src}/otel/helpers.d.ts +3 -2
  199. package/lib/typescript/src/otel/helpers.d.ts.map +1 -0
  200. package/{dist → lib/typescript/src}/otel/index.d.ts +2 -2
  201. package/lib/typescript/src/otel/index.d.ts.map +1 -0
  202. package/{dist → lib/typescript/src}/otel/instrumentations/index.d.ts +2 -1
  203. package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -0
  204. package/lib/typescript/src/patch/index.d.ts +2 -0
  205. package/lib/typescript/src/patch/index.d.ts.map +1 -0
  206. package/{dist → lib/typescript/src}/patch/xhr.d.ts +1 -0
  207. package/lib/typescript/src/patch/xhr.d.ts.map +1 -0
  208. package/{dist → lib/typescript/src}/recorder/eventExporter.d.ts +2 -1
  209. package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -0
  210. package/{dist → lib/typescript/src}/recorder/gestureRecorder.d.ts +3 -2
  211. package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -0
  212. package/{dist → lib/typescript/src}/recorder/index.d.ts +3 -2
  213. package/lib/typescript/src/recorder/index.d.ts.map +1 -0
  214. package/{dist → lib/typescript/src}/recorder/navigationTracker.d.ts +2 -1
  215. package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -0
  216. package/{dist → lib/typescript/src}/recorder/screenRecorder.d.ts +4 -4
  217. package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -0
  218. package/{dist → lib/typescript/src}/services/api.service.d.ts +2 -1
  219. package/lib/typescript/src/services/api.service.d.ts.map +1 -0
  220. package/{dist → lib/typescript/src}/services/network.service.d.ts +1 -0
  221. package/lib/typescript/src/services/network.service.d.ts.map +1 -0
  222. package/{dist → lib/typescript/src}/services/screenMaskingService.d.ts +2 -1
  223. package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -0
  224. package/{dist → lib/typescript/src}/services/storage.service.d.ts +2 -1
  225. package/lib/typescript/src/services/storage.service.d.ts.map +1 -0
  226. package/{dist → lib/typescript/src}/session-recorder.d.ts +3 -2
  227. package/lib/typescript/src/session-recorder.d.ts.map +1 -0
  228. package/{dist → lib/typescript/src}/types/configs.d.ts +3 -2
  229. package/lib/typescript/src/types/configs.d.ts.map +1 -0
  230. package/{dist → lib/typescript/src}/types/index.d.ts +1 -0
  231. package/lib/typescript/src/types/index.d.ts.map +1 -0
  232. package/{dist → lib/typescript/src}/types/session-recorder.d.ts +7 -6
  233. package/lib/typescript/src/types/session-recorder.d.ts.map +1 -0
  234. package/{dist → lib/typescript/src}/types/session.d.ts +1 -0
  235. package/lib/typescript/src/types/session.d.ts.map +1 -0
  236. package/{dist → lib/typescript/src}/utils/app-metadata.d.ts +1 -0
  237. package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -0
  238. package/{dist → lib/typescript/src}/utils/constants.optional.d.ts +1 -0
  239. package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -0
  240. package/{dist → lib/typescript/src}/utils/constants.optional.expo.d.ts +1 -0
  241. package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -0
  242. package/{dist → lib/typescript/src}/utils/createStore.d.ts +1 -0
  243. package/lib/typescript/src/utils/createStore.d.ts.map +1 -0
  244. package/lib/typescript/src/utils/index.d.ts +8 -0
  245. package/lib/typescript/src/utils/index.d.ts.map +1 -0
  246. package/{dist → lib/typescript/src}/utils/logger.d.ts +2 -1
  247. package/lib/typescript/src/utils/logger.d.ts.map +1 -0
  248. package/{dist → lib/typescript/src}/utils/platform.d.ts +2 -1
  249. package/lib/typescript/src/utils/platform.d.ts.map +1 -0
  250. package/{dist → lib/typescript/src}/utils/request-utils.d.ts +1 -0
  251. package/lib/typescript/src/utils/request-utils.d.ts.map +1 -0
  252. package/{dist → lib/typescript/src}/utils/rrweb-events.d.ts +2 -1
  253. package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -0
  254. package/{dist → lib/typescript/src}/utils/session.d.ts +1 -0
  255. package/lib/typescript/src/utils/session.d.ts.map +1 -0
  256. package/{dist → lib/typescript/src}/utils/shallowEqual.d.ts +1 -0
  257. package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -0
  258. package/{dist → lib/typescript/src}/utils/time.d.ts +1 -0
  259. package/lib/typescript/src/utils/time.d.ts.map +1 -0
  260. package/{dist → lib/typescript/src}/utils/type-utils.d.ts +1 -0
  261. package/lib/typescript/src/utils/type-utils.d.ts.map +1 -0
  262. package/lib/typescript/src/version.d.ts +2 -0
  263. package/lib/typescript/src/version.d.ts.map +1 -0
  264. package/package.json +154 -37
  265. package/react-native.config.js +14 -0
  266. package/src/SessionRecorderNativeSpec.ts +33 -0
  267. package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +20 -0
  268. package/src/components/ScreenRecorderView/index.ts +1 -0
  269. package/src/components/SessionRecorderWidget/ErrorBanner.tsx +58 -0
  270. package/src/components/SessionRecorderWidget/FinalPopover.tsx +96 -0
  271. package/src/components/SessionRecorderWidget/FloatingButton.tsx +176 -0
  272. package/src/components/SessionRecorderWidget/InitialPopover.tsx +167 -0
  273. package/src/components/SessionRecorderWidget/ModalContainer.tsx +189 -0
  274. package/src/components/SessionRecorderWidget/ModalHeader.tsx +26 -0
  275. package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +150 -0
  276. package/src/components/SessionRecorderWidget/icons.tsx +80 -0
  277. package/src/components/SessionRecorderWidget/index.ts +3 -0
  278. package/src/components/SessionRecorderWidget/styles.ts +168 -0
  279. package/src/config/constants.ts +67 -0
  280. package/src/config/defaults.ts +105 -0
  281. package/src/config/index.ts +6 -0
  282. package/src/config/masking.ts +60 -0
  283. package/src/config/session-recorder.ts +87 -0
  284. package/src/config/validators.ts +54 -0
  285. package/src/config/widget.ts +47 -0
  286. package/src/context/SessionRecorderContext.tsx +138 -0
  287. package/src/context/SessionRecorderStore.ts +22 -0
  288. package/src/context/useSessionRecorderStore.ts +34 -0
  289. package/src/context/useStoreSelector.ts +36 -0
  290. package/src/index.ts +13 -0
  291. package/src/native/SessionRecorderNative.ts +120 -0
  292. package/src/native/index.ts +5 -0
  293. package/src/otel/helpers.ts +290 -0
  294. package/src/otel/index.ts +132 -0
  295. package/src/otel/instrumentations/index.ts +118 -0
  296. package/src/patch/xhr.ts +148 -0
  297. package/src/recorder/eventExporter.ts +150 -0
  298. package/src/recorder/gestureRecorder.ts +828 -0
  299. package/src/recorder/index.ts +203 -0
  300. package/src/recorder/navigationTracker.ts +268 -0
  301. package/src/recorder/screenRecorder.ts +600 -0
  302. package/src/services/api.service.ts +216 -0
  303. package/src/services/network.service.ts +191 -0
  304. package/src/services/screenMaskingService.ts +153 -0
  305. package/src/services/storage.service.ts +248 -0
  306. package/src/session-recorder.ts +647 -0
  307. package/src/types/configs.ts +118 -0
  308. package/src/types/expo-constants.d.ts +7 -0
  309. package/src/types/index.ts +27 -0
  310. package/src/types/session-recorder.ts +381 -0
  311. package/src/types/session.ts +65 -0
  312. package/src/utils/app-metadata.ts +31 -0
  313. package/src/utils/constants.optional.expo.ts +5 -0
  314. package/src/utils/constants.optional.ts +18 -0
  315. package/src/utils/createStore.ts +32 -0
  316. package/{dist/utils/index.d.ts → src/utils/index.ts} +1 -0
  317. package/src/utils/logger.ts +245 -0
  318. package/src/utils/platform.ts +401 -0
  319. package/src/utils/request-utils.ts +61 -0
  320. package/src/utils/rrweb-events.ts +329 -0
  321. package/src/utils/session.ts +22 -0
  322. package/src/utils/shallowEqual.ts +20 -0
  323. package/src/utils/time.ts +20 -0
  324. package/src/utils/type-utils.ts +75 -0
  325. package/src/version.ts +1 -0
  326. package/copy-react-native-dist.sh +0 -56
  327. package/dist/components/ScreenRecorderView/ScreenRecorderView.d.ts +0 -5
  328. package/dist/components/ScreenRecorderView/ScreenRecorderView.js +0 -1
  329. package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +0 -1
  330. package/dist/components/ScreenRecorderView/index.d.ts +0 -1
  331. package/dist/components/ScreenRecorderView/index.js +0 -1
  332. package/dist/components/ScreenRecorderView/index.js.map +0 -1
  333. package/dist/components/SessionRecorderWidget/ErrorBanner.js +0 -1
  334. package/dist/components/SessionRecorderWidget/ErrorBanner.js.map +0 -1
  335. package/dist/components/SessionRecorderWidget/FinalPopover.js +0 -1
  336. package/dist/components/SessionRecorderWidget/FinalPopover.js.map +0 -1
  337. package/dist/components/SessionRecorderWidget/FloatingButton.js +0 -1
  338. package/dist/components/SessionRecorderWidget/FloatingButton.js.map +0 -1
  339. package/dist/components/SessionRecorderWidget/InitialPopover.js +0 -1
  340. package/dist/components/SessionRecorderWidget/InitialPopover.js.map +0 -1
  341. package/dist/components/SessionRecorderWidget/ModalContainer.js +0 -1
  342. package/dist/components/SessionRecorderWidget/ModalContainer.js.map +0 -1
  343. package/dist/components/SessionRecorderWidget/ModalHeader.js +0 -1
  344. package/dist/components/SessionRecorderWidget/ModalHeader.js.map +0 -1
  345. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js +0 -1
  346. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js.map +0 -1
  347. package/dist/components/SessionRecorderWidget/icons.js +0 -1
  348. package/dist/components/SessionRecorderWidget/icons.js.map +0 -1
  349. package/dist/components/SessionRecorderWidget/index.d.ts +0 -2
  350. package/dist/components/SessionRecorderWidget/index.js +0 -1
  351. package/dist/components/SessionRecorderWidget/index.js.map +0 -1
  352. package/dist/components/SessionRecorderWidget/styles.js +0 -1
  353. package/dist/components/SessionRecorderWidget/styles.js.map +0 -1
  354. package/dist/components/index.js +0 -1
  355. package/dist/components/index.js.map +0 -1
  356. package/dist/config/constants.js +0 -1
  357. package/dist/config/constants.js.map +0 -1
  358. package/dist/config/defaults.js +0 -1
  359. package/dist/config/defaults.js.map +0 -1
  360. package/dist/config/index.js +0 -1
  361. package/dist/config/index.js.map +0 -1
  362. package/dist/config/masking.d.ts +0 -2
  363. package/dist/config/masking.js +0 -1
  364. package/dist/config/masking.js.map +0 -1
  365. package/dist/config/session-recorder.d.ts +0 -2
  366. package/dist/config/session-recorder.js +0 -1
  367. package/dist/config/session-recorder.js.map +0 -1
  368. package/dist/config/validators.js +0 -1
  369. package/dist/config/validators.js.map +0 -1
  370. package/dist/config/widget.js +0 -1
  371. package/dist/config/widget.js.map +0 -1
  372. package/dist/context/SessionRecorderContext.js +0 -1
  373. package/dist/context/SessionRecorderContext.js.map +0 -1
  374. package/dist/context/SessionRecorderStore.js +0 -1
  375. package/dist/context/SessionRecorderStore.js.map +0 -1
  376. package/dist/context/useSessionRecorderStore.js +0 -1
  377. package/dist/context/useSessionRecorderStore.js.map +0 -1
  378. package/dist/context/useStoreSelector.js +0 -1
  379. package/dist/context/useStoreSelector.js.map +0 -1
  380. package/dist/index.js +0 -1
  381. package/dist/index.js.map +0 -1
  382. package/dist/native/GestureRecorderNative.d.ts +0 -57
  383. package/dist/native/GestureRecorderNative.js +0 -1
  384. package/dist/native/GestureRecorderNative.js.map +0 -1
  385. package/dist/native/GestureRecorderNativeTurboSpec.d.ts +0 -31
  386. package/dist/native/GestureRecorderNativeTurboSpec.js +0 -1
  387. package/dist/native/GestureRecorderNativeTurboSpec.js.map +0 -1
  388. package/dist/native/SessionRecorderNative.d.ts +0 -33
  389. package/dist/native/SessionRecorderNative.js +0 -1
  390. package/dist/native/SessionRecorderNative.js.map +0 -1
  391. package/dist/native/SessionRecorderNativeTurboSpec.js +0 -1
  392. package/dist/native/SessionRecorderNativeTurboSpec.js.map +0 -1
  393. package/dist/native/index.d.ts +0 -2
  394. package/dist/native/index.js +0 -1
  395. package/dist/native/index.js.map +0 -1
  396. package/dist/otel/helpers.js +0 -1
  397. package/dist/otel/helpers.js.map +0 -1
  398. package/dist/otel/index.js +0 -1
  399. package/dist/otel/index.js.map +0 -1
  400. package/dist/otel/instrumentations/index.js +0 -1
  401. package/dist/otel/instrumentations/index.js.map +0 -1
  402. package/dist/patch/index.js +0 -1
  403. package/dist/patch/index.js.map +0 -1
  404. package/dist/patch/xhr.js +0 -1
  405. package/dist/patch/xhr.js.map +0 -1
  406. package/dist/recorder/eventExporter.js +0 -1
  407. package/dist/recorder/eventExporter.js.map +0 -1
  408. package/dist/recorder/gestureRecorder.js +0 -1
  409. package/dist/recorder/gestureRecorder.js.map +0 -1
  410. package/dist/recorder/index.js +0 -1
  411. package/dist/recorder/index.js.map +0 -1
  412. package/dist/recorder/navigationTracker.js +0 -1
  413. package/dist/recorder/navigationTracker.js.map +0 -1
  414. package/dist/recorder/screenRecorder.js +0 -1
  415. package/dist/recorder/screenRecorder.js.map +0 -1
  416. package/dist/services/api.service.js +0 -1
  417. package/dist/services/api.service.js.map +0 -1
  418. package/dist/services/network.service.js +0 -1
  419. package/dist/services/network.service.js.map +0 -1
  420. package/dist/services/screenMaskingService.js +0 -1
  421. package/dist/services/screenMaskingService.js.map +0 -1
  422. package/dist/services/storage.service.js +0 -1
  423. package/dist/services/storage.service.js.map +0 -1
  424. package/dist/session-recorder.js +0 -1
  425. package/dist/session-recorder.js.map +0 -1
  426. package/dist/types/configs.js +0 -1
  427. package/dist/types/configs.js.map +0 -1
  428. package/dist/types/index.js +0 -1
  429. package/dist/types/index.js.map +0 -1
  430. package/dist/types/session-recorder.js +0 -1
  431. package/dist/types/session-recorder.js.map +0 -1
  432. package/dist/types/session.js +0 -1
  433. package/dist/types/session.js.map +0 -1
  434. package/dist/utils/app-metadata.js +0 -1
  435. package/dist/utils/app-metadata.js.map +0 -1
  436. package/dist/utils/constants.optional.expo.js +0 -1
  437. package/dist/utils/constants.optional.expo.js.map +0 -1
  438. package/dist/utils/constants.optional.js +0 -1
  439. package/dist/utils/constants.optional.js.map +0 -1
  440. package/dist/utils/createStore.js +0 -1
  441. package/dist/utils/createStore.js.map +0 -1
  442. package/dist/utils/index.js +0 -1
  443. package/dist/utils/index.js.map +0 -1
  444. package/dist/utils/logger.js +0 -1
  445. package/dist/utils/logger.js.map +0 -1
  446. package/dist/utils/platform.js +0 -1
  447. package/dist/utils/platform.js.map +0 -1
  448. package/dist/utils/request-utils.js +0 -1
  449. package/dist/utils/request-utils.js.map +0 -1
  450. package/dist/utils/rrweb-events.js +0 -1
  451. package/dist/utils/rrweb-events.js.map +0 -1
  452. package/dist/utils/session.js +0 -1
  453. package/dist/utils/session.js.map +0 -1
  454. package/dist/utils/shallowEqual.js +0 -1
  455. package/dist/utils/shallowEqual.js.map +0 -1
  456. package/dist/utils/time.js +0 -1
  457. package/dist/utils/time.js.map +0 -1
  458. package/dist/utils/type-utils.js +0 -1
  459. package/dist/utils/type-utils.js.map +0 -1
  460. package/dist/version.d.ts +0 -1
  461. package/dist/version.js +0 -1
  462. package/dist/version.js.map +0 -1
  463. package/docs/AUTO_METADATA_DETECTION.md +0 -108
  464. package/ios/GestureRecorderNative.swift +0 -316
  465. package/ios/SessionRecorderNative.m +0 -17
  466. package/ios/SessionRecorderNative.podspec +0 -26
  467. package/turbo.json +0 -41
  468. /package/{dist/components/index.d.ts → src/components/index.ts} +0 -0
  469. /package/{dist/patch/index.d.ts → src/patch/index.ts} +0 -0
@@ -0,0 +1,290 @@
1
+ import { type Span } from '@opentelemetry/api';
2
+ import {
3
+ MULTIPLAYER_TRACE_DEBUG_PREFIX,
4
+ MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX,
5
+ ATTR_MULTIPLAYER_HTTP_REQUEST_BODY,
6
+ ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,
7
+ ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,
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
+ export interface HttpPayloadData {
14
+ requestBody?: any;
15
+ responseBody?: any;
16
+ requestHeaders?: Record<string, string>;
17
+ responseHeaders?: Record<string, string>;
18
+ }
19
+
20
+ export interface ProcessedHttpPayload {
21
+ requestBody?: string;
22
+ responseBody?: string;
23
+ requestHeaders?: string;
24
+ responseHeaders?: string;
25
+ }
26
+
27
+ /**
28
+ * Checks if the trace should be processed based on trace ID prefixes
29
+ */
30
+ export function shouldProcessTrace(traceId: string): boolean {
31
+ return (
32
+ traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX) ||
33
+ traceId.startsWith(MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)
34
+ );
35
+ }
36
+
37
+ /**
38
+ * Processes request and response body based on trace type and configuration
39
+ */
40
+ export function processBody(
41
+ payload: HttpPayloadData,
42
+ config: TracerReactNativeConfig,
43
+ span: Span
44
+ ): { requestBody?: string; responseBody?: string } {
45
+ const { captureBody, masking } = config;
46
+ const traceId = span.spanContext().traceId;
47
+
48
+ if (!captureBody) {
49
+ return {};
50
+ }
51
+
52
+ let { requestBody, responseBody } = payload;
53
+
54
+ if (requestBody !== undefined && requestBody !== null) {
55
+ requestBody = JSON.parse(JSON.stringify(requestBody));
56
+ }
57
+ if (responseBody !== undefined && responseBody !== null) {
58
+ responseBody = JSON.parse(JSON.stringify(responseBody));
59
+ }
60
+
61
+ // Apply masking for debug traces
62
+ if (
63
+ traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX) ||
64
+ traceId.startsWith(MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)
65
+ ) {
66
+ if (masking.isContentMaskingEnabled) {
67
+ requestBody = requestBody && masking.maskBody?.(requestBody, span);
68
+ responseBody = responseBody && masking.maskBody?.(responseBody, span);
69
+ }
70
+ }
71
+
72
+ // Convert to string if needed
73
+ if (typeof requestBody !== 'string') {
74
+ requestBody = JSON.stringify(requestBody);
75
+ }
76
+
77
+ if (typeof responseBody !== 'string') {
78
+ responseBody = JSON.stringify(responseBody);
79
+ }
80
+
81
+ return {
82
+ requestBody: requestBody?.length ? requestBody : undefined,
83
+ responseBody: responseBody?.length ? responseBody : undefined,
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Processes request and response headers based on configuration
89
+ */
90
+ export function processHeaders(
91
+ payload: HttpPayloadData,
92
+ config: TracerReactNativeConfig,
93
+ span: Span
94
+ ): { requestHeaders?: string; responseHeaders?: string } {
95
+ const { captureHeaders, masking } = config;
96
+
97
+ if (!captureHeaders) {
98
+ return {};
99
+ }
100
+
101
+ let { requestHeaders = {}, responseHeaders = {} } = payload;
102
+
103
+ // Handle header filtering
104
+ if (!masking.headersToInclude?.length && !masking.headersToExclude?.length) {
105
+ // Add null checks to prevent JSON.parse error when headers is undefined
106
+ if (requestHeaders !== undefined && requestHeaders !== null) {
107
+ requestHeaders = JSON.parse(JSON.stringify(requestHeaders));
108
+ }
109
+ if (responseHeaders !== undefined && responseHeaders !== null) {
110
+ responseHeaders = JSON.parse(JSON.stringify(responseHeaders));
111
+ }
112
+ } else {
113
+ if (masking.headersToInclude) {
114
+ const _requestHeaders: Record<string, string> = {};
115
+ const _responseHeaders: Record<string, string> = {};
116
+
117
+ for (const headerName of masking.headersToInclude) {
118
+ if (requestHeaders[headerName]) {
119
+ _requestHeaders[headerName] = requestHeaders[headerName];
120
+ }
121
+ if (responseHeaders[headerName]) {
122
+ _responseHeaders[headerName] = responseHeaders[headerName];
123
+ }
124
+ }
125
+
126
+ requestHeaders = _requestHeaders;
127
+ responseHeaders = _responseHeaders;
128
+ }
129
+
130
+ if (masking.headersToExclude?.length) {
131
+ for (const headerName of masking.headersToExclude) {
132
+ delete requestHeaders[headerName];
133
+ delete responseHeaders[headerName];
134
+ }
135
+ }
136
+ }
137
+
138
+ // Apply masking
139
+ const maskedRequestHeaders =
140
+ masking.maskHeaders?.(requestHeaders, span) || requestHeaders;
141
+ const maskedResponseHeaders =
142
+ masking.maskHeaders?.(responseHeaders, span) || responseHeaders;
143
+
144
+ // Convert to string
145
+ const requestHeadersStr =
146
+ typeof maskedRequestHeaders === 'string'
147
+ ? maskedRequestHeaders
148
+ : JSON.stringify(maskedRequestHeaders);
149
+
150
+ const responseHeadersStr =
151
+ typeof maskedResponseHeaders === 'string'
152
+ ? maskedResponseHeaders
153
+ : JSON.stringify(maskedResponseHeaders);
154
+
155
+ return {
156
+ requestHeaders: requestHeadersStr?.length ? requestHeadersStr : undefined,
157
+ responseHeaders: responseHeadersStr?.length
158
+ ? responseHeadersStr
159
+ : undefined,
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Processes HTTP payload (body and headers) and sets span attributes
165
+ */
166
+ export function processHttpPayload(
167
+ payload: HttpPayloadData,
168
+ config: TracerReactNativeConfig,
169
+ span: Span
170
+ ): void {
171
+ const traceId = span.spanContext().traceId;
172
+
173
+ if (!shouldProcessTrace(traceId)) {
174
+ return;
175
+ }
176
+
177
+ const { requestBody, responseBody } = processBody(payload, config, span);
178
+ const { requestHeaders, responseHeaders } = processHeaders(
179
+ payload,
180
+ config,
181
+ span
182
+ );
183
+
184
+ // Set span attributes
185
+ if (requestBody) {
186
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_BODY, requestBody);
187
+ }
188
+
189
+ if (responseBody) {
190
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY, responseBody);
191
+ }
192
+
193
+ if (requestHeaders) {
194
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS, requestHeaders);
195
+ }
196
+
197
+ if (responseHeaders) {
198
+ span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS, responseHeaders);
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Converts Headers object to plain object
204
+ */
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> = {};
214
+
215
+ if (!headers) {
216
+ return result;
217
+ }
218
+
219
+ if (headers instanceof Headers) {
220
+ headers.forEach((value: string, key: string) => {
221
+ result[key] = value;
222
+ });
223
+ } else if (Array.isArray(headers)) {
224
+ // Handle array of [key, value] pairs
225
+ for (const [key, value] of headers) {
226
+ if (typeof key === 'string' && typeof value === 'string') {
227
+ result[key] = value;
228
+ }
229
+ }
230
+ } else if (typeof headers === 'object' && !Array.isArray(headers)) {
231
+ for (const [key, value] of Object.entries(headers)) {
232
+ if (typeof key === 'string' && typeof value === 'string') {
233
+ result[key] = value;
234
+ }
235
+ }
236
+ }
237
+
238
+ return result;
239
+ }
240
+
241
+ /**
242
+ * Extracts response body as string from Response object
243
+ */
244
+ export async function extractResponseBody(
245
+ response: Response
246
+ ): Promise<string | null> {
247
+ if (!response.body) {
248
+ return null;
249
+ }
250
+
251
+ try {
252
+ if (response.body instanceof ReadableStream) {
253
+ // Check if response body is already consumed
254
+ if (response.bodyUsed) {
255
+ return null;
256
+ }
257
+
258
+ const responseClone = response.clone();
259
+ return responseClone.text();
260
+ } else {
261
+ return JSON.stringify(response.body);
262
+ }
263
+ } catch (error) {
264
+ // If cloning fails (body already consumed), return null
265
+
266
+ logger.warn('DEBUGGER_LIB', 'Failed to extract response body', error);
267
+ return null;
268
+ }
269
+ }
270
+
271
+ export const getExporterEndpoint = (exporterEndpoint: string): string => {
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
+ })();
282
+
283
+ if (hasPath) {
284
+ return exporterEndpoint;
285
+ }
286
+
287
+ const trimmedExporterEndpoint = new URL(exporterEndpoint).origin;
288
+
289
+ return `${trimmedExporterEndpoint}/v1/traces`;
290
+ };
@@ -0,0 +1,132 @@
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
+ import {
7
+ SessionType,
8
+ ATTR_MULTIPLAYER_SESSION_ID,
9
+ SessionRecorderIdGenerator,
10
+ SessionRecorderTraceIdRatioBasedSampler,
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
+ export class TracerReactNativeSDK {
21
+ private tracerProvider?: WebTracerProvider;
22
+ private config?: TracerReactNativeConfig;
23
+
24
+ private sessionId = '';
25
+ private idGenerator?: SessionRecorderIdGenerator;
26
+ private exporter?: any;
27
+
28
+ constructor() {}
29
+
30
+ private _setSessionId(
31
+ sessionId: string,
32
+ sessionType: SessionType = SessionType.PLAIN
33
+ ) {
34
+ this.sessionId = sessionId;
35
+ this.idGenerator?.setSessionId(sessionId, sessionType);
36
+ }
37
+
38
+ init(options: TracerReactNativeConfig): void {
39
+ this.config = options;
40
+
41
+ const { application, version, environment } = this.config;
42
+
43
+ this.idGenerator = new SessionRecorderIdGenerator();
44
+
45
+ this.exporter = new SessionRecorderBrowserTraceExporter({
46
+ apiKey: options.apiKey,
47
+ url: getExporterEndpoint(options.exporterEndpoint),
48
+ });
49
+
50
+ this.tracerProvider = new WebTracerProvider({
51
+ resource: resourceFromAttributes({
52
+ [SemanticAttributes.SEMRESATTRS_SERVICE_NAME]: application,
53
+ [SemanticAttributes.SEMRESATTRS_SERVICE_VERSION]: version,
54
+ [SemanticAttributes.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment,
55
+ ...getPlatformAttributes(),
56
+ }),
57
+ idGenerator: this.idGenerator,
58
+ sampler: new SessionRecorderTraceIdRatioBasedSampler(
59
+ this.config.sampleTraceRatio || 0.15
60
+ ),
61
+ spanProcessors: [
62
+ this._getSpanSessionIdProcessor(),
63
+ new BatchSpanProcessor(this.exporter),
64
+ ],
65
+ });
66
+
67
+ this.tracerProvider.register({
68
+ propagator: new W3CTraceContextPropagator(),
69
+ });
70
+
71
+ // Register instrumentations
72
+ registerInstrumentations({
73
+ tracerProvider: this.tracerProvider,
74
+ instrumentations: getInstrumentations(this.config),
75
+ });
76
+ }
77
+
78
+ private _getSpanSessionIdProcessor() {
79
+ return {
80
+ onStart: (span: any) => {
81
+ if (this.sessionId) {
82
+ span.setAttribute(ATTR_MULTIPLAYER_SESSION_ID, this.sessionId);
83
+ }
84
+ // Add React Native specific attributes
85
+ span.setAttribute('platform', 'react-native');
86
+ span.setAttribute('timestamp', Date.now());
87
+ },
88
+ onEnd: () => {},
89
+ shutdown: () => Promise.resolve(),
90
+ forceFlush: () => Promise.resolve(),
91
+ };
92
+ }
93
+
94
+ start(sessionId: string, sessionType: SessionType): void {
95
+ if (!this.tracerProvider) {
96
+ throw new Error(
97
+ 'Configuration not initialized. Call init() before start().'
98
+ );
99
+ }
100
+
101
+ this._setSessionId(sessionId, sessionType);
102
+ }
103
+
104
+ stop(): void {
105
+ if (!this.tracerProvider) {
106
+ throw new Error(
107
+ 'Configuration not initialized. Call init() before start().'
108
+ );
109
+ }
110
+
111
+ this._setSessionId('');
112
+ }
113
+
114
+ setApiKey(apiKey: string): void {
115
+ if (!this.exporter) {
116
+ throw new Error(
117
+ 'Configuration not initialized. Call init() before setApiKey().'
118
+ );
119
+ }
120
+
121
+ this.exporter.setApiKey?.(apiKey);
122
+ }
123
+
124
+ setSessionId(sessionId: string, sessionType: SessionType): void {
125
+ this._setSessionId(sessionId, sessionType);
126
+ }
127
+
128
+ // Shutdown (React Native specific)
129
+ shutdown(): Promise<void> {
130
+ return Promise.resolve();
131
+ }
132
+ }
@@ -0,0 +1,118 @@
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';
12
+
13
+ export function getInstrumentations(config: TracerReactNativeConfig) {
14
+ const instrumentations = [];
15
+
16
+ // Fetch instrumentation
17
+ try {
18
+ instrumentations.push(
19
+ new FetchInstrumentation({
20
+ clearTimingResources: false,
21
+ ignoreUrls: [...OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
22
+ propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
23
+ applyCustomAttributesOnSpan: async (span, request, response) => {
24
+ if (!config) return;
25
+
26
+ const { captureBody, captureHeaders } = config;
27
+
28
+ try {
29
+ if (!captureBody && !captureHeaders) {
30
+ return;
31
+ }
32
+
33
+ const requestBody = request.body;
34
+ const requestHeaders = headersToObject(request.headers);
35
+ const responseHeaders = headersToObject(
36
+ response instanceof Response ? response.headers : undefined
37
+ );
38
+
39
+ let responseBody: string | null = null;
40
+ if (response instanceof Response && response.body) {
41
+ responseBody = await extractResponseBody(response);
42
+ }
43
+
44
+ const payload = {
45
+ requestBody,
46
+ responseBody,
47
+ requestHeaders,
48
+ responseHeaders,
49
+ };
50
+ processHttpPayload(payload, config, span);
51
+ } catch (error) {
52
+ // eslint-disable-next-line
53
+ logger.error('DEBUGGER_LIB', 'Failed to capture fetch payload', error)
54
+ }
55
+ },
56
+ })
57
+ );
58
+ } catch (error) {
59
+ logger.warn('DEBUGGER_LIB', 'Fetch instrumentation not available', error);
60
+ }
61
+
62
+ // XMLHttpRequest instrumentation
63
+ try {
64
+ instrumentations.push(
65
+ new XMLHttpRequestInstrumentation({
66
+ clearTimingResources: false,
67
+ ignoreUrls: [...OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
68
+ propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
69
+ applyCustomAttributesOnSpan: (span, xhr) => {
70
+ if (!config) return;
71
+
72
+ const { captureBody, captureHeaders } = config;
73
+
74
+ try {
75
+ if (!captureBody && !captureHeaders) {
76
+ return;
77
+ }
78
+
79
+ // @ts-ignore
80
+ const requestBody = xhr.networkRequest.requestBody;
81
+ // @ts-ignore
82
+ const responseBody = xhr.networkRequest.responseBody;
83
+ // @ts-ignore
84
+ const requestHeaders = xhr.networkRequest.requestHeaders || {};
85
+ // @ts-ignore
86
+ const responseHeaders = xhr.networkRequest.responseHeaders || {};
87
+
88
+ const payload = {
89
+ requestBody,
90
+ responseBody,
91
+ requestHeaders,
92
+ responseHeaders,
93
+ };
94
+ processHttpPayload(payload, config, span);
95
+ } catch (error) {
96
+ // eslint-disable-next-line
97
+ logger.error('DEBUGGER_LIB', 'Failed to capture xml-http payload', error)
98
+ }
99
+ },
100
+ })
101
+ );
102
+ } catch (error) {
103
+ logger.warn(
104
+ 'DEBUGGER_LIB',
105
+ 'XMLHttpRequest instrumentation not available',
106
+ error
107
+ );
108
+ }
109
+
110
+ // Custom React Native instrumentations
111
+ // try {
112
+ // instrumentations.push(new ReactNativeInstrumentation())
113
+ // } catch (error) {
114
+ // console.warn('React Native instrumentation not available:', error)
115
+ // }
116
+
117
+ return instrumentations;
118
+ }
@@ -0,0 +1,148 @@
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';
5
+
6
+ // Check if we're on web platform
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
+ };
28
+
29
+ function _tryReadXHRBody({
30
+ body,
31
+ }: {
32
+ body: any | null | undefined;
33
+ url: string | URL | RequestInfo;
34
+ }): string | null {
35
+ if (isNullish(body)) {
36
+ return null;
37
+ }
38
+
39
+ if (isString(body)) {
40
+ return body;
41
+ }
42
+
43
+ if (isFormData(body)) {
44
+ return formDataToQuery(body);
45
+ }
46
+
47
+ if (isObject(body)) {
48
+ try {
49
+ return JSON.stringify({ ...body });
50
+ } catch {
51
+ return '[XHR] Failed to stringify response object';
52
+ }
53
+ }
54
+
55
+ return `[XHR] Cannot read body of type ${Object.prototype.toString.call(body)}`;
56
+ }
57
+
58
+ // Only patch XMLHttpRequest if not on web platform or if XMLHttpRequest is available
59
+ if (!isWeb && typeof XMLHttpRequest !== 'undefined') {
60
+ (function (xhr) {
61
+ const originalOpen = XMLHttpRequest.prototype.open;
62
+
63
+ xhr.open = function (
64
+ method: string,
65
+ url: string | URL,
66
+ async = true,
67
+ username?: string | null,
68
+ password?: string | null
69
+ ) {
70
+ const xhr = this as XMLHttpRequest;
71
+ const networkRequest: {
72
+ requestHeaders?: any;
73
+ requestBody?: any;
74
+ responseHeaders?: any;
75
+ responseBody?: any;
76
+ } = {};
77
+
78
+ // @ts-ignore
79
+ const requestHeaders: Record<string, string> = {};
80
+ const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr);
81
+ xhr.setRequestHeader = (header: string, value: string) => {
82
+ requestHeaders[header] = value;
83
+ return originalSetRequestHeader(header, value);
84
+ };
85
+ if (recordRequestHeaders) {
86
+ networkRequest.requestHeaders = requestHeaders;
87
+ }
88
+
89
+ const originalSend = xhr.send.bind(xhr);
90
+ xhr.send = (body) => {
91
+ if (shouldRecordBody) {
92
+ const requestBody = _tryReadXHRBody({ body, url });
93
+
94
+ if (
95
+ requestBody?.length &&
96
+ requestBody.length <= maxCapturingHttpPayloadSize
97
+ ) {
98
+ networkRequest.requestBody = requestBody;
99
+ }
100
+ }
101
+ return originalSend(body);
102
+ };
103
+
104
+ xhr.addEventListener('readystatechange', () => {
105
+ if (xhr.readyState !== xhr.DONE) {
106
+ return;
107
+ }
108
+
109
+ // @ts-ignore
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
+
117
+ headers.forEach((line) => {
118
+ const parts = line.split(': ');
119
+ const header = parts.shift();
120
+ const value = parts.join(': ');
121
+ if (header) {
122
+ responseHeaders[header] = value;
123
+ }
124
+ });
125
+ if (recordResponseHeaders) {
126
+ networkRequest.responseHeaders = responseHeaders;
127
+ }
128
+ if (shouldRecordBody) {
129
+ const responseBody = _tryReadXHRBody({ body: xhr.response, url });
130
+
131
+ if (
132
+ responseBody?.length &&
133
+ responseBody.length <= maxCapturingHttpPayloadSize
134
+ ) {
135
+ networkRequest.responseBody = responseBody;
136
+ }
137
+ }
138
+ });
139
+
140
+ // @ts-ignore
141
+ xhr.networkRequest = networkRequest;
142
+
143
+ originalOpen.call(xhr, method, url as string, async, username, password);
144
+ };
145
+ })(XMLHttpRequest.prototype);
146
+ } else if (isWeb) {
147
+ console.info('XHR patch: Skipping XMLHttpRequest patching on web platform');
148
+ }