@multiplayer-app/session-recorder-react-native 1.0.0 → 1.0.1-beta.10

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 (463) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +216 -155
  3. package/SessionRecorderNative.podspec +35 -14
  4. package/android/build.gradle +65 -22
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeConfig.kt +52 -0
  8. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeModule.kt +861 -0
  9. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativePackage.kt +33 -0
  10. package/android/src/main/java/com/sessionrecordernative/SessionRecorderNativeSpec.kt +79 -0
  11. package/android/src/main/java/com/sessionrecordernative/model/TargetInfo.kt +9 -0
  12. package/android/src/main/java/com/sessionrecordernative/util/ViewUtils.kt +72 -0
  13. package/ios/GestureTargetFinder.swift +50 -0
  14. package/ios/SessionRecorderNative-Bridging-Header.h +2 -0
  15. package/ios/{GestureRecorderNative.m → SessionRecorderNative.mm} +17 -6
  16. package/ios/SessionRecorderNative.swift +256 -4
  17. package/lib/module/SessionRecorderNativeSpec.js +5 -0
  18. package/lib/module/SessionRecorderNativeSpec.js.map +1 -0
  19. package/lib/module/components/ScreenRecorderView/ScreenRecorderView.js +23 -0
  20. package/lib/module/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -0
  21. package/lib/module/components/ScreenRecorderView/index.js +4 -0
  22. package/lib/module/components/ScreenRecorderView/index.js.map +1 -0
  23. package/lib/module/components/SessionRecorderWidget/ErrorBanner.js +64 -0
  24. package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -0
  25. package/lib/module/components/SessionRecorderWidget/FinalPopover.js +74 -0
  26. package/lib/module/components/SessionRecorderWidget/FinalPopover.js.map +1 -0
  27. package/lib/module/components/SessionRecorderWidget/FloatingButton.js +191 -0
  28. package/lib/module/components/SessionRecorderWidget/FloatingButton.js.map +1 -0
  29. package/lib/module/components/SessionRecorderWidget/InitialPopover.js +138 -0
  30. package/lib/module/components/SessionRecorderWidget/InitialPopover.js.map +1 -0
  31. package/lib/module/components/SessionRecorderWidget/ModalContainer.js +177 -0
  32. package/lib/module/components/SessionRecorderWidget/ModalContainer.js.map +1 -0
  33. package/lib/module/components/SessionRecorderWidget/ModalHeader.js +27 -0
  34. package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -0
  35. package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js +133 -0
  36. package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -0
  37. package/lib/module/components/SessionRecorderWidget/icons.js +93 -0
  38. package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -0
  39. package/lib/module/components/SessionRecorderWidget/index.js +5 -0
  40. package/lib/module/components/SessionRecorderWidget/index.js.map +1 -0
  41. package/lib/module/components/SessionRecorderWidget/styles.js +173 -0
  42. package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -0
  43. package/lib/module/components/index.js +5 -0
  44. package/lib/module/components/index.js.map +1 -0
  45. package/lib/module/config/constants.js +42 -0
  46. package/lib/module/config/constants.js.map +1 -0
  47. package/lib/module/config/defaults.js +81 -0
  48. package/lib/module/config/defaults.js.map +1 -0
  49. package/lib/module/config/index.js +9 -0
  50. package/lib/module/config/index.js.map +1 -0
  51. package/lib/module/config/masking.js +35 -0
  52. package/lib/module/config/masking.js.map +1 -0
  53. package/lib/module/config/session-recorder.js +44 -0
  54. package/lib/module/config/session-recorder.js.map +1 -0
  55. package/lib/module/config/validators.js +28 -0
  56. package/lib/module/config/validators.js.map +1 -0
  57. package/lib/module/config/widget.js +35 -0
  58. package/lib/module/config/widget.js.map +1 -0
  59. package/lib/module/context/SessionRecorderContext.js +93 -0
  60. package/lib/module/context/SessionRecorderContext.js.map +1 -0
  61. package/lib/module/context/SessionRecorderStore.js +12 -0
  62. package/lib/module/context/SessionRecorderStore.js.map +1 -0
  63. package/lib/module/context/useSessionRecorderStore.js +20 -0
  64. package/lib/module/context/useSessionRecorderStore.js.map +1 -0
  65. package/lib/module/context/useStoreSelector.js +27 -0
  66. package/lib/module/context/useStoreSelector.js.map +1 -0
  67. package/lib/module/index.js +16 -0
  68. package/lib/module/index.js.map +1 -0
  69. package/lib/module/native/SessionRecorderNative.js +79 -0
  70. package/lib/module/native/SessionRecorderNative.js.map +1 -0
  71. package/lib/module/native/index.js +4 -0
  72. package/lib/module/native/index.js.map +1 -0
  73. package/lib/module/otel/helpers.js +218 -0
  74. package/lib/module/otel/helpers.js.map +1 -0
  75. package/lib/module/otel/index.js +95 -0
  76. package/lib/module/otel/index.js.map +1 -0
  77. package/lib/module/otel/instrumentations/index.js +102 -0
  78. package/lib/module/otel/instrumentations/index.js.map +1 -0
  79. package/lib/module/package.json +1 -0
  80. package/lib/module/patch/index.js +4 -0
  81. package/lib/module/patch/index.js.map +1 -0
  82. package/lib/module/patch/xhr.js +116 -0
  83. package/lib/module/patch/xhr.js.map +1 -0
  84. package/lib/module/recorder/eventExporter.js +130 -0
  85. package/lib/module/recorder/eventExporter.js.map +1 -0
  86. package/lib/module/recorder/gestureRecorder.js +641 -0
  87. package/lib/module/recorder/gestureRecorder.js.map +1 -0
  88. package/lib/module/recorder/index.js +168 -0
  89. package/lib/module/recorder/index.js.map +1 -0
  90. package/lib/module/recorder/navigationTracker.js +228 -0
  91. package/lib/module/recorder/navigationTracker.js.map +1 -0
  92. package/lib/module/recorder/screenRecorder.js +495 -0
  93. package/lib/module/recorder/screenRecorder.js.map +1 -0
  94. package/lib/module/services/api.service.js +149 -0
  95. package/lib/module/services/api.service.js.map +1 -0
  96. package/lib/module/services/network.service.js +178 -0
  97. package/lib/module/services/network.service.js.map +1 -0
  98. package/lib/module/services/screenMaskingService.js +107 -0
  99. package/lib/module/services/screenMaskingService.js.map +1 -0
  100. package/lib/module/services/storage.service.js +179 -0
  101. package/lib/module/services/storage.service.js.map +1 -0
  102. package/lib/module/session-recorder.js +541 -0
  103. package/lib/module/session-recorder.js.map +1 -0
  104. package/lib/module/types/configs.js +4 -0
  105. package/lib/module/types/configs.js.map +1 -0
  106. package/lib/module/types/expo-constants.d.js +2 -0
  107. package/lib/module/types/expo-constants.d.js.map +1 -0
  108. package/lib/module/types/index.js +11 -0
  109. package/lib/module/types/index.js.map +1 -0
  110. package/lib/module/types/session-recorder.js +68 -0
  111. package/lib/module/types/session-recorder.js.map +1 -0
  112. package/lib/module/types/session.js +9 -0
  113. package/lib/module/types/session.js.map +1 -0
  114. package/lib/module/utils/app-metadata.js +28 -0
  115. package/lib/module/utils/app-metadata.js.map +1 -0
  116. package/lib/module/utils/constants.optional.expo.js +6 -0
  117. package/lib/module/utils/constants.optional.expo.js.map +1 -0
  118. package/lib/module/utils/constants.optional.js +8 -0
  119. package/lib/module/utils/constants.optional.js.map +1 -0
  120. package/lib/module/utils/createStore.js +27 -0
  121. package/lib/module/utils/createStore.js.map +1 -0
  122. package/lib/module/utils/index.js +11 -0
  123. package/lib/module/utils/index.js.map +1 -0
  124. package/lib/module/utils/logger.js +185 -0
  125. package/lib/module/utils/logger.js.map +1 -0
  126. package/lib/module/utils/platform.js +340 -0
  127. package/lib/module/utils/platform.js.map +1 -0
  128. package/lib/module/utils/request-utils.js +58 -0
  129. package/lib/module/utils/request-utils.js.map +1 -0
  130. package/lib/module/utils/rrweb-events.js +276 -0
  131. package/lib/module/utils/rrweb-events.js.map +1 -0
  132. package/lib/module/utils/session.js +21 -0
  133. package/lib/module/utils/session.js.map +1 -0
  134. package/lib/module/utils/shallowEqual.js +17 -0
  135. package/lib/module/utils/shallowEqual.js.map +1 -0
  136. package/lib/module/utils/time.js +17 -0
  137. package/lib/module/utils/time.js.map +1 -0
  138. package/lib/module/utils/type-utils.js +69 -0
  139. package/lib/module/utils/type-utils.js.map +1 -0
  140. package/lib/module/version.js +4 -0
  141. package/lib/module/version.js.map +1 -0
  142. package/lib/typescript/package.json +1 -0
  143. package/{dist/native/SessionRecorderNative.d.ts → lib/typescript/src/SessionRecorderNativeSpec.d.ts} +23 -15
  144. package/lib/typescript/src/SessionRecorderNativeSpec.d.ts.map +1 -0
  145. package/lib/typescript/src/components/ScreenRecorderView/ScreenRecorderView.d.ts +6 -0
  146. package/lib/typescript/src/components/ScreenRecorderView/ScreenRecorderView.d.ts.map +1 -0
  147. package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +2 -0
  148. package/lib/typescript/src/components/ScreenRecorderView/index.d.ts.map +1 -0
  149. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ErrorBanner.d.ts +1 -0
  150. package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -0
  151. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/FinalPopover.d.ts +2 -1
  152. package/lib/typescript/src/components/SessionRecorderWidget/FinalPopover.d.ts.map +1 -0
  153. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/FloatingButton.d.ts +1 -0
  154. package/lib/typescript/src/components/SessionRecorderWidget/FloatingButton.d.ts.map +1 -0
  155. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/InitialPopover.d.ts +2 -1
  156. package/lib/typescript/src/components/SessionRecorderWidget/InitialPopover.d.ts.map +1 -0
  157. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ModalContainer.d.ts +1 -0
  158. package/lib/typescript/src/components/SessionRecorderWidget/ModalContainer.d.ts.map +1 -0
  159. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ModalHeader.d.ts +1 -0
  160. package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -0
  161. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/SessionRecorderWidget.d.ts +1 -0
  162. package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -0
  163. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/icons.d.ts +1 -0
  164. package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -0
  165. package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +3 -0
  166. package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts.map +1 -0
  167. package/{dist → lib/typescript/src}/components/SessionRecorderWidget/styles.d.ts +4 -3
  168. package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -0
  169. package/lib/typescript/src/components/index.d.ts +3 -0
  170. package/lib/typescript/src/components/index.d.ts.map +1 -0
  171. package/{dist → lib/typescript/src}/config/constants.d.ts +1 -0
  172. package/lib/typescript/src/config/constants.d.ts.map +1 -0
  173. package/{dist → lib/typescript/src}/config/defaults.d.ts +2 -1
  174. package/lib/typescript/src/config/defaults.d.ts.map +1 -0
  175. package/{dist → lib/typescript/src}/config/index.d.ts +1 -0
  176. package/lib/typescript/src/config/index.d.ts.map +1 -0
  177. package/lib/typescript/src/config/masking.d.ts +3 -0
  178. package/lib/typescript/src/config/masking.d.ts.map +1 -0
  179. package/lib/typescript/src/config/session-recorder.d.ts +3 -0
  180. package/lib/typescript/src/config/session-recorder.d.ts.map +1 -0
  181. package/{dist → lib/typescript/src}/config/validators.d.ts +1 -0
  182. package/lib/typescript/src/config/validators.d.ts.map +1 -0
  183. package/{dist → lib/typescript/src}/config/widget.d.ts +2 -1
  184. package/lib/typescript/src/config/widget.d.ts.map +1 -0
  185. package/{dist → lib/typescript/src}/context/SessionRecorderContext.d.ts +3 -2
  186. package/lib/typescript/src/context/SessionRecorderContext.d.ts.map +1 -0
  187. package/{dist → lib/typescript/src}/context/SessionRecorderStore.d.ts +2 -1
  188. package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -0
  189. package/{dist → lib/typescript/src}/context/useSessionRecorderStore.d.ts +4 -3
  190. package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -0
  191. package/{dist → lib/typescript/src}/context/useStoreSelector.d.ts +2 -1
  192. package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -0
  193. package/{dist → lib/typescript/src}/index.d.ts +2 -0
  194. package/lib/typescript/src/index.d.ts.map +1 -0
  195. package/lib/typescript/src/native/SessionRecorderNative.d.ts +27 -0
  196. package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -0
  197. package/lib/typescript/src/native/index.d.ts +2 -0
  198. package/lib/typescript/src/native/index.d.ts.map +1 -0
  199. package/{dist → lib/typescript/src}/otel/helpers.d.ts +3 -2
  200. package/lib/typescript/src/otel/helpers.d.ts.map +1 -0
  201. package/{dist → lib/typescript/src}/otel/index.d.ts +2 -2
  202. package/lib/typescript/src/otel/index.d.ts.map +1 -0
  203. package/{dist → lib/typescript/src}/otel/instrumentations/index.d.ts +2 -1
  204. package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -0
  205. package/lib/typescript/src/patch/index.d.ts +2 -0
  206. package/lib/typescript/src/patch/index.d.ts.map +1 -0
  207. package/{dist → lib/typescript/src}/patch/xhr.d.ts +1 -0
  208. package/lib/typescript/src/patch/xhr.d.ts.map +1 -0
  209. package/{dist → lib/typescript/src}/recorder/eventExporter.d.ts +2 -1
  210. package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -0
  211. package/{dist → lib/typescript/src}/recorder/gestureRecorder.d.ts +3 -2
  212. package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -0
  213. package/{dist → lib/typescript/src}/recorder/index.d.ts +3 -2
  214. package/lib/typescript/src/recorder/index.d.ts.map +1 -0
  215. package/{dist → lib/typescript/src}/recorder/navigationTracker.d.ts +2 -1
  216. package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -0
  217. package/{dist → lib/typescript/src}/recorder/screenRecorder.d.ts +4 -4
  218. package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -0
  219. package/{dist → lib/typescript/src}/services/api.service.d.ts +2 -1
  220. package/lib/typescript/src/services/api.service.d.ts.map +1 -0
  221. package/{dist → lib/typescript/src}/services/network.service.d.ts +1 -0
  222. package/lib/typescript/src/services/network.service.d.ts.map +1 -0
  223. package/{dist → lib/typescript/src}/services/screenMaskingService.d.ts +2 -1
  224. package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -0
  225. package/{dist → lib/typescript/src}/services/storage.service.d.ts +2 -1
  226. package/lib/typescript/src/services/storage.service.d.ts.map +1 -0
  227. package/{dist → lib/typescript/src}/session-recorder.d.ts +3 -2
  228. package/lib/typescript/src/session-recorder.d.ts.map +1 -0
  229. package/{dist → lib/typescript/src}/types/configs.d.ts +3 -2
  230. package/lib/typescript/src/types/configs.d.ts.map +1 -0
  231. package/{dist → lib/typescript/src}/types/index.d.ts +1 -0
  232. package/lib/typescript/src/types/index.d.ts.map +1 -0
  233. package/{dist → lib/typescript/src}/types/session-recorder.d.ts +7 -6
  234. package/lib/typescript/src/types/session-recorder.d.ts.map +1 -0
  235. package/{dist → lib/typescript/src}/types/session.d.ts +1 -0
  236. package/lib/typescript/src/types/session.d.ts.map +1 -0
  237. package/{dist → lib/typescript/src}/utils/app-metadata.d.ts +1 -0
  238. package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -0
  239. package/{dist → lib/typescript/src}/utils/constants.optional.d.ts +1 -0
  240. package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -0
  241. package/{dist → lib/typescript/src}/utils/constants.optional.expo.d.ts +1 -0
  242. package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -0
  243. package/{dist → lib/typescript/src}/utils/createStore.d.ts +1 -0
  244. package/lib/typescript/src/utils/createStore.d.ts.map +1 -0
  245. package/lib/typescript/src/utils/index.d.ts +8 -0
  246. package/lib/typescript/src/utils/index.d.ts.map +1 -0
  247. package/{dist → lib/typescript/src}/utils/logger.d.ts +2 -1
  248. package/lib/typescript/src/utils/logger.d.ts.map +1 -0
  249. package/{dist → lib/typescript/src}/utils/platform.d.ts +2 -1
  250. package/lib/typescript/src/utils/platform.d.ts.map +1 -0
  251. package/{dist → lib/typescript/src}/utils/request-utils.d.ts +1 -0
  252. package/lib/typescript/src/utils/request-utils.d.ts.map +1 -0
  253. package/{dist → lib/typescript/src}/utils/rrweb-events.d.ts +2 -1
  254. package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -0
  255. package/{dist → lib/typescript/src}/utils/session.d.ts +1 -0
  256. package/lib/typescript/src/utils/session.d.ts.map +1 -0
  257. package/{dist → lib/typescript/src}/utils/shallowEqual.d.ts +1 -0
  258. package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -0
  259. package/{dist → lib/typescript/src}/utils/time.d.ts +1 -0
  260. package/lib/typescript/src/utils/time.d.ts.map +1 -0
  261. package/{dist → lib/typescript/src}/utils/type-utils.d.ts +1 -0
  262. package/lib/typescript/src/utils/type-utils.d.ts.map +1 -0
  263. package/lib/typescript/src/version.d.ts +2 -0
  264. package/lib/typescript/src/version.d.ts.map +1 -0
  265. package/package.json +157 -39
  266. package/react-native.config.js +8 -6
  267. package/src/SessionRecorderNativeSpec.ts +52 -0
  268. package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +20 -0
  269. package/src/components/ScreenRecorderView/index.ts +1 -0
  270. package/src/components/SessionRecorderWidget/ErrorBanner.tsx +58 -0
  271. package/src/components/SessionRecorderWidget/FinalPopover.tsx +96 -0
  272. package/src/components/SessionRecorderWidget/FloatingButton.tsx +176 -0
  273. package/src/components/SessionRecorderWidget/InitialPopover.tsx +167 -0
  274. package/src/components/SessionRecorderWidget/ModalContainer.tsx +189 -0
  275. package/src/components/SessionRecorderWidget/ModalHeader.tsx +26 -0
  276. package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +150 -0
  277. package/src/components/SessionRecorderWidget/icons.tsx +80 -0
  278. package/src/components/SessionRecorderWidget/index.ts +3 -0
  279. package/src/components/SessionRecorderWidget/styles.ts +168 -0
  280. package/src/config/constants.ts +67 -0
  281. package/src/config/defaults.ts +105 -0
  282. package/src/config/index.ts +6 -0
  283. package/src/config/masking.ts +60 -0
  284. package/src/config/session-recorder.ts +87 -0
  285. package/src/config/validators.ts +54 -0
  286. package/src/config/widget.ts +47 -0
  287. package/src/context/SessionRecorderContext.tsx +138 -0
  288. package/src/context/SessionRecorderStore.ts +22 -0
  289. package/src/context/useSessionRecorderStore.ts +34 -0
  290. package/src/context/useStoreSelector.ts +36 -0
  291. package/src/index.ts +13 -0
  292. package/src/native/SessionRecorderNative.ts +120 -0
  293. package/src/native/index.ts +5 -0
  294. package/src/otel/helpers.ts +290 -0
  295. package/src/otel/index.ts +132 -0
  296. package/src/otel/instrumentations/index.ts +118 -0
  297. package/src/patch/xhr.ts +148 -0
  298. package/src/recorder/eventExporter.ts +150 -0
  299. package/src/recorder/gestureRecorder.ts +828 -0
  300. package/src/recorder/index.ts +203 -0
  301. package/src/recorder/navigationTracker.ts +268 -0
  302. package/src/recorder/screenRecorder.ts +600 -0
  303. package/src/services/api.service.ts +216 -0
  304. package/src/services/network.service.ts +191 -0
  305. package/src/services/screenMaskingService.ts +153 -0
  306. package/src/services/storage.service.ts +248 -0
  307. package/src/session-recorder.ts +647 -0
  308. package/src/types/configs.ts +118 -0
  309. package/src/types/expo-constants.d.ts +7 -0
  310. package/src/types/index.ts +27 -0
  311. package/src/types/session-recorder.ts +381 -0
  312. package/src/types/session.ts +65 -0
  313. package/src/utils/app-metadata.ts +31 -0
  314. package/src/utils/constants.optional.expo.ts +5 -0
  315. package/src/utils/constants.optional.ts +18 -0
  316. package/src/utils/createStore.ts +32 -0
  317. package/{dist/utils/index.d.ts → src/utils/index.ts} +1 -0
  318. package/src/utils/logger.ts +245 -0
  319. package/src/utils/platform.ts +401 -0
  320. package/src/utils/request-utils.ts +61 -0
  321. package/src/utils/rrweb-events.ts +329 -0
  322. package/src/utils/session.ts +22 -0
  323. package/src/utils/shallowEqual.ts +20 -0
  324. package/src/utils/time.ts +20 -0
  325. package/src/utils/type-utils.ts +75 -0
  326. package/src/version.ts +1 -0
  327. package/copy-react-native-dist.sh +0 -56
  328. package/dist/components/ScreenRecorderView/ScreenRecorderView.d.ts +0 -5
  329. package/dist/components/ScreenRecorderView/ScreenRecorderView.js +0 -1
  330. package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +0 -1
  331. package/dist/components/ScreenRecorderView/index.d.ts +0 -1
  332. package/dist/components/ScreenRecorderView/index.js +0 -1
  333. package/dist/components/ScreenRecorderView/index.js.map +0 -1
  334. package/dist/components/SessionRecorderWidget/ErrorBanner.js +0 -1
  335. package/dist/components/SessionRecorderWidget/ErrorBanner.js.map +0 -1
  336. package/dist/components/SessionRecorderWidget/FinalPopover.js +0 -1
  337. package/dist/components/SessionRecorderWidget/FinalPopover.js.map +0 -1
  338. package/dist/components/SessionRecorderWidget/FloatingButton.js +0 -1
  339. package/dist/components/SessionRecorderWidget/FloatingButton.js.map +0 -1
  340. package/dist/components/SessionRecorderWidget/InitialPopover.js +0 -1
  341. package/dist/components/SessionRecorderWidget/InitialPopover.js.map +0 -1
  342. package/dist/components/SessionRecorderWidget/ModalContainer.js +0 -1
  343. package/dist/components/SessionRecorderWidget/ModalContainer.js.map +0 -1
  344. package/dist/components/SessionRecorderWidget/ModalHeader.js +0 -1
  345. package/dist/components/SessionRecorderWidget/ModalHeader.js.map +0 -1
  346. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js +0 -1
  347. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js.map +0 -1
  348. package/dist/components/SessionRecorderWidget/icons.js +0 -1
  349. package/dist/components/SessionRecorderWidget/icons.js.map +0 -1
  350. package/dist/components/SessionRecorderWidget/index.d.ts +0 -2
  351. package/dist/components/SessionRecorderWidget/index.js +0 -1
  352. package/dist/components/SessionRecorderWidget/index.js.map +0 -1
  353. package/dist/components/SessionRecorderWidget/styles.js +0 -1
  354. package/dist/components/SessionRecorderWidget/styles.js.map +0 -1
  355. package/dist/components/index.js +0 -1
  356. package/dist/components/index.js.map +0 -1
  357. package/dist/config/constants.js +0 -1
  358. package/dist/config/constants.js.map +0 -1
  359. package/dist/config/defaults.js +0 -1
  360. package/dist/config/defaults.js.map +0 -1
  361. package/dist/config/index.js +0 -1
  362. package/dist/config/index.js.map +0 -1
  363. package/dist/config/masking.d.ts +0 -2
  364. package/dist/config/masking.js +0 -1
  365. package/dist/config/masking.js.map +0 -1
  366. package/dist/config/session-recorder.d.ts +0 -2
  367. package/dist/config/session-recorder.js +0 -1
  368. package/dist/config/session-recorder.js.map +0 -1
  369. package/dist/config/validators.js +0 -1
  370. package/dist/config/validators.js.map +0 -1
  371. package/dist/config/widget.js +0 -1
  372. package/dist/config/widget.js.map +0 -1
  373. package/dist/context/SessionRecorderContext.js +0 -1
  374. package/dist/context/SessionRecorderContext.js.map +0 -1
  375. package/dist/context/SessionRecorderStore.js +0 -1
  376. package/dist/context/SessionRecorderStore.js.map +0 -1
  377. package/dist/context/useSessionRecorderStore.js +0 -1
  378. package/dist/context/useSessionRecorderStore.js.map +0 -1
  379. package/dist/context/useStoreSelector.js +0 -1
  380. package/dist/context/useStoreSelector.js.map +0 -1
  381. package/dist/index.js +0 -1
  382. package/dist/index.js.map +0 -1
  383. package/dist/native/GestureRecorderNative.d.ts +0 -57
  384. package/dist/native/GestureRecorderNative.js +0 -1
  385. package/dist/native/GestureRecorderNative.js.map +0 -1
  386. package/dist/native/SessionRecorderNative.js +0 -1
  387. package/dist/native/SessionRecorderNative.js.map +0 -1
  388. package/dist/native/index.d.ts +0 -2
  389. package/dist/native/index.js +0 -1
  390. package/dist/native/index.js.map +0 -1
  391. package/dist/otel/helpers.js +0 -1
  392. package/dist/otel/helpers.js.map +0 -1
  393. package/dist/otel/index.js +0 -1
  394. package/dist/otel/index.js.map +0 -1
  395. package/dist/otel/instrumentations/index.js +0 -1
  396. package/dist/otel/instrumentations/index.js.map +0 -1
  397. package/dist/patch/index.js +0 -1
  398. package/dist/patch/index.js.map +0 -1
  399. package/dist/patch/xhr.js +0 -1
  400. package/dist/patch/xhr.js.map +0 -1
  401. package/dist/recorder/eventExporter.js +0 -1
  402. package/dist/recorder/eventExporter.js.map +0 -1
  403. package/dist/recorder/gestureRecorder.js +0 -1
  404. package/dist/recorder/gestureRecorder.js.map +0 -1
  405. package/dist/recorder/index.js +0 -1
  406. package/dist/recorder/index.js.map +0 -1
  407. package/dist/recorder/navigationTracker.js +0 -1
  408. package/dist/recorder/navigationTracker.js.map +0 -1
  409. package/dist/recorder/screenRecorder.js +0 -1
  410. package/dist/recorder/screenRecorder.js.map +0 -1
  411. package/dist/services/api.service.js +0 -1
  412. package/dist/services/api.service.js.map +0 -1
  413. package/dist/services/network.service.js +0 -1
  414. package/dist/services/network.service.js.map +0 -1
  415. package/dist/services/screenMaskingService.js +0 -1
  416. package/dist/services/screenMaskingService.js.map +0 -1
  417. package/dist/services/storage.service.js +0 -1
  418. package/dist/services/storage.service.js.map +0 -1
  419. package/dist/session-recorder.js +0 -1
  420. package/dist/session-recorder.js.map +0 -1
  421. package/dist/types/configs.js +0 -1
  422. package/dist/types/configs.js.map +0 -1
  423. package/dist/types/index.js +0 -1
  424. package/dist/types/index.js.map +0 -1
  425. package/dist/types/session-recorder.js +0 -1
  426. package/dist/types/session-recorder.js.map +0 -1
  427. package/dist/types/session.js +0 -1
  428. package/dist/types/session.js.map +0 -1
  429. package/dist/utils/app-metadata.js +0 -1
  430. package/dist/utils/app-metadata.js.map +0 -1
  431. package/dist/utils/constants.optional.expo.js +0 -1
  432. package/dist/utils/constants.optional.expo.js.map +0 -1
  433. package/dist/utils/constants.optional.js +0 -1
  434. package/dist/utils/constants.optional.js.map +0 -1
  435. package/dist/utils/createStore.js +0 -1
  436. package/dist/utils/createStore.js.map +0 -1
  437. package/dist/utils/index.js +0 -1
  438. package/dist/utils/index.js.map +0 -1
  439. package/dist/utils/logger.js +0 -1
  440. package/dist/utils/logger.js.map +0 -1
  441. package/dist/utils/platform.js +0 -1
  442. package/dist/utils/platform.js.map +0 -1
  443. package/dist/utils/request-utils.js +0 -1
  444. package/dist/utils/request-utils.js.map +0 -1
  445. package/dist/utils/rrweb-events.js +0 -1
  446. package/dist/utils/rrweb-events.js.map +0 -1
  447. package/dist/utils/session.js +0 -1
  448. package/dist/utils/session.js.map +0 -1
  449. package/dist/utils/shallowEqual.js +0 -1
  450. package/dist/utils/shallowEqual.js.map +0 -1
  451. package/dist/utils/time.js +0 -1
  452. package/dist/utils/time.js.map +0 -1
  453. package/dist/utils/type-utils.js +0 -1
  454. package/dist/utils/type-utils.js.map +0 -1
  455. package/dist/version.d.ts +0 -1
  456. package/dist/version.js +0 -1
  457. package/dist/version.js.map +0 -1
  458. package/docs/AUTO_METADATA_DETECTION.md +0 -108
  459. package/ios/GestureRecorderNative.swift +0 -316
  460. package/ios/SessionRecorderNative.m +0 -17
  461. package/ios/SessionRecorderNative.podspec +0 -26
  462. /package/{dist/components/index.d.ts → src/components/index.ts} +0 -0
  463. /package/{dist/patch/index.d.ts → src/patch/index.ts} +0 -0
@@ -0,0 +1,600 @@
1
+ import {
2
+ type ScreenEvent,
3
+ type RecorderConfig,
4
+ type EventRecorder,
5
+ } from '../types';
6
+ import { type eventWithTime } from '@rrweb/types';
7
+ import { trace, SpanStatusCode } from '@opentelemetry/api';
8
+ import { Dimensions, Platform } from 'react-native';
9
+ import {
10
+ createRecordingMetaEvent,
11
+ createFullSnapshotEvent,
12
+ createIncrementalSnapshotWithImageUpdate as createIncrementalSnapshotUtil,
13
+ generateScreenHash,
14
+ logger,
15
+ } from '../utils';
16
+ import {
17
+ screenMaskingService,
18
+ type ScreenMaskingConfig,
19
+ } from '../services/screenMaskingService';
20
+ import { captureRef } from 'react-native-view-shot';
21
+ const isWeb = Platform.OS === 'web';
22
+
23
+ export class ScreenRecorder implements EventRecorder {
24
+ private config?: RecorderConfig;
25
+ private isRecording = false;
26
+ private events: ScreenEvent[] = [];
27
+ private captureInterval?: any;
28
+ private captureCount: number = 0;
29
+ private maxCaptures: number = 100; // Limit captures to prevent memory issues
30
+ private captureQuality: number = 0.2;
31
+ private captureScale: number = 0.66;
32
+ private captureFormat: 'png' | 'jpg' = 'jpg';
33
+ private screenDimensions: { width: number; height: number } | null = null;
34
+ private eventRecorder?: EventRecorder;
35
+ private nodeIdCounter: number = 1;
36
+ private viewShotRef: any = null;
37
+ private lastScreenCapture: string | null = null;
38
+ private lastScreenHash: string | null = null;
39
+ private enableChangeDetection: boolean = true;
40
+ private hashSampleSize: number = 100;
41
+ private currentImageNodeId: number | null = null;
42
+ private maskingConfig?: ScreenMaskingConfig;
43
+
44
+ init(config: RecorderConfig, eventRecorder?: EventRecorder): void {
45
+ this.config = config;
46
+ this.eventRecorder = eventRecorder;
47
+ this._getScreenDimensions();
48
+
49
+ // Initialize masking configuration
50
+ this.maskingConfig = {
51
+ enabled: true,
52
+ ...this.config.masking,
53
+ };
54
+
55
+ // Update the masking service configuration
56
+ screenMaskingService.updateConfig(this.maskingConfig);
57
+ }
58
+
59
+ start(): void {
60
+ this.isRecording = true;
61
+ this.events = [];
62
+ this.captureCount = 0;
63
+ this.lastScreenCapture = null;
64
+ this.lastScreenHash = null;
65
+ this.currentImageNodeId = null; // Reset image node ID for new session
66
+ logger.info('ScreenRecorder', 'Screen recording started');
67
+ // Emit screen recording started meta event
68
+
69
+ this.recordEvent(createRecordingMetaEvent());
70
+
71
+ this._startPeriodicCapture();
72
+
73
+ // Capture initial screen immediately
74
+ this._captureScreen();
75
+
76
+ // Screen recording started
77
+ }
78
+
79
+ stop(): void {
80
+ this.isRecording = false;
81
+ this._stopPeriodicCapture();
82
+ // Screen recording stopped
83
+ }
84
+
85
+ pause(): void {
86
+ this.isRecording = false;
87
+ this._stopPeriodicCapture();
88
+ }
89
+
90
+ resume(): void {
91
+ this.isRecording = true;
92
+ // this._startPeriodicCapture()
93
+ }
94
+
95
+ private _getScreenDimensions(): void {
96
+ try {
97
+ this.screenDimensions = Dimensions.get('window');
98
+ } catch (error) {
99
+ // Failed to get screen dimensions - silently continue
100
+ this.screenDimensions = { width: 375, height: 667 }; // Default fallback
101
+ }
102
+ }
103
+
104
+ private _startPeriodicCapture(): void {
105
+ if (this.captureInterval) {
106
+ clearInterval(this.captureInterval);
107
+ }
108
+
109
+ // Capture screen every 5 seconds (reduced frequency)
110
+ this.captureInterval = setInterval(() => {
111
+ this._captureScreen();
112
+ }, 5000);
113
+ }
114
+
115
+ private _stopPeriodicCapture(): void {
116
+ if (this.captureInterval) {
117
+ clearInterval(this.captureInterval);
118
+ this.captureInterval = undefined;
119
+ }
120
+ }
121
+
122
+ private async _captureScreen(timestamp?: number): Promise<void> {
123
+ if (!this.isRecording || this.captureCount >= this.maxCaptures) return;
124
+
125
+ try {
126
+ const base64Image = await this._captureScreenBase64();
127
+
128
+ if (base64Image) {
129
+ // Check if screen has changed by comparing with previous capture
130
+ const hasChanged = this.enableChangeDetection
131
+ ? this._hasScreenChanged(base64Image)
132
+ : true;
133
+
134
+ if (hasChanged) {
135
+ // Use incremental snapshot if we have an existing image node, otherwise create full snapshot
136
+ if (this.currentImageNodeId !== null && this.lastScreenCapture) {
137
+ const success = this.updateScreenWithIncrementalSnapshot(
138
+ base64Image,
139
+ timestamp
140
+ );
141
+ if (!success) {
142
+ // Fallback to full snapshot if incremental update fails
143
+ this._createAndEmitFullSnapshotEvent(base64Image, timestamp);
144
+ }
145
+ } else {
146
+ // First capture or no existing image node - create full snapshot
147
+ this._createAndEmitFullSnapshotEvent(base64Image, timestamp);
148
+ }
149
+
150
+ this.lastScreenCapture = base64Image;
151
+ this.lastScreenHash = this._generateScreenHash(base64Image);
152
+ this.captureCount++;
153
+ }
154
+ }
155
+ } catch (error) {
156
+ this._recordScreenCaptureError(error as Error);
157
+ }
158
+ }
159
+
160
+ private async _captureScreenBase64(): Promise<string | null> {
161
+ try {
162
+ // Check if we're on web platform
163
+ if (isWeb) {
164
+ logger.warn(
165
+ 'ScreenRecorder',
166
+ 'Screen capture not available on web platform'
167
+ );
168
+ return null;
169
+ }
170
+
171
+ // Try native masking first if available
172
+ if (screenMaskingService.isScreenMaskingAvailable()) {
173
+ logger.info(
174
+ 'ScreenRecorder',
175
+ 'Using native masking for screen capture'
176
+ );
177
+ const maskedImage = await screenMaskingService.captureMaskedScreen({
178
+ quality: this.captureQuality,
179
+ scale: this.captureScale,
180
+ });
181
+
182
+ if (maskedImage) {
183
+ return maskedImage;
184
+ }
185
+
186
+ logger.warn(
187
+ 'ScreenRecorder',
188
+ 'Native masking failed, falling back to view-shot'
189
+ );
190
+ }
191
+
192
+ // Fallback to react-native-view-shot
193
+ if (!this.viewShotRef) {
194
+ logger.warn(
195
+ 'ScreenRecorder',
196
+ 'ViewShot ref not available for screen capture'
197
+ );
198
+ return null;
199
+ }
200
+
201
+ // Check if captureRef is available
202
+ if (!captureRef) {
203
+ logger.warn('ScreenRecorder', 'react-native-view-shot not available');
204
+ return null;
205
+ }
206
+
207
+ // Capture the screen using react-native-view-shot
208
+ const result = await captureRef(this.viewShotRef, {
209
+ format: this.captureFormat,
210
+ quality: this.captureQuality,
211
+ result: 'base64',
212
+ });
213
+
214
+ return result;
215
+ } catch (error) {
216
+ logger.error(
217
+ 'ScreenRecorder',
218
+ 'Failed to capture screen. Make sure react-native-view-shot is properly installed and linked:',
219
+ error
220
+ );
221
+ return null;
222
+ }
223
+ }
224
+
225
+ private _createAndEmitFullSnapshotEvent(
226
+ base64Image: string,
227
+ timestamp?: number
228
+ ): void {
229
+ if (!this.screenDimensions) return;
230
+
231
+ // Use the new createFullSnapshot method
232
+ const fullSnapshotEvent = this.createFullSnapshot(base64Image, timestamp);
233
+ this.recordEvent(fullSnapshotEvent);
234
+ }
235
+
236
+ /**
237
+ * Create a full snapshot event with the given base64 image
238
+ * @param base64Image - Base64 encoded image data
239
+ * @param timestamp - Optional timestamp to use for the event
240
+ * @returns Full snapshot event
241
+ */
242
+ createFullSnapshot(base64Image: string, timestamp?: number): eventWithTime {
243
+ if (!this.screenDimensions) {
244
+ throw new Error('Screen dimensions not available');
245
+ }
246
+
247
+ const { width, height } = this.screenDimensions;
248
+ this.nodeIdCounter = 1;
249
+
250
+ // Use utility function to create full snapshot event
251
+ const fullSnapshotEvent = createFullSnapshotEvent(
252
+ base64Image,
253
+ width,
254
+ height,
255
+ this.captureFormat,
256
+ { current: this.nodeIdCounter },
257
+ timestamp
258
+ );
259
+
260
+ // Store the image node ID for future incremental updates
261
+ // The image node ID is the first node created (after the document)
262
+ this.currentImageNodeId = 0; // First element node is the image
263
+
264
+ return fullSnapshotEvent;
265
+ }
266
+
267
+ /**
268
+ * Create an incremental snapshot event with mutation data to update image src
269
+ * @param base64Image - New base64 encoded image data
270
+ * @param captureFormat - Image format (png, jpg, etc.)
271
+ * @param timestamp - Optional timestamp to use for the event
272
+ * @returns Incremental snapshot event with mutation data
273
+ */
274
+ createIncrementalSnapshotWithImageUpdate(
275
+ base64Image: string,
276
+ captureFormat?: string,
277
+ timestamp?: number
278
+ ): eventWithTime {
279
+ return createIncrementalSnapshotUtil(
280
+ base64Image,
281
+ captureFormat || this.captureFormat,
282
+ timestamp
283
+ );
284
+ }
285
+
286
+ /**
287
+ * Update the screen with a new image using incremental snapshot
288
+ * @param base64Image - New base64 encoded image data
289
+ * @param timestamp - Optional timestamp to use for the event
290
+ * @returns true if update was successful, false otherwise
291
+ */
292
+ updateScreenWithIncrementalSnapshot(
293
+ base64Image: string,
294
+ timestamp?: number
295
+ ): boolean {
296
+ if (this.currentImageNodeId === null) {
297
+ logger.warn(
298
+ 'ScreenRecorder',
299
+ 'No image node ID available for incremental update'
300
+ );
301
+ return false;
302
+ }
303
+
304
+ const incrementalEvent = this.createIncrementalSnapshotWithImageUpdate(
305
+ base64Image,
306
+ 'jpg',
307
+ timestamp
308
+ );
309
+ this.recordEvent(incrementalEvent);
310
+ return true;
311
+ }
312
+
313
+ /**
314
+ * Force a full snapshot (useful when screen dimensions change or for debugging)
315
+ * @param base64Image - Base64 encoded image data
316
+ */
317
+ forceFullSnapshot(base64Image: string): void {
318
+ this._createAndEmitFullSnapshotEvent(base64Image);
319
+ this.lastScreenCapture = base64Image;
320
+ this.lastScreenHash = this._generateScreenHash(base64Image);
321
+ this.captureCount++;
322
+ }
323
+
324
+ /**
325
+ * Check if the screen has changed by comparing with the previous capture
326
+ * @param currentBase64 - Current screen capture as base64
327
+ * @returns true if screen has changed, false otherwise
328
+ */
329
+ private _hasScreenChanged(currentBase64: string): boolean {
330
+ // If this is the first capture, consider it changed
331
+ if (!this.lastScreenCapture) {
332
+ return true;
333
+ }
334
+
335
+ // Generate hash for current capture
336
+ const currentHash = this._generateScreenHash(currentBase64);
337
+
338
+ // Compare with previous hash
339
+ return currentHash !== this.lastScreenHash;
340
+ }
341
+
342
+ /**
343
+ * Generate a simple hash for screen comparison
344
+ * This is a lightweight hash that focuses on the beginning and end of the base64 string
345
+ * to detect changes without doing a full comparison
346
+ * @param base64Image - Base64 encoded image
347
+ * @returns Hash string for comparison
348
+ */
349
+ private _generateScreenHash(base64Image: string): string {
350
+ return generateScreenHash(base64Image, this.hashSampleSize);
351
+ }
352
+
353
+ private _sendEvent(_event: ScreenEvent): void {
354
+ // Screen event recorded
355
+ // Send event to backend or store locally
356
+ }
357
+
358
+ private _recordOpenTelemetrySpan(event: ScreenEvent): void {
359
+ try {
360
+ const span = trace.getTracer('screen').startSpan(`Screen.${event.type}`, {
361
+ attributes: {
362
+ 'screen.type': event.type,
363
+ 'screen.timestamp': event.timestamp,
364
+ 'screen.platform': 'react-native',
365
+ },
366
+ });
367
+
368
+ if (event.metadata) {
369
+ Object.entries(event.metadata).forEach(([key, value]) => {
370
+ span.setAttribute(`screen.metadata.${key}`, String(value));
371
+ });
372
+ }
373
+
374
+ span.setStatus({ code: SpanStatusCode.OK });
375
+ span.end();
376
+ } catch (error) {
377
+ // Failed to record OpenTelemetry span for screen - silently continue
378
+ }
379
+ }
380
+
381
+ private _recordScreenCaptureError(error: Error): void {
382
+ try {
383
+ const span = trace.getTracer('screen').startSpan('Screen.capture.error', {
384
+ attributes: {
385
+ 'screen.error': true,
386
+ 'screen.error.type': error.name,
387
+ 'screen.error.message': error.message,
388
+ 'screen.timestamp': Date.now(),
389
+ },
390
+ });
391
+
392
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
393
+ span.recordException(error);
394
+ span.end();
395
+ } catch (spanError) {
396
+ // Failed to record error span - silently continue
397
+ }
398
+ }
399
+
400
+ async captureSpecificElement(
401
+ elementRef: any,
402
+ _options?: {
403
+ format?: 'png' | 'jpg' | 'webp';
404
+ quality?: number;
405
+ }
406
+ ): Promise<string | null> {
407
+ try {
408
+ if (isWeb || !captureRef) {
409
+ logger.warn(
410
+ 'ScreenRecorder',
411
+ 'Element capture not available on web platform'
412
+ );
413
+ return null;
414
+ }
415
+ return await captureRef(elementRef);
416
+ } catch (error) {
417
+ // Failed to capture specific element - silently continue
418
+ return null;
419
+ }
420
+ }
421
+
422
+ // Configuration methods
423
+ setCaptureInterval(intervalMs: number): void {
424
+ if (this.captureInterval) {
425
+ clearInterval(this.captureInterval);
426
+ }
427
+
428
+ if (this.isRecording) {
429
+ this.captureInterval = setInterval(() => {
430
+ this._captureScreen();
431
+ }, intervalMs);
432
+ }
433
+ }
434
+
435
+ setCaptureQuality(quality: number): void {
436
+ this.captureQuality = Math.max(0.1, Math.min(1.0, quality));
437
+ }
438
+
439
+ setCaptureFormat(format: 'png' | 'jpg'): void {
440
+ this.captureFormat = format;
441
+ }
442
+
443
+ setMaxCaptures(max: number): void {
444
+ this.maxCaptures = Math.max(1, max);
445
+ }
446
+
447
+ /**
448
+ * Enable or disable change detection
449
+ * @param enabled - Whether to enable change detection
450
+ */
451
+ setChangeDetection(enabled: boolean): void {
452
+ this.enableChangeDetection = enabled;
453
+ }
454
+
455
+ /**
456
+ * Set the hash sample size for change detection
457
+ * @param size - Number of characters to sample from each part of the image
458
+ */
459
+ setHashSampleSize(size: number): void {
460
+ this.hashSampleSize = Math.max(10, Math.min(1000, size));
461
+ }
462
+
463
+ // Performance monitoring
464
+ recordScreenPerformance(screenName: string, loadTime: number): void {
465
+ const event: ScreenEvent = {
466
+ screenName,
467
+ type: 'screenCapture',
468
+ timestamp: Date.now(),
469
+ metadata: {
470
+ screenName,
471
+ loadTime,
472
+ performance: 'monitoring',
473
+ captureCount: this.captureCount,
474
+ },
475
+ };
476
+
477
+ this.events.push(event);
478
+ this._sendEvent(event);
479
+ this._recordOpenTelemetrySpan(event);
480
+ this.events.push(event);
481
+ this._sendEvent(event);
482
+ this._recordOpenTelemetrySpan(event);
483
+ }
484
+
485
+ // Error tracking
486
+ recordScreenError(error: Error, screenName?: string): void {
487
+ const event: ScreenEvent = {
488
+ screenName: screenName || 'unknown',
489
+ type: 'screenCapture',
490
+ timestamp: Date.now(),
491
+ metadata: {
492
+ error: true,
493
+ errorType: error.name,
494
+ errorMessage: error.message,
495
+ screenName,
496
+ captureCount: this.captureCount,
497
+ },
498
+ };
499
+
500
+ this.events.push(event);
501
+ this._sendEvent(event);
502
+ this._recordOpenTelemetrySpan(event);
503
+ this.events.push(event);
504
+ this._sendEvent(event);
505
+ this._recordScreenCaptureError(error);
506
+ }
507
+
508
+ // Get recorded events
509
+ getEvents(): ScreenEvent[] {
510
+ return [...this.events];
511
+ }
512
+
513
+ // Clear events
514
+ clearEvents(): void {
515
+ this.events = [];
516
+ this.captureCount = 0;
517
+ }
518
+
519
+ // Get screen capture statistics
520
+ getScreenStats(): Record<string, any> {
521
+ const stats = {
522
+ totalCaptures: this.captureCount,
523
+ totalEvents: this.events.length,
524
+ averageCaptureTime: 0,
525
+ successRate: 0,
526
+ };
527
+
528
+ if (this.events.length > 0) {
529
+ const captureTimes = this.events
530
+ .map((event) => event.metadata?.captureTime || 0)
531
+ .filter((time) => time > 0);
532
+
533
+ if (captureTimes.length > 0) {
534
+ stats.averageCaptureTime =
535
+ captureTimes.reduce((a, b) => a + b, 0) / captureTimes.length;
536
+ }
537
+
538
+ const successfulCaptures = this.events.filter(
539
+ (event) => event.dataUrl
540
+ ).length;
541
+ stats.successRate = (successfulCaptures / this.events.length) * 100;
542
+ }
543
+
544
+ return stats;
545
+ }
546
+
547
+ // Get recording status
548
+ isRecordingEnabled(): boolean {
549
+ return this.isRecording;
550
+ }
551
+
552
+ // Get current configuration
553
+ getConfiguration(): Record<string, any> {
554
+ return {
555
+ captureInterval: this.captureInterval ? 2000 : 0, // Default 5 seconds
556
+ captureQuality: this.captureQuality,
557
+ captureFormat: this.captureFormat,
558
+ maxCaptures: this.maxCaptures,
559
+ screenDimensions: this.screenDimensions,
560
+ };
561
+ }
562
+
563
+ // Shutdown
564
+ shutdown(): void {
565
+ this.stop();
566
+ this.clearEvents();
567
+ // Screen recorder shutdown
568
+ }
569
+
570
+ /**
571
+ * Set the viewshot ref for screen capture
572
+ * @param ref - React Native View ref for screen capture
573
+ */
574
+ setViewShotRef(ref: any): void {
575
+ this.viewShotRef = ref;
576
+ }
577
+
578
+ /**
579
+ * Force capture screen (useful after touch interactions)
580
+ * This bypasses the change detection and always captures
581
+ * @param timestamp - Optional timestamp to use for the capture event
582
+ */
583
+ forceCapture(timestamp?: number): void {
584
+ if (!this.isRecording) {
585
+ return;
586
+ }
587
+
588
+ this._captureScreen(timestamp);
589
+ }
590
+
591
+ /**
592
+ * Record an rrweb event
593
+ * @param event - The rrweb event to record
594
+ */
595
+ recordEvent(event: any): void {
596
+ if (this.eventRecorder) {
597
+ this.eventRecorder.recordEvent(event);
598
+ }
599
+ }
600
+ }