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

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