@scalebun/react-native 1.0.2 → 1.0.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 (1694) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +65 -65
  3. package/android/build.gradle +86 -86
  4. package/android/consumer-rules.pro +28 -28
  5. package/android/src/main/AndroidManifest.xml +14 -14
  6. package/android/src/main/java/com/scalebun/core/crash/CrashStorage.kt +155 -41
  7. package/android/src/main/java/com/scalebun/core/crash/NativeCrashHandler.kt +93 -79
  8. package/android/src/main/java/com/scalebun/core/performance/ANRWatchdog.kt +100 -100
  9. package/android/src/main/java/com/scalebun/core/performance/AppStartCollector.kt +132 -132
  10. package/android/src/main/java/com/scalebun/core/performance/FrameMetricsCollector.kt +230 -230
  11. package/android/src/main/java/com/scalebun/core/performance/PerformanceCore.kt +165 -165
  12. package/android/src/main/java/com/scalebun/profiler/ProfilerModule.kt +398 -398
  13. package/android/src/main/java/com/scalebun/profiler/ProfilerPackage.kt +24 -24
  14. package/android/src/main/java/com/scalebun/profiler/collectors/CpuCollector.kt +161 -161
  15. package/android/src/main/java/com/scalebun/profiler/collectors/IncidentDetector.kt +223 -223
  16. package/android/src/main/java/com/scalebun/profiler/collectors/MemoryCollector.kt +157 -157
  17. package/android/src/main/java/com/scalebun/profiler/collectors/RenderCollector.kt +194 -194
  18. package/android/src/main/java/com/scalebun/profiler/collectors/SamplerScheduler.kt +218 -218
  19. package/android/src/main/java/com/scalebun/profiler/collectors/ThreadCollector.kt +142 -142
  20. package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkModule.kt +982 -966
  21. package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkPackage.kt +24 -24
  22. package/android/src/main/java/com/scalebun/replaysdk/capture/CaptureReason.kt +47 -47
  23. package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureManager.kt +508 -508
  24. package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureScheduler.kt +187 -187
  25. package/android/src/main/java/com/scalebun/replaysdk/capture/UiStabilityDetector.kt +214 -214
  26. package/android/src/main/java/com/scalebun/replaysdk/core/ReplayConfig.kt +144 -144
  27. package/android/src/main/java/com/scalebun/replaysdk/core/ReplayLogger.kt +31 -31
  28. package/android/src/main/java/com/scalebun/replaysdk/core/SessionIdGenerator.kt +15 -15
  29. package/android/src/main/java/com/scalebun/replaysdk/models/ReplayModels.kt +88 -88
  30. package/android/src/main/java/com/scalebun/replaysdk/outbox/NativeOutbox.kt +541 -541
  31. package/android/src/main/java/com/scalebun/replaysdk/outbox/OutboxUploader.kt +407 -407
  32. package/android/src/main/java/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.kt +126 -126
  33. package/android/src/main/java/com/scalebun/replaysdk/session/SessionManager.kt +281 -281
  34. package/android/src/main/java/com/scalebun/replaysdk/storage/ReplayStorage.kt +136 -136
  35. package/android/src/main/java/com/scalebun/replaysdk/timeline/TimelineCollector.kt +28 -28
  36. package/android/src/main/java/com/scalebun/replaysdk/tracking/InteractionTracker.kt +419 -419
  37. package/android/src/main/java/com/scalebun/replaysdk/tracking/ScreenTracker.kt +20 -20
  38. package/android/src/main/java/com/scalebun/replaysdk/transport/ReplayTransport.kt +99 -99
  39. package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceRecorder.kt +121 -121
  40. package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceTranscriber.kt +170 -104
  41. package/android/src/main/java/com/scalebun/rn/ScaleBunPackage.kt +113 -113
  42. package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashModule.kt +164 -100
  43. package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashPackage.kt +22 -22
  44. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngageModule.kt +579 -579
  45. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngagePackage.kt +22 -22
  46. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunNotificationPresenter.kt +110 -110
  47. package/android/src/main/java/com/scalebun/rn/ota/BundleDownloader.kt +170 -0
  48. package/android/src/main/java/com/scalebun/rn/ota/ScaleBunOtaModule.kt +284 -136
  49. package/android/src/main/java/com/scalebun/rn/ota/SlotManager.kt +311 -285
  50. package/android/src/main/java/com/scalebun/rn/performance/PerformanceModule.kt +206 -206
  51. package/android/src/main/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.kt +77 -77
  52. package/android/src/main/java/com/scalebun/rn/storage/ScaleBunStorageModule.kt +68 -68
  53. package/android/src/main/java/com/scalebun/storage/KvFileStore.kt +174 -174
  54. package/android/src/newarch/java/com/scalebun/profiler/ProfilerSpec.kt +12 -12
  55. package/android/src/newarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +12 -12
  56. package/android/src/newarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +15 -15
  57. package/android/src/newarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +16 -16
  58. package/android/src/newarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +12 -12
  59. package/android/src/newarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +14 -14
  60. package/android/src/newarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +16 -16
  61. package/android/src/oldarch/java/com/scalebun/profiler/ProfilerSpec.kt +34 -34
  62. package/android/src/oldarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +76 -76
  63. package/android/src/oldarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +21 -21
  64. package/android/src/oldarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +31 -25
  65. package/android/src/oldarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +27 -27
  66. package/android/src/oldarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +18 -18
  67. package/android/src/oldarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +26 -26
  68. package/bin/lib/iosCodemod.js +266 -266
  69. package/bin/scalebun.js +640 -640
  70. package/ios/Capture/InteractionTracker.swift +191 -191
  71. package/ios/Capture/PrivacyMaskProcessor.swift +158 -158
  72. package/ios/Capture/ScreenshotCaptureManager.swift +315 -315
  73. package/ios/Capture/WindowResolver.swift +63 -63
  74. package/ios/Core/ReplayConfig.swift +100 -100
  75. package/ios/Core/ReplayLogger.swift +22 -22
  76. package/ios/Core/SessionIdGenerator.swift +18 -18
  77. package/ios/Crash/ScaleBunCrashBridge.mm +69 -63
  78. package/ios/Crash/ScaleBunCrashHandler.swift +80 -67
  79. package/ios/Crash/ScaleBunCrashModule.swift +83 -69
  80. package/ios/Crash/ScaleBunCrashSignalBridge.h +49 -18
  81. package/ios/Crash/ScaleBunCrashSignalBridge.m +296 -131
  82. package/ios/Crash/ScaleBunCrashSignalStress.c +137 -0
  83. package/ios/Crash/ScaleBunCrashStorage.swift +121 -46
  84. package/ios/Engage/ScaleBunEngageBridge.m +32 -32
  85. package/ios/Engage/ScaleBunEngageModule.swift +250 -250
  86. package/ios/Engage/ScaleBunPushNotificationCenter.swift +185 -185
  87. package/ios/Ota/BundleDownloader.swift +182 -0
  88. package/ios/Ota/OtaSlotManager.swift +290 -264
  89. package/ios/Ota/ScaleBunOtaBridge.mm +77 -68
  90. package/ios/Ota/ScaleBunOtaEventsModule.swift +61 -0
  91. package/ios/Ota/ScaleBunOtaModule.swift +176 -123
  92. package/ios/Outbox/NativeOutbox.swift +598 -598
  93. package/ios/Outbox/OutboxUploader.swift +431 -431
  94. package/ios/Performance/ScaleBunPerformanceBridge.m +32 -32
  95. package/ios/Performance/ScaleBunPerformanceModule.swift +290 -290
  96. package/ios/PrivacyInfo.xcprivacy +97 -97
  97. package/ios/Profiler/ScaleBunProfilerBridge.m +55 -55
  98. package/ios/Profiler/ScaleBunProfilerModule.swift +972 -972
  99. package/ios/ReplaySdk-Bridging-Header.h +2 -2
  100. package/ios/ReplaySdk.swift +608 -608
  101. package/ios/ReplaySdkBridge.m +94 -94
  102. package/ios/Session/SessionManager.swift +203 -203
  103. package/ios/Skan/ScaleBunSkanBridge.m +14 -14
  104. package/ios/Skan/ScaleBunSkanModule.swift +61 -61
  105. package/ios/Storage/ReplayStorage.swift +61 -61
  106. package/ios/Storage/ScaleBunKvFileStore.swift +125 -125
  107. package/ios/Storage/ScaleBunStorageBridge.mm +72 -72
  108. package/ios/Storage/ScaleBunStorageModule.swift +57 -57
  109. package/ios/Transport/ReplayTransport.swift +70 -70
  110. package/ios/VoiceRecorder.swift +145 -145
  111. package/lib/commonjs/analytics/EventTracker.js +64 -36
  112. package/lib/commonjs/analytics/EventTracker.js.map +1 -1
  113. package/lib/commonjs/analytics/automaticEvents.js +7 -7
  114. package/lib/commonjs/analytics/automaticEvents.js.map +1 -1
  115. package/lib/commonjs/analytics/batching.js +24 -24
  116. package/lib/commonjs/analytics/batching.js.map +1 -1
  117. package/lib/commonjs/analytics/eventLane.js +13 -13
  118. package/lib/commonjs/analytics/eventLane.js.map +1 -1
  119. package/lib/commonjs/bootstrap/FeatureRegistry.js +17 -17
  120. package/lib/commonjs/bootstrap/FeatureRegistry.js.map +1 -1
  121. package/lib/commonjs/bootstrap/SDKBootstrapper.js +83 -56
  122. package/lib/commonjs/bootstrap/SDKBootstrapper.js.map +1 -1
  123. package/lib/commonjs/bucketing/fnv1a32.js +10 -10
  124. package/lib/commonjs/bucketing/fnv1a32.js.map +1 -1
  125. package/lib/commonjs/compat/codepush.js +6 -6
  126. package/lib/commonjs/compat/codepush.js.map +1 -1
  127. package/lib/commonjs/config/ConfigManager.js +20 -20
  128. package/lib/commonjs/config/ConfigManager.js.map +1 -1
  129. package/lib/commonjs/config/configTypes.js.map +1 -1
  130. package/lib/commonjs/core/architecture.js +23 -23
  131. package/lib/commonjs/core/architecture.js.map +1 -1
  132. package/lib/commonjs/core/clock/now.js +2 -2
  133. package/lib/commonjs/core/clock/now.js.map +1 -1
  134. package/lib/commonjs/core/config/defaults.js.map +1 -1
  135. package/lib/commonjs/core/config/schema.js +112 -104
  136. package/lib/commonjs/core/config/schema.js.map +1 -1
  137. package/lib/commonjs/core/constants/endpoints.js +7 -7
  138. package/lib/commonjs/core/constants/endpoints.js.map +1 -1
  139. package/lib/commonjs/core/constants/timings.js +5 -5
  140. package/lib/commonjs/core/constants/timings.js.map +1 -1
  141. package/lib/commonjs/core/constants/version.js +4 -4
  142. package/lib/commonjs/core/constants/version.js.map +1 -1
  143. package/lib/commonjs/core/context/app.js.map +1 -1
  144. package/lib/commonjs/core/context/device.js +130 -0
  145. package/lib/commonjs/core/context/device.js.map +1 -1
  146. package/lib/commonjs/core/context/session.js.map +1 -1
  147. package/lib/commonjs/core/context/user.js.map +1 -1
  148. package/lib/commonjs/core/contracts/IFeature.js.map +1 -1
  149. package/lib/commonjs/core/di/container.js.map +1 -1
  150. package/lib/commonjs/core/encoding/base64.js +9 -9
  151. package/lib/commonjs/core/encoding/base64.js.map +1 -1
  152. package/lib/commonjs/core/id/deviceId.js +4 -4
  153. package/lib/commonjs/core/id/deviceId.js.map +1 -1
  154. package/lib/commonjs/core/id/sessionId.js.map +1 -1
  155. package/lib/commonjs/core/lifecycle/appLifecycle.js.map +1 -1
  156. package/lib/commonjs/core/lifecycle/crashSafe.js +3 -3
  157. package/lib/commonjs/core/lifecycle/crashSafe.js.map +1 -1
  158. package/lib/commonjs/core/logger/errorClassification.js +30 -30
  159. package/lib/commonjs/core/logger/errorClassification.js.map +1 -1
  160. package/lib/commonjs/core/logger/internalLogger.js.map +1 -1
  161. package/lib/commonjs/core/logger/levels.js.map +1 -1
  162. package/lib/commonjs/crypto/hmacSha256.js +6 -6
  163. package/lib/commonjs/crypto/hmacSha256.js.map +1 -1
  164. package/lib/commonjs/debug/bootstrap.js +26 -26
  165. package/lib/commonjs/debug/bootstrap.js.map +1 -1
  166. package/lib/commonjs/debug/commands.js +10 -10
  167. package/lib/commonjs/debug/commands.js.map +1 -1
  168. package/lib/commonjs/debug/configBuilder.js +6 -6
  169. package/lib/commonjs/debug/configBuilder.js.map +1 -1
  170. package/lib/commonjs/debug/exportBridge.js +17 -17
  171. package/lib/commonjs/debug/exportBridge.js.map +1 -1
  172. package/lib/commonjs/debug/hostResolver.js +10 -10
  173. package/lib/commonjs/debug/hostResolver.js.map +1 -1
  174. package/lib/commonjs/debug/index.js.map +1 -1
  175. package/lib/commonjs/debug/metrics.js.map +1 -1
  176. package/lib/commonjs/debug/perf.js +11 -11
  177. package/lib/commonjs/debug/perf.js.map +1 -1
  178. package/lib/commonjs/debug/perfWiring.js +10 -10
  179. package/lib/commonjs/debug/perfWiring.js.map +1 -1
  180. package/lib/commonjs/debug/protocol.js.map +1 -1
  181. package/lib/commonjs/debug/redaction.js +26 -26
  182. package/lib/commonjs/debug/redaction.js.map +1 -1
  183. package/lib/commonjs/debug/replayWiring.js +13 -12
  184. package/lib/commonjs/debug/replayWiring.js.map +1 -1
  185. package/lib/commonjs/debug/screenTracking.js +7 -7
  186. package/lib/commonjs/debug/screenTracking.js.map +1 -1
  187. package/lib/commonjs/debug/sessionWiring.js +8 -8
  188. package/lib/commonjs/debug/sessionWiring.js.map +1 -1
  189. package/lib/commonjs/debug/stream.js +26 -26
  190. package/lib/commonjs/debug/stream.js.map +1 -1
  191. package/lib/commonjs/debug/transport.js +24 -24
  192. package/lib/commonjs/debug/transport.js.map +1 -1
  193. package/lib/commonjs/features/bugreport/BugReportFeature.js +112 -0
  194. package/lib/commonjs/features/bugreport/BugReportFeature.js.map +1 -0
  195. package/lib/commonjs/features/bugreport/buildPayload.js +97 -0
  196. package/lib/commonjs/features/bugreport/buildPayload.js.map +1 -0
  197. package/lib/commonjs/features/bugreport/index.js.map +1 -1
  198. package/lib/commonjs/features/crash/CrashFeature.js +27 -9
  199. package/lib/commonjs/features/crash/CrashFeature.js.map +1 -1
  200. package/lib/commonjs/features/crash/CrashReporter.js +53 -29
  201. package/lib/commonjs/features/crash/CrashReporter.js.map +1 -1
  202. package/lib/commonjs/features/crash/NativeCrashFeature.js +7 -7
  203. package/lib/commonjs/features/crash/NativeCrashFeature.js.map +1 -1
  204. package/lib/commonjs/features/crash/capture.js +27 -9
  205. package/lib/commonjs/features/crash/capture.js.map +1 -1
  206. package/lib/commonjs/features/crash/globalHandler.js +11 -11
  207. package/lib/commonjs/features/crash/globalHandler.js.map +1 -1
  208. package/lib/commonjs/features/crash/index.js.map +1 -1
  209. package/lib/commonjs/features/crash/nativeCrashBridge.js +179 -44
  210. package/lib/commonjs/features/crash/nativeCrashBridge.js.map +1 -1
  211. package/lib/commonjs/features/crash/rejectionHandler.js +123 -0
  212. package/lib/commonjs/features/crash/rejectionHandler.js.map +1 -0
  213. package/lib/commonjs/features/engage/EngageAnchor.js +3 -3
  214. package/lib/commonjs/features/engage/EngageAnchor.js.map +1 -1
  215. package/lib/commonjs/features/engage/EngageArchetypeRenderers.js +19 -19
  216. package/lib/commonjs/features/engage/EngageArchetypeRenderers.js.map +1 -1
  217. package/lib/commonjs/features/engage/EngageInAppView.js +35 -35
  218. package/lib/commonjs/features/engage/EngageInAppView.js.map +1 -1
  219. package/lib/commonjs/features/engage/EngageInlinePlacement.js +7 -7
  220. package/lib/commonjs/features/engage/EngageInlinePlacement.js.map +1 -1
  221. package/lib/commonjs/features/engage/EngagePromptProvider.js +124 -88
  222. package/lib/commonjs/features/engage/EngagePromptProvider.js.map +1 -1
  223. package/lib/commonjs/features/engage/EngagePromptView.js +65 -32
  224. package/lib/commonjs/features/engage/EngagePromptView.js.map +1 -1
  225. package/lib/commonjs/features/engage/EngageTransport.js +79 -79
  226. package/lib/commonjs/features/engage/EngageTransport.js.map +1 -1
  227. package/lib/commonjs/features/engage/EngageVariantContent.js +10 -10
  228. package/lib/commonjs/features/engage/EngageVariantContent.js.map +1 -1
  229. package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js +7 -7
  230. package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js.map +1 -1
  231. package/lib/commonjs/features/engage/attachmentCapture.js +12 -12
  232. package/lib/commonjs/features/engage/attachmentCapture.js.map +1 -1
  233. package/lib/commonjs/features/engage/captureVoiceAttachment.js +20 -20
  234. package/lib/commonjs/features/engage/captureVoiceAttachment.js.map +1 -1
  235. package/lib/commonjs/features/engage/engageCoachmarkTour.js +4 -4
  236. package/lib/commonjs/features/engage/engageCoachmarkTour.js.map +1 -1
  237. package/lib/commonjs/features/engage/engageGameLogic.js.map +1 -1
  238. package/lib/commonjs/features/engage/engageMediaSizing.js +15 -15
  239. package/lib/commonjs/features/engage/engageMediaSizing.js.map +1 -1
  240. package/lib/commonjs/features/engage/engageMultiStepSheet.js +6 -6
  241. package/lib/commonjs/features/engage/engageMultiStepSheet.js.map +1 -1
  242. package/lib/commonjs/features/engage/engageOutcome.js +6 -6
  243. package/lib/commonjs/features/engage/engageOutcome.js.map +1 -1
  244. package/lib/commonjs/features/engage/engagePushTokenBridge.js +20 -20
  245. package/lib/commonjs/features/engage/engagePushTokenBridge.js.map +1 -1
  246. package/lib/commonjs/features/engage/engageShakeBridge.js +16 -16
  247. package/lib/commonjs/features/engage/engageShakeBridge.js.map +1 -1
  248. package/lib/commonjs/features/engage/engageSignals.js.map +1 -1
  249. package/lib/commonjs/features/engage/engageStoreReviewBridge.js +19 -19
  250. package/lib/commonjs/features/engage/engageStoreReviewBridge.js.map +1 -1
  251. package/lib/commonjs/features/engage/engageTestSeenStore.js +29 -29
  252. package/lib/commonjs/features/engage/engageTestSeenStore.js.map +1 -1
  253. package/lib/commonjs/features/engage/engageThrottle.js +117 -86
  254. package/lib/commonjs/features/engage/engageThrottle.js.map +1 -1
  255. package/lib/commonjs/features/engage/engageTriggerEngine.js +17 -7
  256. package/lib/commonjs/features/engage/engageTriggerEngine.js.map +1 -1
  257. package/lib/commonjs/features/engage/engageTypes.js +33 -33
  258. package/lib/commonjs/features/engage/engageTypes.js.map +1 -1
  259. package/lib/commonjs/features/engage/engageVariantResolver.js +13 -13
  260. package/lib/commonjs/features/engage/engageVariantResolver.js.map +1 -1
  261. package/lib/commonjs/features/engage/engageWindowInsets.js +10 -10
  262. package/lib/commonjs/features/engage/engageWindowInsets.js.map +1 -1
  263. package/lib/commonjs/features/engage/gestureTriggerDetector.js.map +1 -1
  264. package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js +16 -16
  265. package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js.map +1 -1
  266. package/lib/commonjs/features/install-referrer/installReferrer.js +26 -26
  267. package/lib/commonjs/features/install-referrer/installReferrer.js.map +1 -1
  268. package/lib/commonjs/features/journey/ScaleBunDebugRoot.js +30 -29
  269. package/lib/commonjs/features/journey/ScaleBunDebugRoot.js.map +1 -1
  270. package/lib/commonjs/features/journey/ScaleBunFlatList.js +15 -15
  271. package/lib/commonjs/features/journey/ScaleBunFlatList.js.map +1 -1
  272. package/lib/commonjs/features/journey/ScaleBunImpression.js +22 -22
  273. package/lib/commonjs/features/journey/ScaleBunImpression.js.map +1 -1
  274. package/lib/commonjs/features/journey/ScaleBunScrollView.js +20 -20
  275. package/lib/commonjs/features/journey/ScaleBunScrollView.js.map +1 -1
  276. package/lib/commonjs/features/journey/ScaleBunSectionList.js +15 -15
  277. package/lib/commonjs/features/journey/ScaleBunSectionList.js.map +1 -1
  278. package/lib/commonjs/features/journey/calibrationContext.js +12 -12
  279. package/lib/commonjs/features/journey/calibrationContext.js.map +1 -1
  280. package/lib/commonjs/features/journey/gestureBuffer.js +9 -9
  281. package/lib/commonjs/features/journey/gestureBuffer.js.map +1 -1
  282. package/lib/commonjs/features/journey/gestureDetector.js +10 -10
  283. package/lib/commonjs/features/journey/gestureDetector.js.map +1 -1
  284. package/lib/commonjs/features/journey/impression.js +18 -18
  285. package/lib/commonjs/features/journey/impression.js.map +1 -1
  286. package/lib/commonjs/features/journey/journeyManager.js +6 -6
  287. package/lib/commonjs/features/journey/journeyManager.js.map +1 -1
  288. package/lib/commonjs/features/journey/journeyTypes.js +5 -5
  289. package/lib/commonjs/features/journey/journeyTypes.js.map +1 -1
  290. package/lib/commonjs/features/journey/navDetector.js +7 -7
  291. package/lib/commonjs/features/journey/navDetector.js.map +1 -1
  292. package/lib/commonjs/features/journey/screenshotHelper.js +7 -7
  293. package/lib/commonjs/features/journey/screenshotHelper.js.map +1 -1
  294. package/lib/commonjs/features/journey/targetRegistry.js +17 -17
  295. package/lib/commonjs/features/journey/targetRegistry.js.map +1 -1
  296. package/lib/commonjs/features/journey/touchTarget.js +29 -29
  297. package/lib/commonjs/features/journey/touchTarget.js.map +1 -1
  298. package/lib/commonjs/features/navigation/AutoScreenDetector.js +114 -71
  299. package/lib/commonjs/features/navigation/AutoScreenDetector.js.map +1 -1
  300. package/lib/commonjs/features/network/NetworkFeature.js +23 -23
  301. package/lib/commonjs/features/network/NetworkFeature.js.map +1 -1
  302. package/lib/commonjs/features/network/index.js +5 -5
  303. package/lib/commonjs/features/network/index.js.map +1 -1
  304. package/lib/commonjs/features/ota/OtaEventEmitter.js +21 -21
  305. package/lib/commonjs/features/ota/OtaEventEmitter.js.map +1 -1
  306. package/lib/commonjs/features/ota/OtaOrchestrator.js +595 -42
  307. package/lib/commonjs/features/ota/OtaOrchestrator.js.map +1 -1
  308. package/lib/commonjs/features/ota/OtaTypes.js.map +1 -1
  309. package/lib/commonjs/features/ota/deviceAttributes.js +48 -0
  310. package/lib/commonjs/features/ota/deviceAttributes.js.map +1 -0
  311. package/lib/commonjs/features/ota/environment.js +172 -0
  312. package/lib/commonjs/features/ota/environment.js.map +1 -0
  313. package/lib/commonjs/features/ota/geoCountry.js +93 -0
  314. package/lib/commonjs/features/ota/geoCountry.js.map +1 -0
  315. package/lib/commonjs/features/ota/retry.js +96 -0
  316. package/lib/commonjs/features/ota/retry.js.map +1 -0
  317. package/lib/commonjs/features/ota/signature.js +115 -0
  318. package/lib/commonjs/features/ota/signature.js.map +1 -0
  319. package/lib/commonjs/features/ota/useOtaUpdate.js +18 -15
  320. package/lib/commonjs/features/ota/useOtaUpdate.js.map +1 -1
  321. package/lib/commonjs/features/performance/PerformanceFeature.js +49 -35
  322. package/lib/commonjs/features/performance/PerformanceFeature.js.map +1 -1
  323. package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js +13 -13
  324. package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js.map +1 -1
  325. package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js +32 -32
  326. package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js.map +1 -1
  327. package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js +13 -13
  328. package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js.map +1 -1
  329. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js +80 -20
  330. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
  331. package/lib/commonjs/features/performance/collectors/JsStallCollector.js +12 -12
  332. package/lib/commonjs/features/performance/collectors/JsStallCollector.js.map +1 -1
  333. package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js +10 -10
  334. package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js.map +1 -1
  335. package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js +11 -11
  336. package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js.map +1 -1
  337. package/lib/commonjs/features/performance/collectors/UiHangCollector.js +5 -5
  338. package/lib/commonjs/features/performance/collectors/UiHangCollector.js.map +1 -1
  339. package/lib/commonjs/features/performance/config.js +11 -11
  340. package/lib/commonjs/features/performance/config.js.map +1 -1
  341. package/lib/commonjs/features/performance/getNativePerformanceModule.js +11 -11
  342. package/lib/commonjs/features/performance/getNativePerformanceModule.js.map +1 -1
  343. package/lib/commonjs/features/performance/index.js.map +1 -1
  344. package/lib/commonjs/features/performance/metrics/MetricsEngine.js +13 -13
  345. package/lib/commonjs/features/performance/metrics/MetricsEngine.js.map +1 -1
  346. package/lib/commonjs/features/performance/models.js +8 -8
  347. package/lib/commonjs/features/performance/models.js.map +1 -1
  348. package/lib/commonjs/features/performance/transport/PerformanceTransport.js +31 -6
  349. package/lib/commonjs/features/performance/transport/PerformanceTransport.js.map +1 -1
  350. package/lib/commonjs/features/profiler/ProfilerFeature.js +53 -53
  351. package/lib/commonjs/features/profiler/ProfilerFeature.js.map +1 -1
  352. package/lib/commonjs/features/profiler/config.js +15 -15
  353. package/lib/commonjs/features/profiler/config.js.map +1 -1
  354. package/lib/commonjs/features/profiler/contracts.js +22 -22
  355. package/lib/commonjs/features/profiler/contracts.js.map +1 -1
  356. package/lib/commonjs/features/profiler/index.js.map +1 -1
  357. package/lib/commonjs/features/profiler/models.js +44 -44
  358. package/lib/commonjs/features/profiler/models.js.map +1 -1
  359. package/lib/commonjs/features/profiler/transport/ProfilerTransport.js +9 -9
  360. package/lib/commonjs/features/profiler/transport/ProfilerTransport.js.map +1 -1
  361. package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js +17 -17
  362. package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js.map +1 -1
  363. package/lib/commonjs/features/replay/bridge/eventEmitter.js +8 -8
  364. package/lib/commonjs/features/replay/bridge/eventEmitter.js.map +1 -1
  365. package/lib/commonjs/features/replay/bridge/nativeModule.js +20 -20
  366. package/lib/commonjs/features/replay/bridge/nativeModule.js.map +1 -1
  367. package/lib/commonjs/features/replay/core/clock/clock.js +6 -6
  368. package/lib/commonjs/features/replay/core/clock/clock.js.map +1 -1
  369. package/lib/commonjs/features/replay/core/config/defaults.js +2 -2
  370. package/lib/commonjs/features/replay/core/config/defaults.js.map +1 -1
  371. package/lib/commonjs/features/replay/core/config/validator.js +5 -5
  372. package/lib/commonjs/features/replay/core/config/validator.js.map +1 -1
  373. package/lib/commonjs/features/replay/core/env/environmentDetector.js +10 -10
  374. package/lib/commonjs/features/replay/core/env/environmentDetector.js.map +1 -1
  375. package/lib/commonjs/features/replay/core/errors/safeCall.js +4 -4
  376. package/lib/commonjs/features/replay/core/errors/safeCall.js.map +1 -1
  377. package/lib/commonjs/features/replay/core/ids/sessionId.js +5 -5
  378. package/lib/commonjs/features/replay/core/ids/sessionId.js.map +1 -1
  379. package/lib/commonjs/features/replay/core/logger/logger.js +5 -5
  380. package/lib/commonjs/features/replay/core/logger/logger.js.map +1 -1
  381. package/lib/commonjs/features/replay/core/privacy/privacyTypes.js +4 -4
  382. package/lib/commonjs/features/replay/core/privacy/privacyTypes.js.map +1 -1
  383. package/lib/commonjs/features/replay/core/queue/boundedQueue.js +5 -5
  384. package/lib/commonjs/features/replay/core/queue/boundedQueue.js.map +1 -1
  385. package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js +59 -59
  386. package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js.map +1 -1
  387. package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js +19 -19
  388. package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js.map +1 -1
  389. package/lib/commonjs/features/replay/integrations/network/networkAdapter.js +30 -30
  390. package/lib/commonjs/features/replay/integrations/network/networkAdapter.js.map +1 -1
  391. package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js +19 -19
  392. package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
  393. package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js +16 -16
  394. package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
  395. package/lib/commonjs/features/replay/pipeline/batching/batchManager.js +5 -5
  396. package/lib/commonjs/features/replay/pipeline/batching/batchManager.js.map +1 -1
  397. package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js +5 -5
  398. package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js.map +1 -1
  399. package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js +4 -4
  400. package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
  401. package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js +7 -7
  402. package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js.map +1 -1
  403. package/lib/commonjs/features/replay/public/api.js +21 -21
  404. package/lib/commonjs/features/replay/public/api.js.map +1 -1
  405. package/lib/commonjs/features/replay/public/enums.js +5 -5
  406. package/lib/commonjs/features/replay/public/enums.js.map +1 -1
  407. package/lib/commonjs/features/replay/public/types.js.map +1 -1
  408. package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js +5 -5
  409. package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js.map +1 -1
  410. package/lib/commonjs/features/replay/replay/frames/frameModels.js +4 -4
  411. package/lib/commonjs/features/replay/replay/frames/frameModels.js.map +1 -1
  412. package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js +10 -10
  413. package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
  414. package/lib/commonjs/features/replay/replay/timeline/timelineModels.js +4 -4
  415. package/lib/commonjs/features/replay/replay/timeline/timelineModels.js.map +1 -1
  416. package/lib/commonjs/features/replay/transport/BackendReplayTransport.js +13 -13
  417. package/lib/commonjs/features/replay/transport/BackendReplayTransport.js.map +1 -1
  418. package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js +8 -8
  419. package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js.map +1 -1
  420. package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js +14 -14
  421. package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js.map +1 -1
  422. package/lib/commonjs/features/replay/transport/ReplayTransport.js.map +1 -1
  423. package/lib/commonjs/features/session/BackendSessionAdapter.js +486 -164
  424. package/lib/commonjs/features/session/BackendSessionAdapter.js.map +1 -1
  425. package/lib/commonjs/features/session/DesktopSessionTransport.js +14 -14
  426. package/lib/commonjs/features/session/DesktopSessionTransport.js.map +1 -1
  427. package/lib/commonjs/features/session/JourneyEventPipeline.js +20 -19
  428. package/lib/commonjs/features/session/JourneyEventPipeline.js.map +1 -1
  429. package/lib/commonjs/features/session/ReplayCaptureManager.js +169 -123
  430. package/lib/commonjs/features/session/ReplayCaptureManager.js.map +1 -1
  431. package/lib/commonjs/features/session/ScrollTracker.js +17 -17
  432. package/lib/commonjs/features/session/ScrollTracker.js.map +1 -1
  433. package/lib/commonjs/features/session/SessionManager.js +185 -155
  434. package/lib/commonjs/features/session/SessionManager.js.map +1 -1
  435. package/lib/commonjs/features/session/SyncDecisionEngine.js +23 -23
  436. package/lib/commonjs/features/session/SyncDecisionEngine.js.map +1 -1
  437. package/lib/commonjs/features/session/index.js.map +1 -1
  438. package/lib/commonjs/features/session/nativeCapture.js +9 -9
  439. package/lib/commonjs/features/session/nativeCapture.js.map +1 -1
  440. package/lib/commonjs/features/session/outboxFrameCapture.js +18 -17
  441. package/lib/commonjs/features/session/outboxFrameCapture.js.map +1 -1
  442. package/lib/commonjs/features/session/sessionTypes.js +44 -44
  443. package/lib/commonjs/features/session/sessionTypes.js.map +1 -1
  444. package/lib/commonjs/features/skan/skanBridge.js +11 -11
  445. package/lib/commonjs/features/skan/skanBridge.js.map +1 -1
  446. package/lib/commonjs/features/skan/skanConversionManager.js +23 -23
  447. package/lib/commonjs/features/skan/skanConversionManager.js.map +1 -1
  448. package/lib/commonjs/index.js +20 -0
  449. package/lib/commonjs/index.js.map +1 -1
  450. package/lib/commonjs/integrations/fetch/fetchInterceptor.js +21 -21
  451. package/lib/commonjs/integrations/fetch/fetchInterceptor.js.map +1 -1
  452. package/lib/commonjs/integrations/navigation/screenTracker.js.map +1 -1
  453. package/lib/commonjs/integrations/network/bodyCapture.js +69 -69
  454. package/lib/commonjs/integrations/network/bodyCapture.js.map +1 -1
  455. package/lib/commonjs/integrations/xhr/xhrInterceptor.js +24 -24
  456. package/lib/commonjs/integrations/xhr/xhrInterceptor.js.map +1 -1
  457. package/lib/commonjs/metro/index.js +37 -37
  458. package/lib/commonjs/metro/index.js.map +1 -1
  459. package/lib/commonjs/metro/optionalDependencyStub.js.map +1 -1
  460. package/lib/commonjs/metro/optionalModules.js +16 -16
  461. package/lib/commonjs/metro/optionalModules.js.map +1 -1
  462. package/lib/commonjs/pipeline/dispatcher/dispatcher.js.map +1 -1
  463. package/lib/commonjs/pipeline/envelope/envelope.js.map +1 -1
  464. package/lib/commonjs/pipeline/envelope/serializer.js.map +1 -1
  465. package/lib/commonjs/pipeline/processors/dedupe.js.map +1 -1
  466. package/lib/commonjs/pipeline/processors/enrich.js.map +1 -1
  467. package/lib/commonjs/pipeline/processors/sampling.js.map +1 -1
  468. package/lib/commonjs/pipeline/processors/sanitize.js.map +1 -1
  469. package/lib/commonjs/pipeline/queue/flushQueue.js +4 -4
  470. package/lib/commonjs/pipeline/queue/flushQueue.js.map +1 -1
  471. package/lib/commonjs/pipeline/queue/memoryQueue.js.map +1 -1
  472. package/lib/commonjs/pipeline/queue/persistentQueue.js +80 -80
  473. package/lib/commonjs/pipeline/queue/persistentQueue.js.map +1 -1
  474. package/lib/commonjs/pipeline/queue/queuePolicy.js.map +1 -1
  475. package/lib/commonjs/pipeline/scheduler/flushScheduler.js.map +1 -1
  476. package/lib/commonjs/pipeline/scheduler/retryPolicy.js +2 -2
  477. package/lib/commonjs/pipeline/scheduler/retryPolicy.js.map +1 -1
  478. package/lib/commonjs/public/ScaleBunErrorBoundary.js +79 -0
  479. package/lib/commonjs/public/ScaleBunErrorBoundary.js.map +1 -0
  480. package/lib/commonjs/public/ScaleBunFacade.js +424 -276
  481. package/lib/commonjs/public/ScaleBunFacade.js.map +1 -1
  482. package/lib/commonjs/public/ScaleBunProvider.js +3 -3
  483. package/lib/commonjs/public/ScaleBunProvider.js.map +1 -1
  484. package/lib/commonjs/public/typedTracker.js +36 -36
  485. package/lib/commonjs/public/typedTracker.js.map +1 -1
  486. package/lib/commonjs/public/types.js.map +1 -1
  487. package/lib/commonjs/push/PushManager.js +21 -21
  488. package/lib/commonjs/push/PushManager.js.map +1 -1
  489. package/lib/commonjs/push/adapters/ManualAdapter.js +14 -14
  490. package/lib/commonjs/push/adapters/ManualAdapter.js.map +1 -1
  491. package/lib/commonjs/push/adapters/NativeBridgeAdapter.js +17 -17
  492. package/lib/commonjs/push/adapters/NativeBridgeAdapter.js.map +1 -1
  493. package/lib/commonjs/push/adapters/NoopAdapter.js +5 -5
  494. package/lib/commonjs/push/adapters/NoopAdapter.js.map +1 -1
  495. package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js +17 -17
  496. package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js.map +1 -1
  497. package/lib/commonjs/push/adapters/loadMessaging.js +12 -12
  498. package/lib/commonjs/push/adapters/loadMessaging.js.map +1 -1
  499. package/lib/commonjs/push/adapters/loadNotifee.js +12 -12
  500. package/lib/commonjs/push/adapters/loadNotifee.js.map +1 -1
  501. package/lib/commonjs/push/adapters/selectAdapter.js +14 -14
  502. package/lib/commonjs/push/adapters/selectAdapter.js.map +1 -1
  503. package/lib/commonjs/push/detect/capabilities.js +19 -19
  504. package/lib/commonjs/push/detect/capabilities.js.map +1 -1
  505. package/lib/commonjs/push/index.js.map +1 -1
  506. package/lib/commonjs/push/native/nativeNotifications.js +32 -32
  507. package/lib/commonjs/push/native/nativeNotifications.js.map +1 -1
  508. package/lib/commonjs/push/types.js.map +1 -1
  509. package/lib/commonjs/specs/NativeReplaySdk.js +18 -18
  510. package/lib/commonjs/specs/NativeReplaySdk.js.map +1 -1
  511. package/lib/commonjs/specs/NativeScaleBunCrash.js +19 -19
  512. package/lib/commonjs/specs/NativeScaleBunCrash.js.map +1 -1
  513. package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js +14 -14
  514. package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js.map +1 -1
  515. package/lib/commonjs/specs/NativeScaleBunOta.js +21 -21
  516. package/lib/commonjs/specs/NativeScaleBunOta.js.map +1 -1
  517. package/lib/commonjs/specs/NativeScaleBunPerformance.js +15 -15
  518. package/lib/commonjs/specs/NativeScaleBunPerformance.js.map +1 -1
  519. package/lib/commonjs/specs/NativeScaleBunProfiler.js +16 -16
  520. package/lib/commonjs/specs/NativeScaleBunProfiler.js.map +1 -1
  521. package/lib/commonjs/specs/NativeScaleBunStorage.js +29 -29
  522. package/lib/commonjs/specs/NativeScaleBunStorage.js.map +1 -1
  523. package/lib/commonjs/storage/StorageBackend.js +83 -83
  524. package/lib/commonjs/storage/StorageBackend.js.map +1 -1
  525. package/lib/commonjs/storage/db/sqlite.js.map +1 -1
  526. package/lib/commonjs/storage/files/fileStore.js.map +1 -1
  527. package/lib/commonjs/transport/auth/sdkSession.js.map +1 -1
  528. package/lib/commonjs/transport/backoff/exponentialJitter.js +2 -2
  529. package/lib/commonjs/transport/backoff/exponentialJitter.js.map +1 -1
  530. package/lib/commonjs/transport/http/endpoints.js.map +1 -1
  531. package/lib/commonjs/transport/http/httpClient.js +3 -3
  532. package/lib/commonjs/transport/http/httpClient.js.map +1 -1
  533. package/lib/commonjs/transport/rateLimit/retryAfter.js.map +1 -1
  534. package/lib/commonjs/transport/signing/requestSigner.js.map +1 -1
  535. package/lib/commonjs/vendor/protocol/index.js +74 -74
  536. package/lib/commonjs/vendor/protocol/index.js.map +1 -1
  537. package/lib/commonjs/vendor/protocol/internal/validation.js +23 -23
  538. package/lib/commonjs/vendor/protocol/internal/validation.js.map +1 -1
  539. package/lib/commonjs/vendor/sdk-contracts/bridge.js.map +1 -1
  540. package/lib/commonjs/vendor/sdk-contracts/config.js.map +1 -1
  541. package/lib/commonjs/vendor/sdk-contracts/events.js.map +1 -1
  542. package/lib/commonjs/vendor/sdk-contracts/features.js.map +1 -1
  543. package/lib/commonjs/vendor/sdk-contracts/index.js.map +1 -1
  544. package/lib/commonjs/vendor/sdk-contracts/platform.js.map +1 -1
  545. package/lib/commonjs/vendor/sdk-contracts/session-boundary.js.map +1 -1
  546. package/lib/commonjs/vendor/sdk-contracts/session.js.map +1 -1
  547. package/lib/commonjs/vendor/vendor.manifest +10 -10
  548. package/lib/module/analytics/EventTracker.js +63 -35
  549. package/lib/module/analytics/EventTracker.js.map +1 -1
  550. package/lib/module/analytics/automaticEvents.js +7 -7
  551. package/lib/module/analytics/automaticEvents.js.map +1 -1
  552. package/lib/module/analytics/batching.js +24 -24
  553. package/lib/module/analytics/batching.js.map +1 -1
  554. package/lib/module/analytics/eventLane.js +13 -13
  555. package/lib/module/analytics/eventLane.js.map +1 -1
  556. package/lib/module/bootstrap/FeatureRegistry.js +17 -17
  557. package/lib/module/bootstrap/FeatureRegistry.js.map +1 -1
  558. package/lib/module/bootstrap/SDKBootstrapper.js +81 -54
  559. package/lib/module/bootstrap/SDKBootstrapper.js.map +1 -1
  560. package/lib/module/bucketing/fnv1a32.js +10 -10
  561. package/lib/module/bucketing/fnv1a32.js.map +1 -1
  562. package/lib/module/compat/codepush.js +6 -6
  563. package/lib/module/compat/codepush.js.map +1 -1
  564. package/lib/module/config/ConfigManager.js +20 -20
  565. package/lib/module/config/ConfigManager.js.map +1 -1
  566. package/lib/module/config/configTypes.js.map +1 -1
  567. package/lib/module/core/architecture.js +23 -23
  568. package/lib/module/core/architecture.js.map +1 -1
  569. package/lib/module/core/clock/now.js +2 -2
  570. package/lib/module/core/clock/now.js.map +1 -1
  571. package/lib/module/core/config/defaults.js.map +1 -1
  572. package/lib/module/core/config/schema.js +112 -104
  573. package/lib/module/core/config/schema.js.map +1 -1
  574. package/lib/module/core/constants/endpoints.js +7 -7
  575. package/lib/module/core/constants/endpoints.js.map +1 -1
  576. package/lib/module/core/constants/timings.js +5 -5
  577. package/lib/module/core/constants/timings.js.map +1 -1
  578. package/lib/module/core/constants/version.js +4 -4
  579. package/lib/module/core/constants/version.js.map +1 -1
  580. package/lib/module/core/context/app.js.map +1 -1
  581. package/lib/module/core/context/device.js +119 -0
  582. package/lib/module/core/context/device.js.map +1 -1
  583. package/lib/module/core/context/session.js.map +1 -1
  584. package/lib/module/core/context/user.js.map +1 -1
  585. package/lib/module/core/contracts/IFeature.js.map +1 -1
  586. package/lib/module/core/di/container.js.map +1 -1
  587. package/lib/module/core/encoding/base64.js +9 -9
  588. package/lib/module/core/encoding/base64.js.map +1 -1
  589. package/lib/module/core/id/deviceId.js +4 -4
  590. package/lib/module/core/id/deviceId.js.map +1 -1
  591. package/lib/module/core/id/sessionId.js.map +1 -1
  592. package/lib/module/core/lifecycle/appLifecycle.js.map +1 -1
  593. package/lib/module/core/lifecycle/crashSafe.js +3 -3
  594. package/lib/module/core/lifecycle/crashSafe.js.map +1 -1
  595. package/lib/module/core/logger/errorClassification.js +30 -30
  596. package/lib/module/core/logger/errorClassification.js.map +1 -1
  597. package/lib/module/core/logger/internalLogger.js.map +1 -1
  598. package/lib/module/core/logger/levels.js.map +1 -1
  599. package/lib/module/crypto/hmacSha256.js +6 -6
  600. package/lib/module/crypto/hmacSha256.js.map +1 -1
  601. package/lib/module/debug/bootstrap.js +26 -26
  602. package/lib/module/debug/bootstrap.js.map +1 -1
  603. package/lib/module/debug/commands.js +10 -10
  604. package/lib/module/debug/commands.js.map +1 -1
  605. package/lib/module/debug/configBuilder.js +6 -6
  606. package/lib/module/debug/configBuilder.js.map +1 -1
  607. package/lib/module/debug/exportBridge.js +17 -17
  608. package/lib/module/debug/exportBridge.js.map +1 -1
  609. package/lib/module/debug/hostResolver.js +10 -10
  610. package/lib/module/debug/hostResolver.js.map +1 -1
  611. package/lib/module/debug/index.js +5 -5
  612. package/lib/module/debug/index.js.map +1 -1
  613. package/lib/module/debug/metrics.js.map +1 -1
  614. package/lib/module/debug/perf.js +11 -11
  615. package/lib/module/debug/perf.js.map +1 -1
  616. package/lib/module/debug/perfWiring.js +10 -10
  617. package/lib/module/debug/perfWiring.js.map +1 -1
  618. package/lib/module/debug/protocol.js +11 -11
  619. package/lib/module/debug/protocol.js.map +1 -1
  620. package/lib/module/debug/redaction.js +26 -26
  621. package/lib/module/debug/redaction.js.map +1 -1
  622. package/lib/module/debug/replayWiring.js +13 -12
  623. package/lib/module/debug/replayWiring.js.map +1 -1
  624. package/lib/module/debug/screenTracking.js +7 -7
  625. package/lib/module/debug/screenTracking.js.map +1 -1
  626. package/lib/module/debug/sessionWiring.js +8 -8
  627. package/lib/module/debug/sessionWiring.js.map +1 -1
  628. package/lib/module/debug/stream.js +26 -26
  629. package/lib/module/debug/stream.js.map +1 -1
  630. package/lib/module/debug/transport.js +24 -24
  631. package/lib/module/debug/transport.js.map +1 -1
  632. package/lib/module/features/bugreport/BugReportFeature.js +105 -0
  633. package/lib/module/features/bugreport/BugReportFeature.js.map +1 -0
  634. package/lib/module/features/bugreport/buildPayload.js +91 -0
  635. package/lib/module/features/bugreport/buildPayload.js.map +1 -0
  636. package/lib/module/features/bugreport/index.js.map +1 -1
  637. package/lib/module/features/crash/CrashFeature.js +27 -9
  638. package/lib/module/features/crash/CrashFeature.js.map +1 -1
  639. package/lib/module/features/crash/CrashReporter.js +53 -29
  640. package/lib/module/features/crash/CrashReporter.js.map +1 -1
  641. package/lib/module/features/crash/NativeCrashFeature.js +7 -7
  642. package/lib/module/features/crash/NativeCrashFeature.js.map +1 -1
  643. package/lib/module/features/crash/capture.js +28 -9
  644. package/lib/module/features/crash/capture.js.map +1 -1
  645. package/lib/module/features/crash/globalHandler.js +11 -11
  646. package/lib/module/features/crash/globalHandler.js.map +1 -1
  647. package/lib/module/features/crash/index.js.map +1 -1
  648. package/lib/module/features/crash/nativeCrashBridge.js +177 -44
  649. package/lib/module/features/crash/nativeCrashBridge.js.map +1 -1
  650. package/lib/module/features/crash/rejectionHandler.js +116 -0
  651. package/lib/module/features/crash/rejectionHandler.js.map +1 -0
  652. package/lib/module/features/engage/EngageAnchor.js +3 -3
  653. package/lib/module/features/engage/EngageAnchor.js.map +1 -1
  654. package/lib/module/features/engage/EngageArchetypeRenderers.js +19 -19
  655. package/lib/module/features/engage/EngageArchetypeRenderers.js.map +1 -1
  656. package/lib/module/features/engage/EngageInAppView.js +35 -35
  657. package/lib/module/features/engage/EngageInAppView.js.map +1 -1
  658. package/lib/module/features/engage/EngageInlinePlacement.js +7 -7
  659. package/lib/module/features/engage/EngageInlinePlacement.js.map +1 -1
  660. package/lib/module/features/engage/EngagePromptProvider.js +124 -88
  661. package/lib/module/features/engage/EngagePromptProvider.js.map +1 -1
  662. package/lib/module/features/engage/EngagePromptView.js +65 -32
  663. package/lib/module/features/engage/EngagePromptView.js.map +1 -1
  664. package/lib/module/features/engage/EngageTransport.js +79 -79
  665. package/lib/module/features/engage/EngageTransport.js.map +1 -1
  666. package/lib/module/features/engage/EngageVariantContent.js +10 -10
  667. package/lib/module/features/engage/EngageVariantContent.js.map +1 -1
  668. package/lib/module/features/engage/__test-support__/reactNativeStub.js +7 -7
  669. package/lib/module/features/engage/__test-support__/reactNativeStub.js.map +1 -1
  670. package/lib/module/features/engage/attachmentCapture.js +12 -12
  671. package/lib/module/features/engage/attachmentCapture.js.map +1 -1
  672. package/lib/module/features/engage/captureVoiceAttachment.js +20 -20
  673. package/lib/module/features/engage/captureVoiceAttachment.js.map +1 -1
  674. package/lib/module/features/engage/engageCoachmarkTour.js +4 -4
  675. package/lib/module/features/engage/engageCoachmarkTour.js.map +1 -1
  676. package/lib/module/features/engage/engageGameLogic.js.map +1 -1
  677. package/lib/module/features/engage/engageMediaSizing.js +15 -15
  678. package/lib/module/features/engage/engageMediaSizing.js.map +1 -1
  679. package/lib/module/features/engage/engageMultiStepSheet.js +6 -6
  680. package/lib/module/features/engage/engageMultiStepSheet.js.map +1 -1
  681. package/lib/module/features/engage/engageOutcome.js +6 -6
  682. package/lib/module/features/engage/engageOutcome.js.map +1 -1
  683. package/lib/module/features/engage/engagePushTokenBridge.js +20 -20
  684. package/lib/module/features/engage/engagePushTokenBridge.js.map +1 -1
  685. package/lib/module/features/engage/engageShakeBridge.js +16 -16
  686. package/lib/module/features/engage/engageShakeBridge.js.map +1 -1
  687. package/lib/module/features/engage/engageSignals.js.map +1 -1
  688. package/lib/module/features/engage/engageStoreReviewBridge.js +19 -19
  689. package/lib/module/features/engage/engageStoreReviewBridge.js.map +1 -1
  690. package/lib/module/features/engage/engageTestSeenStore.js +29 -29
  691. package/lib/module/features/engage/engageTestSeenStore.js.map +1 -1
  692. package/lib/module/features/engage/engageThrottle.js +117 -86
  693. package/lib/module/features/engage/engageThrottle.js.map +1 -1
  694. package/lib/module/features/engage/engageTriggerEngine.js +17 -7
  695. package/lib/module/features/engage/engageTriggerEngine.js.map +1 -1
  696. package/lib/module/features/engage/engageTypes.js +33 -33
  697. package/lib/module/features/engage/engageTypes.js.map +1 -1
  698. package/lib/module/features/engage/engageVariantResolver.js +13 -13
  699. package/lib/module/features/engage/engageVariantResolver.js.map +1 -1
  700. package/lib/module/features/engage/engageWindowInsets.js +10 -10
  701. package/lib/module/features/engage/engageWindowInsets.js.map +1 -1
  702. package/lib/module/features/engage/gestureTriggerDetector.js.map +1 -1
  703. package/lib/module/features/engage/transcription/TranscriptionProvider.js +16 -16
  704. package/lib/module/features/engage/transcription/TranscriptionProvider.js.map +1 -1
  705. package/lib/module/features/install-referrer/installReferrer.js +26 -26
  706. package/lib/module/features/install-referrer/installReferrer.js.map +1 -1
  707. package/lib/module/features/journey/ScaleBunDebugRoot.js +30 -29
  708. package/lib/module/features/journey/ScaleBunDebugRoot.js.map +1 -1
  709. package/lib/module/features/journey/ScaleBunFlatList.js +15 -15
  710. package/lib/module/features/journey/ScaleBunFlatList.js.map +1 -1
  711. package/lib/module/features/journey/ScaleBunImpression.js +22 -22
  712. package/lib/module/features/journey/ScaleBunImpression.js.map +1 -1
  713. package/lib/module/features/journey/ScaleBunScrollView.js +20 -20
  714. package/lib/module/features/journey/ScaleBunScrollView.js.map +1 -1
  715. package/lib/module/features/journey/ScaleBunSectionList.js +15 -15
  716. package/lib/module/features/journey/ScaleBunSectionList.js.map +1 -1
  717. package/lib/module/features/journey/calibrationContext.js +12 -12
  718. package/lib/module/features/journey/calibrationContext.js.map +1 -1
  719. package/lib/module/features/journey/gestureBuffer.js +9 -9
  720. package/lib/module/features/journey/gestureBuffer.js.map +1 -1
  721. package/lib/module/features/journey/gestureDetector.js +10 -10
  722. package/lib/module/features/journey/gestureDetector.js.map +1 -1
  723. package/lib/module/features/journey/impression.js +18 -18
  724. package/lib/module/features/journey/impression.js.map +1 -1
  725. package/lib/module/features/journey/journeyManager.js +6 -6
  726. package/lib/module/features/journey/journeyManager.js.map +1 -1
  727. package/lib/module/features/journey/journeyTypes.js +5 -5
  728. package/lib/module/features/journey/journeyTypes.js.map +1 -1
  729. package/lib/module/features/journey/navDetector.js +7 -7
  730. package/lib/module/features/journey/navDetector.js.map +1 -1
  731. package/lib/module/features/journey/screenshotHelper.js +7 -7
  732. package/lib/module/features/journey/screenshotHelper.js.map +1 -1
  733. package/lib/module/features/journey/targetRegistry.js +17 -17
  734. package/lib/module/features/journey/targetRegistry.js.map +1 -1
  735. package/lib/module/features/journey/touchTarget.js +29 -29
  736. package/lib/module/features/journey/touchTarget.js.map +1 -1
  737. package/lib/module/features/navigation/AutoScreenDetector.js +114 -71
  738. package/lib/module/features/navigation/AutoScreenDetector.js.map +1 -1
  739. package/lib/module/features/network/NetworkFeature.js +23 -23
  740. package/lib/module/features/network/NetworkFeature.js.map +1 -1
  741. package/lib/module/features/network/index.js +5 -5
  742. package/lib/module/features/network/index.js.map +1 -1
  743. package/lib/module/features/ota/OtaEventEmitter.js +21 -21
  744. package/lib/module/features/ota/OtaEventEmitter.js.map +1 -1
  745. package/lib/module/features/ota/OtaOrchestrator.js +596 -43
  746. package/lib/module/features/ota/OtaOrchestrator.js.map +1 -1
  747. package/lib/module/features/ota/OtaTypes.js.map +1 -1
  748. package/lib/module/features/ota/deviceAttributes.js +43 -0
  749. package/lib/module/features/ota/deviceAttributes.js.map +1 -0
  750. package/lib/module/features/ota/environment.js +165 -0
  751. package/lib/module/features/ota/environment.js.map +1 -0
  752. package/lib/module/features/ota/geoCountry.js +86 -0
  753. package/lib/module/features/ota/geoCountry.js.map +1 -0
  754. package/lib/module/features/ota/retry.js +87 -0
  755. package/lib/module/features/ota/retry.js.map +1 -0
  756. package/lib/module/features/ota/signature.js +109 -0
  757. package/lib/module/features/ota/signature.js.map +1 -0
  758. package/lib/module/features/ota/useOtaUpdate.js +18 -15
  759. package/lib/module/features/ota/useOtaUpdate.js.map +1 -1
  760. package/lib/module/features/performance/PerformanceFeature.js +49 -35
  761. package/lib/module/features/performance/PerformanceFeature.js.map +1 -1
  762. package/lib/module/features/performance/collectors/AppLaunchCollector.js +13 -13
  763. package/lib/module/features/performance/collectors/AppLaunchCollector.js.map +1 -1
  764. package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js +32 -32
  765. package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js.map +1 -1
  766. package/lib/module/features/performance/collectors/CustomTraceCollector.js +13 -13
  767. package/lib/module/features/performance/collectors/CustomTraceCollector.js.map +1 -1
  768. package/lib/module/features/performance/collectors/FrameMetricsCollector.js +81 -21
  769. package/lib/module/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
  770. package/lib/module/features/performance/collectors/JsStallCollector.js +12 -12
  771. package/lib/module/features/performance/collectors/JsStallCollector.js.map +1 -1
  772. package/lib/module/features/performance/collectors/NetworkPerfCollector.js +10 -10
  773. package/lib/module/features/performance/collectors/NetworkPerfCollector.js.map +1 -1
  774. package/lib/module/features/performance/collectors/ScreenLoadCollector.js +11 -11
  775. package/lib/module/features/performance/collectors/ScreenLoadCollector.js.map +1 -1
  776. package/lib/module/features/performance/collectors/UiHangCollector.js +5 -5
  777. package/lib/module/features/performance/collectors/UiHangCollector.js.map +1 -1
  778. package/lib/module/features/performance/config.js +11 -11
  779. package/lib/module/features/performance/config.js.map +1 -1
  780. package/lib/module/features/performance/getNativePerformanceModule.js +11 -11
  781. package/lib/module/features/performance/getNativePerformanceModule.js.map +1 -1
  782. package/lib/module/features/performance/index.js +2 -2
  783. package/lib/module/features/performance/index.js.map +1 -1
  784. package/lib/module/features/performance/metrics/MetricsEngine.js +13 -13
  785. package/lib/module/features/performance/metrics/MetricsEngine.js.map +1 -1
  786. package/lib/module/features/performance/models.js +8 -8
  787. package/lib/module/features/performance/models.js.map +1 -1
  788. package/lib/module/features/performance/transport/PerformanceTransport.js +31 -6
  789. package/lib/module/features/performance/transport/PerformanceTransport.js.map +1 -1
  790. package/lib/module/features/profiler/ProfilerFeature.js +53 -53
  791. package/lib/module/features/profiler/ProfilerFeature.js.map +1 -1
  792. package/lib/module/features/profiler/config.js +15 -15
  793. package/lib/module/features/profiler/config.js.map +1 -1
  794. package/lib/module/features/profiler/contracts.js +22 -22
  795. package/lib/module/features/profiler/contracts.js.map +1 -1
  796. package/lib/module/features/profiler/index.js +4 -4
  797. package/lib/module/features/profiler/index.js.map +1 -1
  798. package/lib/module/features/profiler/models.js +44 -44
  799. package/lib/module/features/profiler/models.js.map +1 -1
  800. package/lib/module/features/profiler/transport/ProfilerTransport.js +9 -9
  801. package/lib/module/features/profiler/transport/ProfilerTransport.js.map +1 -1
  802. package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js +17 -17
  803. package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js.map +1 -1
  804. package/lib/module/features/replay/bridge/eventEmitter.js +8 -8
  805. package/lib/module/features/replay/bridge/eventEmitter.js.map +1 -1
  806. package/lib/module/features/replay/bridge/nativeModule.js +20 -20
  807. package/lib/module/features/replay/bridge/nativeModule.js.map +1 -1
  808. package/lib/module/features/replay/core/clock/clock.js +6 -6
  809. package/lib/module/features/replay/core/clock/clock.js.map +1 -1
  810. package/lib/module/features/replay/core/config/defaults.js +2 -2
  811. package/lib/module/features/replay/core/config/defaults.js.map +1 -1
  812. package/lib/module/features/replay/core/config/validator.js +5 -5
  813. package/lib/module/features/replay/core/config/validator.js.map +1 -1
  814. package/lib/module/features/replay/core/env/environmentDetector.js +10 -10
  815. package/lib/module/features/replay/core/env/environmentDetector.js.map +1 -1
  816. package/lib/module/features/replay/core/errors/safeCall.js +4 -4
  817. package/lib/module/features/replay/core/errors/safeCall.js.map +1 -1
  818. package/lib/module/features/replay/core/ids/sessionId.js +5 -5
  819. package/lib/module/features/replay/core/ids/sessionId.js.map +1 -1
  820. package/lib/module/features/replay/core/logger/logger.js +5 -5
  821. package/lib/module/features/replay/core/logger/logger.js.map +1 -1
  822. package/lib/module/features/replay/core/privacy/privacyTypes.js +4 -4
  823. package/lib/module/features/replay/core/privacy/privacyTypes.js.map +1 -1
  824. package/lib/module/features/replay/core/queue/boundedQueue.js +5 -5
  825. package/lib/module/features/replay/core/queue/boundedQueue.js.map +1 -1
  826. package/lib/module/features/replay/integrations/alert/alertInstrumentation.js +59 -59
  827. package/lib/module/features/replay/integrations/alert/alertInstrumentation.js.map +1 -1
  828. package/lib/module/features/replay/integrations/logs/consoleIntegration.js +19 -19
  829. package/lib/module/features/replay/integrations/logs/consoleIntegration.js.map +1 -1
  830. package/lib/module/features/replay/integrations/network/networkAdapter.js +30 -30
  831. package/lib/module/features/replay/integrations/network/networkAdapter.js.map +1 -1
  832. package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js +19 -19
  833. package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
  834. package/lib/module/features/replay/integrations/touch/ReplayRoot.js +16 -16
  835. package/lib/module/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
  836. package/lib/module/features/replay/pipeline/batching/batchManager.js +5 -5
  837. package/lib/module/features/replay/pipeline/batching/batchManager.js.map +1 -1
  838. package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js +5 -5
  839. package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js.map +1 -1
  840. package/lib/module/features/replay/pipeline/retry/retryPolicy.js +4 -4
  841. package/lib/module/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
  842. package/lib/module/features/replay/pipeline/transport/transportTypes.js +7 -7
  843. package/lib/module/features/replay/pipeline/transport/transportTypes.js.map +1 -1
  844. package/lib/module/features/replay/public/api.js +21 -21
  845. package/lib/module/features/replay/public/api.js.map +1 -1
  846. package/lib/module/features/replay/public/enums.js +5 -5
  847. package/lib/module/features/replay/public/enums.js.map +1 -1
  848. package/lib/module/features/replay/public/types.js.map +1 -1
  849. package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js +5 -5
  850. package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js.map +1 -1
  851. package/lib/module/features/replay/replay/frames/frameModels.js +4 -4
  852. package/lib/module/features/replay/replay/frames/frameModels.js.map +1 -1
  853. package/lib/module/features/replay/replay/session/sessionOrchestrator.js +10 -10
  854. package/lib/module/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
  855. package/lib/module/features/replay/replay/timeline/timelineModels.js +4 -4
  856. package/lib/module/features/replay/replay/timeline/timelineModels.js.map +1 -1
  857. package/lib/module/features/replay/transport/BackendReplayTransport.js +13 -13
  858. package/lib/module/features/replay/transport/BackendReplayTransport.js.map +1 -1
  859. package/lib/module/features/replay/transport/CompositeReplayTransport.js +8 -8
  860. package/lib/module/features/replay/transport/CompositeReplayTransport.js.map +1 -1
  861. package/lib/module/features/replay/transport/DesktopReplayTransport.js +14 -14
  862. package/lib/module/features/replay/transport/DesktopReplayTransport.js.map +1 -1
  863. package/lib/module/features/replay/transport/ReplayTransport.js.map +1 -1
  864. package/lib/module/features/session/BackendSessionAdapter.js +485 -164
  865. package/lib/module/features/session/BackendSessionAdapter.js.map +1 -1
  866. package/lib/module/features/session/DesktopSessionTransport.js +14 -14
  867. package/lib/module/features/session/DesktopSessionTransport.js.map +1 -1
  868. package/lib/module/features/session/JourneyEventPipeline.js +20 -19
  869. package/lib/module/features/session/JourneyEventPipeline.js.map +1 -1
  870. package/lib/module/features/session/ReplayCaptureManager.js +169 -123
  871. package/lib/module/features/session/ReplayCaptureManager.js.map +1 -1
  872. package/lib/module/features/session/ScrollTracker.js +17 -17
  873. package/lib/module/features/session/ScrollTracker.js.map +1 -1
  874. package/lib/module/features/session/SessionManager.js +185 -155
  875. package/lib/module/features/session/SessionManager.js.map +1 -1
  876. package/lib/module/features/session/SyncDecisionEngine.js +23 -23
  877. package/lib/module/features/session/SyncDecisionEngine.js.map +1 -1
  878. package/lib/module/features/session/index.js +5 -5
  879. package/lib/module/features/session/index.js.map +1 -1
  880. package/lib/module/features/session/nativeCapture.js +9 -10
  881. package/lib/module/features/session/nativeCapture.js.map +1 -1
  882. package/lib/module/features/session/outboxFrameCapture.js +18 -17
  883. package/lib/module/features/session/outboxFrameCapture.js.map +1 -1
  884. package/lib/module/features/session/sessionTypes.js +44 -44
  885. package/lib/module/features/session/sessionTypes.js.map +1 -1
  886. package/lib/module/features/skan/skanBridge.js +11 -11
  887. package/lib/module/features/skan/skanBridge.js.map +1 -1
  888. package/lib/module/features/skan/skanConversionManager.js +23 -23
  889. package/lib/module/features/skan/skanConversionManager.js.map +1 -1
  890. package/lib/module/index.js +19 -10
  891. package/lib/module/index.js.map +1 -1
  892. package/lib/module/integrations/fetch/fetchInterceptor.js +21 -21
  893. package/lib/module/integrations/fetch/fetchInterceptor.js.map +1 -1
  894. package/lib/module/integrations/navigation/screenTracker.js.map +1 -1
  895. package/lib/module/integrations/network/bodyCapture.js +69 -69
  896. package/lib/module/integrations/network/bodyCapture.js.map +1 -1
  897. package/lib/module/integrations/xhr/xhrInterceptor.js +24 -24
  898. package/lib/module/integrations/xhr/xhrInterceptor.js.map +1 -1
  899. package/lib/module/metro/index.js +37 -37
  900. package/lib/module/metro/index.js.map +1 -1
  901. package/lib/module/metro/optionalDependencyStub.js +11 -11
  902. package/lib/module/metro/optionalDependencyStub.js.map +1 -1
  903. package/lib/module/metro/optionalModules.js +16 -16
  904. package/lib/module/metro/optionalModules.js.map +1 -1
  905. package/lib/module/pipeline/dispatcher/dispatcher.js.map +1 -1
  906. package/lib/module/pipeline/envelope/envelope.js.map +1 -1
  907. package/lib/module/pipeline/envelope/serializer.js.map +1 -1
  908. package/lib/module/pipeline/processors/dedupe.js.map +1 -1
  909. package/lib/module/pipeline/processors/enrich.js.map +1 -1
  910. package/lib/module/pipeline/processors/sampling.js.map +1 -1
  911. package/lib/module/pipeline/processors/sanitize.js.map +1 -1
  912. package/lib/module/pipeline/queue/flushQueue.js +4 -4
  913. package/lib/module/pipeline/queue/flushQueue.js.map +1 -1
  914. package/lib/module/pipeline/queue/memoryQueue.js.map +1 -1
  915. package/lib/module/pipeline/queue/persistentQueue.js +80 -80
  916. package/lib/module/pipeline/queue/persistentQueue.js.map +1 -1
  917. package/lib/module/pipeline/queue/queuePolicy.js.map +1 -1
  918. package/lib/module/pipeline/scheduler/flushScheduler.js.map +1 -1
  919. package/lib/module/pipeline/scheduler/retryPolicy.js +2 -2
  920. package/lib/module/pipeline/scheduler/retryPolicy.js.map +1 -1
  921. package/lib/module/public/ScaleBunErrorBoundary.js +70 -0
  922. package/lib/module/public/ScaleBunErrorBoundary.js.map +1 -0
  923. package/lib/module/public/ScaleBunFacade.js +424 -276
  924. package/lib/module/public/ScaleBunFacade.js.map +1 -1
  925. package/lib/module/public/ScaleBunProvider.js +3 -3
  926. package/lib/module/public/ScaleBunProvider.js.map +1 -1
  927. package/lib/module/public/typedTracker.js +36 -36
  928. package/lib/module/public/typedTracker.js.map +1 -1
  929. package/lib/module/public/types.js.map +1 -1
  930. package/lib/module/push/PushManager.js +21 -21
  931. package/lib/module/push/PushManager.js.map +1 -1
  932. package/lib/module/push/adapters/ManualAdapter.js +14 -14
  933. package/lib/module/push/adapters/ManualAdapter.js.map +1 -1
  934. package/lib/module/push/adapters/NativeBridgeAdapter.js +17 -17
  935. package/lib/module/push/adapters/NativeBridgeAdapter.js.map +1 -1
  936. package/lib/module/push/adapters/NoopAdapter.js +5 -5
  937. package/lib/module/push/adapters/NoopAdapter.js.map +1 -1
  938. package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js +17 -17
  939. package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js.map +1 -1
  940. package/lib/module/push/adapters/loadMessaging.js +12 -12
  941. package/lib/module/push/adapters/loadMessaging.js.map +1 -1
  942. package/lib/module/push/adapters/loadNotifee.js +12 -12
  943. package/lib/module/push/adapters/loadNotifee.js.map +1 -1
  944. package/lib/module/push/adapters/selectAdapter.js +14 -14
  945. package/lib/module/push/adapters/selectAdapter.js.map +1 -1
  946. package/lib/module/push/detect/capabilities.js +19 -19
  947. package/lib/module/push/detect/capabilities.js.map +1 -1
  948. package/lib/module/push/index.js +3 -3
  949. package/lib/module/push/index.js.map +1 -1
  950. package/lib/module/push/native/nativeNotifications.js +32 -32
  951. package/lib/module/push/native/nativeNotifications.js.map +1 -1
  952. package/lib/module/push/types.js.map +1 -1
  953. package/lib/module/specs/NativeReplaySdk.js +18 -18
  954. package/lib/module/specs/NativeReplaySdk.js.map +1 -1
  955. package/lib/module/specs/NativeScaleBunCrash.js +19 -19
  956. package/lib/module/specs/NativeScaleBunCrash.js.map +1 -1
  957. package/lib/module/specs/NativeScaleBunInstallReferrer.js +14 -14
  958. package/lib/module/specs/NativeScaleBunInstallReferrer.js.map +1 -1
  959. package/lib/module/specs/NativeScaleBunOta.js +21 -21
  960. package/lib/module/specs/NativeScaleBunOta.js.map +1 -1
  961. package/lib/module/specs/NativeScaleBunPerformance.js +15 -15
  962. package/lib/module/specs/NativeScaleBunPerformance.js.map +1 -1
  963. package/lib/module/specs/NativeScaleBunProfiler.js +16 -16
  964. package/lib/module/specs/NativeScaleBunProfiler.js.map +1 -1
  965. package/lib/module/specs/NativeScaleBunStorage.js +29 -29
  966. package/lib/module/specs/NativeScaleBunStorage.js.map +1 -1
  967. package/lib/module/storage/StorageBackend.js +83 -83
  968. package/lib/module/storage/StorageBackend.js.map +1 -1
  969. package/lib/module/storage/db/sqlite.js.map +1 -1
  970. package/lib/module/storage/files/fileStore.js.map +1 -1
  971. package/lib/module/transport/auth/sdkSession.js.map +1 -1
  972. package/lib/module/transport/backoff/exponentialJitter.js +2 -2
  973. package/lib/module/transport/backoff/exponentialJitter.js.map +1 -1
  974. package/lib/module/transport/http/endpoints.js.map +1 -1
  975. package/lib/module/transport/http/httpClient.js +3 -3
  976. package/lib/module/transport/http/httpClient.js.map +1 -1
  977. package/lib/module/transport/rateLimit/retryAfter.js.map +1 -1
  978. package/lib/module/transport/signing/requestSigner.js.map +1 -1
  979. package/lib/module/vendor/protocol/index.js +74 -74
  980. package/lib/module/vendor/protocol/index.js.map +1 -1
  981. package/lib/module/vendor/protocol/internal/validation.js +23 -23
  982. package/lib/module/vendor/protocol/internal/validation.js.map +1 -1
  983. package/lib/module/vendor/sdk-contracts/bridge.js.map +1 -1
  984. package/lib/module/vendor/sdk-contracts/config.js.map +1 -1
  985. package/lib/module/vendor/sdk-contracts/events.js.map +1 -1
  986. package/lib/module/vendor/sdk-contracts/features.js.map +1 -1
  987. package/lib/module/vendor/sdk-contracts/index.js.map +1 -1
  988. package/lib/module/vendor/sdk-contracts/platform.js.map +1 -1
  989. package/lib/module/vendor/sdk-contracts/session-boundary.js.map +1 -1
  990. package/lib/module/vendor/sdk-contracts/session.js.map +1 -1
  991. package/lib/module/vendor/vendor.manifest +10 -10
  992. package/lib/typescript/analytics/EventTracker.d.ts +20 -0
  993. package/lib/typescript/analytics/EventTracker.d.ts.map +1 -1
  994. package/lib/typescript/bootstrap/SDKBootstrapper.d.ts.map +1 -1
  995. package/lib/typescript/core/config/schema.d.ts +1 -1
  996. package/lib/typescript/core/config/schema.d.ts.map +1 -1
  997. package/lib/typescript/core/context/device.d.ts +46 -0
  998. package/lib/typescript/core/context/device.d.ts.map +1 -1
  999. package/lib/typescript/debug/replayWiring.d.ts.map +1 -1
  1000. package/lib/typescript/features/bugreport/BugReportFeature.d.ts +59 -0
  1001. package/lib/typescript/features/bugreport/BugReportFeature.d.ts.map +1 -0
  1002. package/lib/typescript/features/bugreport/buildPayload.d.ts +51 -0
  1003. package/lib/typescript/features/bugreport/buildPayload.d.ts.map +1 -0
  1004. package/lib/typescript/features/crash/CrashFeature.d.ts.map +1 -1
  1005. package/lib/typescript/features/crash/CrashReporter.d.ts +20 -1
  1006. package/lib/typescript/features/crash/CrashReporter.d.ts.map +1 -1
  1007. package/lib/typescript/features/crash/capture.d.ts +21 -2
  1008. package/lib/typescript/features/crash/capture.d.ts.map +1 -1
  1009. package/lib/typescript/features/crash/nativeCrashBridge.d.ts +16 -3
  1010. package/lib/typescript/features/crash/nativeCrashBridge.d.ts.map +1 -1
  1011. package/lib/typescript/features/crash/rejectionHandler.d.ts +46 -0
  1012. package/lib/typescript/features/crash/rejectionHandler.d.ts.map +1 -0
  1013. package/lib/typescript/features/engage/EngagePromptProvider.d.ts.map +1 -1
  1014. package/lib/typescript/features/engage/EngagePromptView.d.ts.map +1 -1
  1015. package/lib/typescript/features/engage/engageThrottle.d.ts +24 -4
  1016. package/lib/typescript/features/engage/engageThrottle.d.ts.map +1 -1
  1017. package/lib/typescript/features/engage/engageTriggerEngine.d.ts.map +1 -1
  1018. package/lib/typescript/features/engage/engageTypes.d.ts +21 -0
  1019. package/lib/typescript/features/engage/engageTypes.d.ts.map +1 -1
  1020. package/lib/typescript/features/journey/ScaleBunDebugRoot.d.ts.map +1 -1
  1021. package/lib/typescript/features/navigation/AutoScreenDetector.d.ts +9 -0
  1022. package/lib/typescript/features/navigation/AutoScreenDetector.d.ts.map +1 -1
  1023. package/lib/typescript/features/ota/OtaOrchestrator.d.ts +75 -3
  1024. package/lib/typescript/features/ota/OtaOrchestrator.d.ts.map +1 -1
  1025. package/lib/typescript/features/ota/OtaTypes.d.ts +42 -0
  1026. package/lib/typescript/features/ota/OtaTypes.d.ts.map +1 -1
  1027. package/lib/typescript/features/ota/deviceAttributes.d.ts +18 -0
  1028. package/lib/typescript/features/ota/deviceAttributes.d.ts.map +1 -0
  1029. package/lib/typescript/features/ota/environment.d.ts +99 -0
  1030. package/lib/typescript/features/ota/environment.d.ts.map +1 -0
  1031. package/lib/typescript/features/ota/geoCountry.d.ts +14 -0
  1032. package/lib/typescript/features/ota/geoCountry.d.ts.map +1 -0
  1033. package/lib/typescript/features/ota/retry.d.ts +53 -0
  1034. package/lib/typescript/features/ota/retry.d.ts.map +1 -0
  1035. package/lib/typescript/features/ota/signature.d.ts +66 -0
  1036. package/lib/typescript/features/ota/signature.d.ts.map +1 -0
  1037. package/lib/typescript/features/ota/useOtaUpdate.d.ts +20 -2
  1038. package/lib/typescript/features/ota/useOtaUpdate.d.ts.map +1 -1
  1039. package/lib/typescript/features/performance/PerformanceFeature.d.ts +0 -1
  1040. package/lib/typescript/features/performance/PerformanceFeature.d.ts.map +1 -1
  1041. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts +33 -0
  1042. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts.map +1 -1
  1043. package/lib/typescript/features/performance/transport/PerformanceTransport.d.ts.map +1 -1
  1044. package/lib/typescript/features/session/BackendSessionAdapter.d.ts +135 -4
  1045. package/lib/typescript/features/session/BackendSessionAdapter.d.ts.map +1 -1
  1046. package/lib/typescript/features/session/JourneyEventPipeline.d.ts +2 -0
  1047. package/lib/typescript/features/session/JourneyEventPipeline.d.ts.map +1 -1
  1048. package/lib/typescript/features/session/ReplayCaptureManager.d.ts +38 -1
  1049. package/lib/typescript/features/session/ReplayCaptureManager.d.ts.map +1 -1
  1050. package/lib/typescript/features/session/SessionManager.d.ts.map +1 -1
  1051. package/lib/typescript/features/session/nativeCapture.d.ts +2 -1
  1052. package/lib/typescript/features/session/nativeCapture.d.ts.map +1 -1
  1053. package/lib/typescript/features/session/outboxFrameCapture.d.ts.map +1 -1
  1054. package/lib/typescript/features/session/sessionTypes.d.ts +20 -3
  1055. package/lib/typescript/features/session/sessionTypes.d.ts.map +1 -1
  1056. package/lib/typescript/index.d.ts +7 -0
  1057. package/lib/typescript/index.d.ts.map +1 -1
  1058. package/lib/typescript/public/ScaleBunErrorBoundary.d.ts +44 -0
  1059. package/lib/typescript/public/ScaleBunErrorBoundary.d.ts.map +1 -0
  1060. package/lib/typescript/public/ScaleBunFacade.d.ts +58 -0
  1061. package/lib/typescript/public/ScaleBunFacade.d.ts.map +1 -1
  1062. package/lib/typescript/specs/NativeScaleBunCrash.d.ts +14 -0
  1063. package/lib/typescript/specs/NativeScaleBunCrash.d.ts.map +1 -1
  1064. package/lib/typescript/specs/NativeScaleBunOta.d.ts +11 -0
  1065. package/lib/typescript/specs/NativeScaleBunOta.d.ts.map +1 -1
  1066. package/lib/typescript/vendor/protocol/index.d.ts +17 -17
  1067. package/package.json +12 -14
  1068. package/react-native.config.js +24 -24
  1069. package/scalebun-react-native.podspec +37 -37
  1070. package/src/analytics/EventTracker.ts +489 -462
  1071. package/src/analytics/automaticEvents.ts +105 -105
  1072. package/src/analytics/batching.ts +54 -54
  1073. package/src/analytics/eventLane.ts +26 -26
  1074. package/src/bootstrap/FeatureRegistry.ts +81 -81
  1075. package/src/bootstrap/SDKBootstrapper.ts +610 -585
  1076. package/src/bucketing/fnv1a32.ts +40 -40
  1077. package/src/compat/codepush.ts +118 -118
  1078. package/src/config/ConfigManager.ts +167 -167
  1079. package/src/config/configTypes.ts +32 -32
  1080. package/src/core/architecture.ts +39 -39
  1081. package/src/core/clock/now.ts +6 -6
  1082. package/src/core/config/schema.ts +239 -231
  1083. package/src/core/constants/endpoints.ts +9 -9
  1084. package/src/core/constants/timings.ts +23 -23
  1085. package/src/core/constants/version.ts +6 -6
  1086. package/src/core/context/device.ts +146 -0
  1087. package/src/core/context/user.ts +26 -26
  1088. package/src/core/contracts/IFeature.ts +53 -53
  1089. package/src/core/di/container.ts +26 -26
  1090. package/src/core/encoding/base64.ts +46 -46
  1091. package/src/core/id/deviceId.ts +51 -51
  1092. package/src/core/lifecycle/appLifecycle.ts +33 -33
  1093. package/src/core/lifecycle/crashSafe.ts +29 -29
  1094. package/src/core/logger/errorClassification.ts +108 -108
  1095. package/src/core/logger/internalLogger.ts +65 -65
  1096. package/src/crypto/hmacSha256.ts +106 -106
  1097. package/src/debug/bootstrap.ts +366 -366
  1098. package/src/debug/commands.ts +597 -597
  1099. package/src/debug/configBuilder.ts +56 -56
  1100. package/src/debug/exportBridge.ts +153 -153
  1101. package/src/debug/hostResolver.ts +34 -34
  1102. package/src/debug/index.ts +25 -25
  1103. package/src/debug/metrics.ts +29 -29
  1104. package/src/debug/perf.ts +212 -212
  1105. package/src/debug/perfWiring.ts +119 -119
  1106. package/src/debug/protocol.ts +58 -58
  1107. package/src/debug/redaction.ts +290 -290
  1108. package/src/debug/replayWiring.ts +148 -147
  1109. package/src/debug/screenTracking.ts +55 -55
  1110. package/src/debug/sessionWiring.ts +59 -59
  1111. package/src/debug/stream.ts +561 -561
  1112. package/src/debug/transport.ts +439 -439
  1113. package/src/features/bugreport/BugReportFeature.ts +128 -0
  1114. package/src/features/bugreport/buildPayload.ts +116 -0
  1115. package/src/features/crash/CrashFeature.ts +71 -52
  1116. package/src/features/crash/CrashReporter.ts +179 -140
  1117. package/src/features/crash/NativeCrashFeature.ts +42 -42
  1118. package/src/features/crash/capture.ts +48 -21
  1119. package/src/features/crash/globalHandler.ts +39 -39
  1120. package/src/features/crash/index.ts +8 -8
  1121. package/src/features/crash/nativeCrashBridge.ts +266 -132
  1122. package/src/features/crash/rejectionHandler.ts +134 -0
  1123. package/src/features/engage/EngageAnchor.tsx +159 -159
  1124. package/src/features/engage/EngageArchetypeRenderers.tsx +3716 -3716
  1125. package/src/features/engage/EngageInAppView.tsx +2678 -2678
  1126. package/src/features/engage/EngageInlinePlacement.tsx +169 -169
  1127. package/src/features/engage/EngagePromptProvider.tsx +1318 -1270
  1128. package/src/features/engage/EngagePromptView.tsx +1400 -1364
  1129. package/src/features/engage/EngageTransport.ts +668 -668
  1130. package/src/features/engage/EngageVariantContent.tsx +1483 -1483
  1131. package/src/features/engage/__test-support__/reactNativeStub.js +40 -40
  1132. package/src/features/engage/attachmentCapture.ts +45 -45
  1133. package/src/features/engage/captureVoiceAttachment.ts +81 -81
  1134. package/src/features/engage/engageCoachmarkTour.ts +120 -120
  1135. package/src/features/engage/engageGameLogic.ts +347 -347
  1136. package/src/features/engage/engageMediaSizing.ts +76 -76
  1137. package/src/features/engage/engageMultiStepSheet.ts +53 -53
  1138. package/src/features/engage/engageOutcome.ts +157 -157
  1139. package/src/features/engage/engagePushTokenBridge.ts +84 -84
  1140. package/src/features/engage/engageShakeBridge.ts +67 -67
  1141. package/src/features/engage/engageSignals.ts +40 -40
  1142. package/src/features/engage/engageStoreReviewBridge.ts +48 -48
  1143. package/src/features/engage/engageTestSeenStore.ts +95 -95
  1144. package/src/features/engage/engageThrottle.ts +478 -440
  1145. package/src/features/engage/engageTriggerEngine.ts +350 -335
  1146. package/src/features/engage/engageTypes.ts +712 -691
  1147. package/src/features/engage/engageVariantResolver.ts +364 -364
  1148. package/src/features/engage/engageWindowInsets.ts +108 -108
  1149. package/src/features/engage/gestureTriggerDetector.ts +83 -83
  1150. package/src/features/engage/transcription/TranscriptionProvider.ts +68 -68
  1151. package/src/features/install-referrer/installReferrer.ts +112 -112
  1152. package/src/features/journey/ScaleBunDebugRoot.tsx +727 -726
  1153. package/src/features/journey/ScaleBunFlatList.tsx +39 -39
  1154. package/src/features/journey/ScaleBunImpression.tsx +109 -109
  1155. package/src/features/journey/ScaleBunScrollView.tsx +72 -72
  1156. package/src/features/journey/ScaleBunSectionList.tsx +39 -39
  1157. package/src/features/journey/calibrationContext.ts +53 -53
  1158. package/src/features/journey/gestureBuffer.ts +59 -59
  1159. package/src/features/journey/gestureDetector.ts +162 -162
  1160. package/src/features/journey/impression.ts +92 -92
  1161. package/src/features/journey/journeyManager.ts +466 -466
  1162. package/src/features/journey/journeyTypes.ts +215 -215
  1163. package/src/features/journey/navDetector.ts +149 -149
  1164. package/src/features/journey/screenshotHelper.ts +137 -137
  1165. package/src/features/journey/targetRegistry.ts +43 -43
  1166. package/src/features/journey/touchTarget.ts +128 -128
  1167. package/src/features/navigation/AutoScreenDetector.ts +503 -448
  1168. package/src/features/network/NetworkFeature.ts +144 -144
  1169. package/src/features/network/index.ts +31 -31
  1170. package/src/features/ota/OtaEventEmitter.ts +128 -128
  1171. package/src/features/ota/OtaOrchestrator.ts +963 -323
  1172. package/src/features/ota/OtaTypes.ts +118 -62
  1173. package/src/features/ota/deviceAttributes.ts +46 -0
  1174. package/src/features/ota/environment.ts +199 -0
  1175. package/src/features/ota/geoCountry.ts +85 -0
  1176. package/src/features/ota/retry.ts +123 -0
  1177. package/src/features/ota/signature.ts +123 -0
  1178. package/src/features/ota/useOtaUpdate.ts +152 -134
  1179. package/src/features/performance/PerformanceFeature.ts +597 -584
  1180. package/src/features/performance/collectors/AppLaunchCollector.ts +117 -117
  1181. package/src/features/performance/collectors/AutoScreenLoadCollector.ts +258 -258
  1182. package/src/features/performance/collectors/CustomTraceCollector.ts +116 -116
  1183. package/src/features/performance/collectors/FrameMetricsCollector.ts +181 -119
  1184. package/src/features/performance/collectors/JsStallCollector.ts +165 -165
  1185. package/src/features/performance/collectors/NetworkPerfCollector.ts +69 -69
  1186. package/src/features/performance/collectors/ScreenLoadCollector.ts +95 -95
  1187. package/src/features/performance/collectors/UiHangCollector.ts +98 -98
  1188. package/src/features/performance/config.ts +136 -136
  1189. package/src/features/performance/getNativePerformanceModule.ts +38 -38
  1190. package/src/features/performance/index.ts +28 -28
  1191. package/src/features/performance/metrics/MetricsEngine.ts +152 -152
  1192. package/src/features/performance/models.ts +235 -235
  1193. package/src/features/performance/transport/PerformanceTransport.ts +161 -143
  1194. package/src/features/profiler/ProfilerFeature.ts +661 -661
  1195. package/src/features/profiler/config.ts +230 -230
  1196. package/src/features/profiler/contracts.ts +176 -176
  1197. package/src/features/profiler/index.ts +45 -45
  1198. package/src/features/profiler/models.ts +430 -430
  1199. package/src/features/profiler/transport/ProfilerTransport.ts +93 -93
  1200. package/src/features/replay/bridge/adapters/bridgeAdapter.ts +230 -230
  1201. package/src/features/replay/bridge/eventEmitter.ts +176 -176
  1202. package/src/features/replay/bridge/nativeModule.ts +241 -241
  1203. package/src/features/replay/core/clock/clock.ts +38 -38
  1204. package/src/features/replay/core/config/defaults.ts +66 -66
  1205. package/src/features/replay/core/config/validator.ts +113 -113
  1206. package/src/features/replay/core/env/environmentDetector.ts +21 -21
  1207. package/src/features/replay/core/errors/safeCall.ts +34 -34
  1208. package/src/features/replay/core/ids/sessionId.ts +44 -44
  1209. package/src/features/replay/core/logger/logger.ts +40 -40
  1210. package/src/features/replay/core/privacy/privacyTypes.ts +41 -41
  1211. package/src/features/replay/core/queue/boundedQueue.ts +71 -71
  1212. package/src/features/replay/integrations/alert/alertInstrumentation.ts +277 -277
  1213. package/src/features/replay/integrations/logs/consoleIntegration.ts +116 -116
  1214. package/src/features/replay/integrations/network/networkAdapter.ts +128 -128
  1215. package/src/features/replay/integrations/react-navigation/navigationIntegration.ts +89 -89
  1216. package/src/features/replay/integrations/touch/ReplayRoot.tsx +114 -114
  1217. package/src/features/replay/pipeline/batching/batchManager.ts +133 -133
  1218. package/src/features/replay/pipeline/envelope/envelopeBuilder.ts +66 -66
  1219. package/src/features/replay/pipeline/retry/retryPolicy.ts +62 -62
  1220. package/src/features/replay/pipeline/transport/transportTypes.ts +85 -85
  1221. package/src/features/replay/public/api.ts +364 -364
  1222. package/src/features/replay/public/enums.ts +78 -78
  1223. package/src/features/replay/public/types.ts +297 -297
  1224. package/src/features/replay/replay/breadcrumbs/breadcrumbCollector.ts +115 -115
  1225. package/src/features/replay/replay/frames/frameModels.ts +45 -45
  1226. package/src/features/replay/replay/session/sessionOrchestrator.ts +286 -286
  1227. package/src/features/replay/replay/timeline/timelineModels.ts +129 -129
  1228. package/src/features/replay/transport/BackendReplayTransport.ts +215 -215
  1229. package/src/features/replay/transport/CompositeReplayTransport.ts +82 -82
  1230. package/src/features/replay/transport/DesktopReplayTransport.ts +140 -140
  1231. package/src/features/replay/transport/ReplayTransport.ts +84 -84
  1232. package/src/features/session/BackendSessionAdapter.ts +1568 -1233
  1233. package/src/features/session/DesktopSessionTransport.ts +128 -128
  1234. package/src/features/session/JourneyEventPipeline.ts +276 -273
  1235. package/src/features/session/ReplayCaptureManager.ts +998 -946
  1236. package/src/features/session/ScrollTracker.ts +166 -166
  1237. package/src/features/session/SessionManager.ts +1248 -1209
  1238. package/src/features/session/SyncDecisionEngine.ts +117 -117
  1239. package/src/features/session/index.ts +88 -88
  1240. package/src/features/session/nativeCapture.ts +39 -38
  1241. package/src/features/session/outboxFrameCapture.ts +75 -74
  1242. package/src/features/session/sessionTypes.ts +514 -491
  1243. package/src/features/skan/skanBridge.ts +61 -61
  1244. package/src/features/skan/skanConversionManager.ts +173 -173
  1245. package/src/index.ts +200 -191
  1246. package/src/integrations/fetch/fetchInterceptor.ts +182 -182
  1247. package/src/integrations/network/bodyCapture.ts +328 -328
  1248. package/src/integrations/xhr/xhrInterceptor.ts +231 -231
  1249. package/src/metro/index.ts +164 -164
  1250. package/src/metro/optionalDependencyStub.ts +13 -13
  1251. package/src/metro/optionalModules.ts +27 -27
  1252. package/src/pipeline/dispatcher/dispatcher.ts +22 -22
  1253. package/src/pipeline/envelope/envelope.ts +31 -31
  1254. package/src/pipeline/envelope/serializer.ts +14 -14
  1255. package/src/pipeline/processors/enrich.ts +11 -11
  1256. package/src/pipeline/processors/sanitize.ts +23 -23
  1257. package/src/pipeline/queue/flushQueue.ts +144 -144
  1258. package/src/pipeline/queue/memoryQueue.ts +31 -31
  1259. package/src/pipeline/queue/persistentQueue.ts +414 -414
  1260. package/src/pipeline/scheduler/flushScheduler.ts +47 -47
  1261. package/src/pipeline/scheduler/retryPolicy.ts +8 -8
  1262. package/src/public/ScaleBunErrorBoundary.tsx +79 -0
  1263. package/src/public/ScaleBunFacade.ts +1630 -1479
  1264. package/src/public/ScaleBunProvider.tsx +91 -91
  1265. package/src/public/typedTracker.ts +123 -123
  1266. package/src/public/types.ts +312 -312
  1267. package/src/push/PushManager.ts +318 -318
  1268. package/src/push/adapters/ManualAdapter.ts +100 -100
  1269. package/src/push/adapters/NativeBridgeAdapter.ts +142 -142
  1270. package/src/push/adapters/NoopAdapter.ts +46 -46
  1271. package/src/push/adapters/RNFirebaseMessagingAdapter.ts +271 -271
  1272. package/src/push/adapters/loadMessaging.ts +24 -24
  1273. package/src/push/adapters/loadNotifee.ts +29 -29
  1274. package/src/push/adapters/selectAdapter.ts +176 -176
  1275. package/src/push/detect/capabilities.ts +124 -124
  1276. package/src/push/index.ts +22 -22
  1277. package/src/push/native/nativeNotifications.ts +216 -216
  1278. package/src/push/types.ts +159 -159
  1279. package/src/specs/NativeReplaySdk.ts +99 -99
  1280. package/src/specs/NativeScaleBunCrash.ts +52 -36
  1281. package/src/specs/NativeScaleBunInstallReferrer.ts +29 -29
  1282. package/src/specs/NativeScaleBunOta.ts +97 -85
  1283. package/src/specs/NativeScaleBunPerformance.ts +34 -34
  1284. package/src/specs/NativeScaleBunProfiler.ts +41 -41
  1285. package/src/specs/NativeScaleBunStorage.ts +59 -59
  1286. package/src/storage/StorageBackend.ts +272 -272
  1287. package/src/transport/auth/sdkSession.ts +27 -27
  1288. package/src/transport/backoff/exponentialJitter.ts +9 -9
  1289. package/src/transport/http/endpoints.ts +33 -33
  1290. package/src/transport/http/httpClient.ts +73 -73
  1291. package/src/vendor/protocol/index.ts +391 -391
  1292. package/src/vendor/protocol/internal/validation.ts +497 -497
  1293. package/src/vendor/sdk-contracts/bridge.ts +162 -162
  1294. package/src/vendor/sdk-contracts/config.ts +192 -192
  1295. package/src/vendor/sdk-contracts/events.ts +50 -50
  1296. package/src/vendor/sdk-contracts/features.ts +42 -42
  1297. package/src/vendor/sdk-contracts/index.ts +98 -98
  1298. package/src/vendor/sdk-contracts/platform.ts +42 -42
  1299. package/src/vendor/sdk-contracts/session-boundary.ts +55 -55
  1300. package/src/vendor/sdk-contracts/session.ts +225 -225
  1301. package/src/vendor/vendor.manifest +10 -10
  1302. package/android/build/generated/source/buildConfig/debug/com/scalebun/sdk/BuildConfig.java +0 -12
  1303. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeReplaySdkSpec.java +0 -208
  1304. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunCrashSpec.java +0 -46
  1305. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.java +0 -38
  1306. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunOtaSpec.java +0 -63
  1307. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunPerformanceSpec.java +0 -70
  1308. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunProfilerSpec.java +0 -96
  1309. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunStorageSpec.java +0 -50
  1310. package/android/build/generated/source/codegen/jni/CMakeLists.txt +0 -28
  1311. package/android/build/generated/source/codegen/jni/ScaleBunSpec-generated.cpp +0 -554
  1312. package/android/build/generated/source/codegen/jni/ScaleBunSpec.h +0 -79
  1313. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ComponentDescriptors.cpp +0 -22
  1314. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ComponentDescriptors.h +0 -24
  1315. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/EventEmitters.cpp +0 -16
  1316. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/EventEmitters.h +0 -17
  1317. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/Props.cpp +0 -19
  1318. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/Props.h +0 -18
  1319. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ScaleBunSpecJSI-generated.cpp +0 -595
  1320. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ScaleBunSpecJSI.h +0 -1070
  1321. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ShadowNodes.cpp +0 -17
  1322. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ShadowNodes.h +0 -23
  1323. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/States.cpp +0 -16
  1324. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/States.h +0 -20
  1325. package/android/build/generated/source/codegen/schema.json +0 -1
  1326. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -20
  1327. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  1328. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  1329. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  1330. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  1331. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  1332. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  1333. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
  1334. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  1335. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  1336. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  1337. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  1338. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
  1339. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/sdk/BuildConfig.class +0 -0
  1340. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeReplaySdkSpec.class +0 -0
  1341. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunCrashSpec.class +0 -0
  1342. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.class +0 -0
  1343. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunOtaSpec.class +0 -0
  1344. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunPerformanceSpec.class +0 -0
  1345. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunProfilerSpec.class +0 -0
  1346. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunStorageSpec.class +0 -0
  1347. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
  1348. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -24
  1349. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -20
  1350. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  1351. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  1352. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
  1353. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/CrashStorage.class +0 -0
  1354. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/NativeCrashHandler$Companion.class +0 -0
  1355. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/NativeCrashHandler.class +0 -0
  1356. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/ANRWatchdog$HangInfo.class +0 -0
  1357. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/ANRWatchdog.class +0 -0
  1358. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$AppStartInfo.class +0 -0
  1359. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$Breakdown.class +0 -0
  1360. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$start$1.class +0 -0
  1361. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector.class +0 -0
  1362. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$Companion.class +0 -0
  1363. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$FrameMetricsSnapshot.class +0 -0
  1364. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$start$1.class +0 -0
  1365. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$startChoreographerFallback$1.class +0 -0
  1366. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector.class +0 -0
  1367. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/PerformanceCore$Listener.class +0 -0
  1368. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/PerformanceCore.class +0 -0
  1369. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerModule$Companion.class +0 -0
  1370. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerModule.class +0 -0
  1371. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerPackage.class +0 -0
  1372. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerSpec.class +0 -0
  1373. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/CpuCollector.class +0 -0
  1374. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/IncidentDetector.class +0 -0
  1375. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/MemoryCollector.class +0 -0
  1376. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/RenderCollector$frameCallback$1.class +0 -0
  1377. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/RenderCollector.class +0 -0
  1378. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/SamplerScheduler.class +0 -0
  1379. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/SamplerSchedulerKt.class +0 -0
  1380. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/ThreadCollector$WhenMappings.class +0 -0
  1381. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/ThreadCollector.class +0 -0
  1382. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule$Companion.class +0 -0
  1383. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule$registerConnectivity$cb$1.class +0 -0
  1384. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule.class +0 -0
  1385. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkPackage.class +0 -0
  1386. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkSpec.class +0 -0
  1387. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/CaptureReason$Companion.class +0 -0
  1388. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/CaptureReason.class +0 -0
  1389. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureManager$startFrequencyTimer$1.class +0 -0
  1390. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureManager.class +0 -0
  1391. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$Companion.class +0 -0
  1392. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$FrameRequest.class +0 -0
  1393. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler.class +0 -0
  1394. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$Companion.class +0 -0
  1395. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$SettleWatch.class +0 -0
  1396. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$StabilityWatch.class +0 -0
  1397. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector.class +0 -0
  1398. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/CaptureMode$Companion.class +0 -0
  1399. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/CaptureMode.class +0 -0
  1400. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayConfig$Companion.class +0 -0
  1401. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayConfig.class +0 -0
  1402. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayLogger.class +0 -0
  1403. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ScreenshotQuality$Companion.class +0 -0
  1404. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ScreenshotQuality.class +0 -0
  1405. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/SessionIdGenerator.class +0 -0
  1406. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/SessionState.class +0 -0
  1407. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/ReplayFrame.class +0 -0
  1408. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/ReplaySession.class +0 -0
  1409. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/TimelineEvent.class +0 -0
  1410. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox$Companion.class +0 -0
  1411. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox$enforceLimits$lambda$37$$inlined$sortedBy$1.class +0 -0
  1412. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox.class +0 -0
  1413. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$NetworkError.class +0 -0
  1414. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$Response.class +0 -0
  1415. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult.class +0 -0
  1416. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$Outcome.class +0 -0
  1417. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$WhenMappings.class +0 -0
  1418. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader.class +0 -0
  1419. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.class +0 -0
  1420. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/session/SessionManager.class +0 -0
  1421. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/storage/ReplayStorage$enforceStorageLimit$$inlined$sortedBy$1.class +0 -0
  1422. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/storage/ReplayStorage.class +0 -0
  1423. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/timeline/TimelineCollector.class +0 -0
  1424. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/DialogTouchObserver$start$runnable$1.class +0 -0
  1425. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/DialogTouchObserver.class +0 -0
  1426. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/InteractionTracker.class +0 -0
  1427. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/NativeTouchInterceptor.class +0 -0
  1428. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/ScreenTracker.class +0 -0
  1429. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport$UploadResult.class +0 -0
  1430. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport$upload$2.class +0 -0
  1431. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport.class +0 -0
  1432. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder$Companion.class +0 -0
  1433. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder$Result.class +0 -0
  1434. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder.class +0 -0
  1435. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber$TranscriptResult.class +0 -0
  1436. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber$listener$1.class +0 -0
  1437. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber.class +0 -0
  1438. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ScaleBunPackage$Companion.class +0 -0
  1439. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ScaleBunPackage.class +0 -0
  1440. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashModule$Companion.class +0 -0
  1441. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashModule.class +0 -0
  1442. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashPackage.class +0 -0
  1443. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashSpec.class +0 -0
  1444. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$Companion.class +0 -0
  1445. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$WindowInsetEdges.class +0 -0
  1446. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$shakeListener$1.class +0 -0
  1447. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule.class +0 -0
  1448. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngagePackage.class +0 -0
  1449. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunNotificationPresenter.class +0 -0
  1450. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaModule$Companion.class +0 -0
  1451. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaModule.class +0 -0
  1452. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaSpec.class +0 -0
  1453. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/SlotManager$Companion.class +0 -0
  1454. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/SlotManager.class +0 -0
  1455. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule$Companion.class +0 -0
  1456. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule$coreListener$1.class +0 -0
  1457. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule.class +0 -0
  1458. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceSpec.class +0 -0
  1459. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$Companion.class +0 -0
  1460. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$getInstallReferrer$1.class +0 -0
  1461. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.class +0 -0
  1462. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.class +0 -0
  1463. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageModule$Companion.class +0 -0
  1464. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageModule.class +0 -0
  1465. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageSpec.class +0 -0
  1466. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/sdk/BuildConfig.class +0 -0
  1467. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeReplaySdkSpec.class +0 -0
  1468. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunCrashSpec.class +0 -0
  1469. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.class +0 -0
  1470. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunOtaSpec.class +0 -0
  1471. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunPerformanceSpec.class +0 -0
  1472. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunProfilerSpec.class +0 -0
  1473. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunStorageSpec.class +0 -0
  1474. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/storage/KvFileStore$Companion.class +0 -0
  1475. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/storage/KvFileStore.class +0 -0
  1476. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  1477. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
  1478. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  1479. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  1480. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  1481. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  1482. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  1483. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  1484. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  1485. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  1486. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  1487. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  1488. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  1489. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  1490. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  1491. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  1492. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  1493. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  1494. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  1495. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  1496. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  1497. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  1498. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  1499. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  1500. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  1501. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  1502. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  1503. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  1504. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  1505. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  1506. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  1507. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  1508. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  1509. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  1510. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  1511. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  1512. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  1513. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
  1514. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream +0 -0
  1515. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len +0 -0
  1516. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len +0 -0
  1517. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
  1518. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i +0 -0
  1519. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len +0 -0
  1520. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  1521. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  1522. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  1523. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  1524. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
  1525. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  1526. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +0 -1
  1527. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  1528. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  1529. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  1530. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  1531. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  1532. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  1533. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  1534. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  1535. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  1536. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  1537. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  1538. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  1539. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  1540. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  1541. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  1542. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  1543. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  1544. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  1545. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  1546. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  1547. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  1548. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  1549. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  1550. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +0 -2
  1551. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  1552. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  1553. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  1554. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  1555. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  1556. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  1557. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  1558. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  1559. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  1560. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  1561. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  1562. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  1563. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  1564. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  1565. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  1566. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  1567. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  1568. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  1569. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values +0 -0
  1570. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  1571. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s +0 -1
  1572. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  1573. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  1574. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  1575. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  1576. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  1577. package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -25
  1578. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  1579. package/android/build/tmp/kotlin-classes/debug/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
  1580. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/CrashStorage.class +0 -0
  1581. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/NativeCrashHandler$Companion.class +0 -0
  1582. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/NativeCrashHandler.class +0 -0
  1583. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/ANRWatchdog$HangInfo.class +0 -0
  1584. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/ANRWatchdog.class +0 -0
  1585. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$AppStartInfo.class +0 -0
  1586. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$Breakdown.class +0 -0
  1587. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$start$1.class +0 -0
  1588. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector.class +0 -0
  1589. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$Companion.class +0 -0
  1590. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$FrameMetricsSnapshot.class +0 -0
  1591. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$start$1.class +0 -0
  1592. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$startChoreographerFallback$1.class +0 -0
  1593. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector.class +0 -0
  1594. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/PerformanceCore$Listener.class +0 -0
  1595. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/PerformanceCore.class +0 -0
  1596. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerModule$Companion.class +0 -0
  1597. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerModule.class +0 -0
  1598. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerPackage.class +0 -0
  1599. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerSpec.class +0 -0
  1600. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/CpuCollector.class +0 -0
  1601. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/IncidentDetector.class +0 -0
  1602. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/MemoryCollector.class +0 -0
  1603. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/RenderCollector$frameCallback$1.class +0 -0
  1604. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/RenderCollector.class +0 -0
  1605. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/SamplerScheduler.class +0 -0
  1606. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/SamplerSchedulerKt.class +0 -0
  1607. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/ThreadCollector$WhenMappings.class +0 -0
  1608. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/ThreadCollector.class +0 -0
  1609. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule$Companion.class +0 -0
  1610. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule$registerConnectivity$cb$1.class +0 -0
  1611. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule.class +0 -0
  1612. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkPackage.class +0 -0
  1613. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkSpec.class +0 -0
  1614. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/CaptureReason$Companion.class +0 -0
  1615. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/CaptureReason.class +0 -0
  1616. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureManager$startFrequencyTimer$1.class +0 -0
  1617. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureManager.class +0 -0
  1618. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$Companion.class +0 -0
  1619. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$FrameRequest.class +0 -0
  1620. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler.class +0 -0
  1621. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$Companion.class +0 -0
  1622. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$SettleWatch.class +0 -0
  1623. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$StabilityWatch.class +0 -0
  1624. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector.class +0 -0
  1625. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/CaptureMode$Companion.class +0 -0
  1626. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/CaptureMode.class +0 -0
  1627. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayConfig$Companion.class +0 -0
  1628. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayConfig.class +0 -0
  1629. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayLogger.class +0 -0
  1630. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ScreenshotQuality$Companion.class +0 -0
  1631. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ScreenshotQuality.class +0 -0
  1632. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/SessionIdGenerator.class +0 -0
  1633. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/SessionState.class +0 -0
  1634. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/ReplayFrame.class +0 -0
  1635. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/ReplaySession.class +0 -0
  1636. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/TimelineEvent.class +0 -0
  1637. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox$Companion.class +0 -0
  1638. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox$enforceLimits$lambda$37$$inlined$sortedBy$1.class +0 -0
  1639. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox.class +0 -0
  1640. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$NetworkError.class +0 -0
  1641. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$Response.class +0 -0
  1642. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult.class +0 -0
  1643. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$Outcome.class +0 -0
  1644. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$WhenMappings.class +0 -0
  1645. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader.class +0 -0
  1646. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.class +0 -0
  1647. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/session/SessionManager.class +0 -0
  1648. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/storage/ReplayStorage$enforceStorageLimit$$inlined$sortedBy$1.class +0 -0
  1649. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/storage/ReplayStorage.class +0 -0
  1650. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/timeline/TimelineCollector.class +0 -0
  1651. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/DialogTouchObserver$start$runnable$1.class +0 -0
  1652. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/DialogTouchObserver.class +0 -0
  1653. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/InteractionTracker.class +0 -0
  1654. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/NativeTouchInterceptor.class +0 -0
  1655. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/ScreenTracker.class +0 -0
  1656. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport$UploadResult.class +0 -0
  1657. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport$upload$2.class +0 -0
  1658. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport.class +0 -0
  1659. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder$Companion.class +0 -0
  1660. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder$Result.class +0 -0
  1661. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder.class +0 -0
  1662. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber$TranscriptResult.class +0 -0
  1663. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber$listener$1.class +0 -0
  1664. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber.class +0 -0
  1665. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ScaleBunPackage$Companion.class +0 -0
  1666. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ScaleBunPackage.class +0 -0
  1667. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashModule$Companion.class +0 -0
  1668. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashModule.class +0 -0
  1669. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashPackage.class +0 -0
  1670. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashSpec.class +0 -0
  1671. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$Companion.class +0 -0
  1672. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$WindowInsetEdges.class +0 -0
  1673. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$shakeListener$1.class +0 -0
  1674. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule.class +0 -0
  1675. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngagePackage.class +0 -0
  1676. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunNotificationPresenter.class +0 -0
  1677. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaModule$Companion.class +0 -0
  1678. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaModule.class +0 -0
  1679. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaSpec.class +0 -0
  1680. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/SlotManager$Companion.class +0 -0
  1681. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/SlotManager.class +0 -0
  1682. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule$Companion.class +0 -0
  1683. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule$coreListener$1.class +0 -0
  1684. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule.class +0 -0
  1685. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceSpec.class +0 -0
  1686. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$Companion.class +0 -0
  1687. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$getInstallReferrer$1.class +0 -0
  1688. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.class +0 -0
  1689. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.class +0 -0
  1690. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageModule$Companion.class +0 -0
  1691. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageModule.class +0 -0
  1692. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageSpec.class +0 -0
  1693. package/android/build/tmp/kotlin-classes/debug/com/scalebun/storage/KvFileStore$Companion.class +0 -0
  1694. package/android/build/tmp/kotlin-classes/debug/com/scalebun/storage/KvFileStore.class +0 -0
@@ -1,946 +1,998 @@
1
- /**
2
- * ScaleBun SDK — Replay Capture Manager
3
- *
4
- * Orchestration-only component for frame capture:
5
- * - Decides WHEN to capture (navigation, interaction, scroll, loading, frequency triggers)
6
- * - Delegates ALL frame capture to native engines via sessionReplayAdapter
7
- * - NEVER performs screenshot logic itself
8
- * - If native capture unavailable, returns null and logs warning
9
- * - Manages frame retention with crash-adjacent priority
10
- * - Uses session-bound generation guard to invalidate stale async work
11
- * - All pending timers are cancelled on stop()
12
- *
13
- * Semantic Capture Coordination:
14
- * - Tracks the last completed capture's reason + screen to prevent semantic duplicates
15
- * - Navigation supersedes pending interaction for the SAME screen (interaction is already
16
- * visually represented by the navigation frame)
17
- * - Loading completion for the SAME screen coalesces with a pending navigation capture
18
- * by cancelling the navigation capture (loading's delayed capture shows the final state)
19
- * - Scroll captures have per-cycle identity and do not conflict with navigation/loading
20
- * - Manual and error-context captures ALWAYS bypass coordination (explicit intent)
21
- * - Genuinely distinct states (different screens, different reasons after settle) are never deduped
22
- */
23
-
24
- import { logger } from '../../core/logger/internalLogger';
25
- import type {
26
- ReplayFrame,
27
- CaptureMode,
28
- CaptureReason,
29
- ReplayQuality,
30
- SessionReplayConfig,
31
- PrivacyPolicy,
32
- NativeFrameResult,
33
- } from './sessionTypes';
34
- import {
35
- FrameRetentionPriority,
36
- getFrameRetentionPriority,
37
- QUALITY_PRESETS,
38
- } from './sessionTypes';
39
-
40
- // ─── Types ──────────────────────────────────────────────────────────────────
41
-
42
- /**
43
- * Native capture function provided by the adapter layer.
44
- * Calls the platform native engine (PixelCopy on Android, UIWindow on iOS).
45
- * Returns null if native capture is unavailable.
46
- */
47
- export type NativeCaptureFn = (
48
- sessionId: string,
49
- reason: string,
50
- quality: ReplayQuality,
51
- ) => Promise<NativeFrameResult | null>;
52
-
53
- export type FrameEmitCallback = (frame: ReplayFrame, imageData: string) => void;
54
-
55
- // ─── Native File-Outbox staged capture ───────────────────────────────────────
56
-
57
- /**
58
- * Metadata returned by a native STAGED capture-to-file. The image bytes are
59
- * already written to the native outbox (staged, not yet uploadable) — they NEVER
60
- * cross the bridge. `frameHash` is a native content hash so JS change-detection
61
- * works without base64.
62
- */
63
- export interface StagedFrameResult {
64
- frameId: string;
65
- width: number;
66
- height: number;
67
- byteSize: number;
68
- format: string;
69
- contentType: string;
70
- frameHash: string;
71
- masked: boolean;
72
- timestamp: number;
73
- platform: 'android' | 'ios';
74
- }
75
-
76
- /** JS-authoritative frame metadata written to the outbox on commit. */
77
- export interface OutboxFrameMeta {
78
- frameId: string;
79
- sessionId: string;
80
- timestamp: number;
81
- sequenceNumber: number;
82
- frameType: 'keyframe' | 'delta';
83
- baseFrameId?: string;
84
- screenName: string;
85
- trigger: string;
86
- format: string;
87
- contentType: string;
88
- width: number;
89
- height: number;
90
- sizeBytes: number;
91
- masked: boolean;
92
- }
93
-
94
- /**
95
- * Native file-outbox frame capture. `capture` stages an image and returns metadata
96
- * only (or null when the outbox is off / capture fails → caller falls back to the
97
- * legacy native capture). `commit` writes the JS-decided meta (making the frame
98
- * uploadable); `discard` drops a staged frame the orchestrator suppressed.
99
- */
100
- export interface OutboxFrameCapture {
101
- capture(
102
- sessionId: string,
103
- screenName: string | undefined,
104
- trigger: string,
105
- ): Promise<StagedFrameResult | null>;
106
- commit(meta: OutboxFrameMeta): Promise<boolean>;
107
- discard(sessionId: string, frameId: string): Promise<void>;
108
- }
109
-
110
- // ─── Capture Intent ─────────────────────────────────────────────────────────
111
-
112
- /**
113
- * Represents the semantic identity of a completed capture.
114
- * Used for dedup: two captures with the same intent fingerprint
115
- * represent the same visual state and should not produce two frames.
116
- */
117
- interface CaptureIntent {
118
- reason: CaptureReason;
119
- screen: string | undefined;
120
- ts: number;
121
- }
122
-
123
- /**
124
- * Reasons that always bypass semantic dedup.
125
- * These are explicit user/system requests that should ALWAYS produce a frame.
126
- */
127
- const BYPASS_DEDUP_REASONS: Set<CaptureReason> = new Set([
128
- 'manual',
129
- 'error-context',
130
- 'frequency',
131
- ]);
132
-
133
- /**
134
- * Minimum time (ms) between captures of the same semantic intent
135
- * (same reason + same screen). Secondary heuristic only — the primary
136
- * check is semantic (reason + screen identity).
137
- */
138
- const SAME_INTENT_COOLDOWN_MS = 300;
139
-
140
- /**
141
- * Time (ms) to defer an interaction capture before finalizing.
142
- * If onScreenChange fires within this window (i.e. the tap caused navigation),
143
- * the interaction capture is cancelled and absorbed into the navigation capture.
144
- * If no navigation follows, the interaction captures normally after this delay.
145
- * 200ms is long enough for most React navigation timings but short enough to feel instant.
146
- */
147
- const INTERACTION_SETTLE_MS = 200;
148
-
149
- /**
150
- * Grace window (ms) AFTER an interaction capture has already fired.
151
- * If onScreenChange fires to a DIFFERENT screen within this window,
152
- * the stale interaction frame is retroactively evicted and its tap
153
- * metadata is carried forward to the navigation capture.
154
- * Handles the intermittent case where navigation takes >INTERACTION_SETTLE_MS.
155
- */
156
- const LATE_ABSORPTION_GRACE_MS = 400;
157
-
158
- // ─── Manager ────────────────────────────────────────────────────────────────
159
-
160
- export class ReplayCaptureManager {
161
- private sessionId: string;
162
- private config: SessionReplayConfig;
163
- private nativeCapture: NativeCaptureFn;
164
- /** Optional native file-outbox path. When ready, frames stage→commit natively. */
165
- private outboxCapture: OutboxFrameCapture | null;
166
- private onFrameEmit: FrameEmitCallback | null = null;
167
-
168
- private frames: ReplayFrame[] = [];
169
- /** Set of frameIds near crashes — never evict */
170
- private protectedFrameIds = new Set<string>();
171
- private frequencyTimer: ReturnType<typeof setInterval> | null = null;
172
- private capturing = false;
173
- private currentScreen: string | null = null;
174
- private lastInteractionCapture = 0;
175
-
176
- /**
177
- * Session-bound generation counter.
178
- * Incremented on stop(). All async capture work checks this before AND after
179
- * native capture to ensure stale callbacks from a previous session lifecycle
180
- * do not emit frames into a new session.
181
- */
182
- private captureGeneration = 0;
183
-
184
- /**
185
- * Tracked navigation capture timeout.
186
- * Cancelled on stop() and on each new onScreenChange() call (debounce).
187
- */
188
- private pendingNavTimeout: ReturnType<typeof setTimeout> | null = null;
189
- /** Screen associated with the pending navigation capture */
190
- private pendingNavScreen: string | null = null;
191
-
192
- /**
193
- * Tracked scroll settle capture timeout.
194
- * Cancelled on stop().
195
- */
196
- private pendingScrollTimeout: ReturnType<typeof setTimeout> | null = null;
197
-
198
- /**
199
- * Tracked loading end capture timeout.
200
- * Cancelled on stop().
201
- */
202
- private pendingLoadingTimeout: ReturnType<typeof setTimeout> | null = null;
203
- /** Screen associated with the pending loading capture */
204
- private pendingLoadingScreen: string | null = null;
205
-
206
- /**
207
- * Pending interaction capture timeout.
208
- * When a tap/gesture occurs, the capture is DEFERRED by INTERACTION_SETTLE_MS.
209
- * If onScreenChange fires within that window (tap caused navigation), the
210
- * pending interaction is cancelled and its tap metadata is carried forward
211
- * to the navigation capture ensuring the destination screen is captured
212
- * instead of a stale pre-navigation screenshot.
213
- * If no navigation follows, the interaction capture fires normally.
214
- */
215
- private pendingInteractionTimeout: ReturnType<typeof setTimeout> | null = null;
216
- /** Interaction point metadata held while pending (carried to nav if absorbed) */
217
- private pendingInteractionPoint: ReplayFrame['interactionPoint'] | undefined = undefined;
218
- /** Screen at the time the pending interaction was created */
219
- private pendingInteractionScreen: string | undefined = undefined;
220
-
221
- /**
222
- * Late absorption tracking.
223
- * After an interaction capture fires, store its metadata so that
224
- * a delayed onScreenChange can retroactively evict the stale frame
225
- * and carry the tap metadata forward to the navigation capture.
226
- */
227
- private lastCompletedInteraction: {
228
- frameId: string;
229
- screen: string | undefined;
230
- interactionPoint: ReplayFrame['interactionPoint'] | undefined;
231
- ts: number;
232
- } | null = null;
233
-
234
- /**
235
- * In-flight interaction tracking.
236
- * Set when triggerCapture('interaction') starts the async native call and cleared
237
- * when it completes. If onScreenChange fires for a DIFFERENT screen while a capture
238
- * is in-flight, the capture is suppressed — the navigation frame is the correct state.
239
- * Covers the race window between pendingInteractionTimeout firing and native returning,
240
- * which neither pending-absorption nor late-absorption can reach.
241
- */
242
- private _inFlightInteractionScreen: string | undefined = undefined;
243
- private _inFlightInteractionPoint: ReplayFrame['interactionPoint'] | undefined = undefined;
244
- private _suppressInFlightInteraction = false;
245
-
246
- /**
247
- * Last completed capture intent — used for semantic dedup.
248
- * Captures with the same reason + screen within SAME_INTENT_COOLDOWN_MS are suppressed.
249
- */
250
- private lastCaptureIntent: CaptureIntent | null = null;
251
-
252
- // ── P2-0/1/5 capture state ──────────────────────────────────────────
253
- /** P2-0: monotonic per-session sequence; first emitted frame is 1. */
254
- private _sequenceCounter = 0;
255
- /** P2-1: hash of the last EMITTED frame, for visual change detection. */
256
- private _lastFrameHash: string | null = null;
257
- /** P2-1/5: wall-clock of the last emitted keyframe (heartbeat base). */
258
- private _lastKeyframeTs = 0;
259
- /** P2-5: frameId of the last emitted keyframe delta base reference. */
260
- private _lastKeyframeId: string | null = null;
261
- /** P2-5: emitted frames since the last keyframe (keyframe-interval guard). */
262
- private _framesSinceKeyframe = 0;
263
-
264
- constructor(
265
- sessionId: string,
266
- config: SessionReplayConfig,
267
- nativeCapture: NativeCaptureFn,
268
- outboxCapture?: OutboxFrameCapture | null,
269
- ) {
270
- this.sessionId = sessionId;
271
- this.config = config;
272
- this.nativeCapture = nativeCapture;
273
- this.outboxCapture = outboxCapture ?? null;
274
- }
275
-
276
- // ─── Public API ─────────────────────────────────────────────────────
277
-
278
- /** Set callback for when a frame is captured */
279
- setFrameEmitCallback(cb: FrameEmitCallback): void {
280
- this.onFrameEmit = cb;
281
- }
282
-
283
- /** Start capture according to configured mode */
284
- start(): void {
285
- if (this.capturing) return;
286
- this.capturing = true;
287
-
288
- // P2-0/1/5: reset per-session capture state so sequence + keyframe tracking
289
- // start clean for this session lifecycle.
290
- this._sequenceCounter = 0;
291
- this._lastFrameHash = null;
292
- this._lastKeyframeTs = 0;
293
- this._lastKeyframeId = null;
294
- this._framesSinceKeyframe = 0;
295
-
296
- // Start frequency timer if in frequency mode
297
- if (this.config.captureMode === 'frequency') {
298
- const intervalMs = Math.max(500, this.config.intervalMs);
299
- this.frequencyTimer = setInterval(() => {
300
- this.triggerCapture('frequency').catch(() => { });
301
- }, intervalMs);
302
- logger.debug(`[ReplayCaptureManager] Frequency mode: every ${intervalMs}ms`);
303
- }
304
-
305
- logger.debug(`[ReplayCaptureManager] Started (mode=${this.config.captureMode})`);
306
- }
307
-
308
- /** Stop capture cancels ALL pending timers and increments generation */
309
- stop(): void {
310
- this.capturing = false;
311
-
312
- // Increment generation — invalidates ALL in-flight async captures
313
- this.captureGeneration++;
314
-
315
- // Cancel frequency timer
316
- if (this.frequencyTimer) {
317
- clearInterval(this.frequencyTimer);
318
- this.frequencyTimer = null;
319
- }
320
-
321
- // Cancel pending navigation capture
322
- if (this.pendingNavTimeout) {
323
- clearTimeout(this.pendingNavTimeout);
324
- this.pendingNavTimeout = null;
325
- this.pendingNavScreen = null;
326
- }
327
-
328
- // Cancel pending scroll capture
329
- if (this.pendingScrollTimeout) {
330
- clearTimeout(this.pendingScrollTimeout);
331
- this.pendingScrollTimeout = null;
332
- }
333
-
334
- // Cancel pending loading capture
335
- if (this.pendingLoadingTimeout) {
336
- clearTimeout(this.pendingLoadingTimeout);
337
- this.pendingLoadingTimeout = null;
338
- this.pendingLoadingScreen = null;
339
- }
340
-
341
- // Cancel pending interaction capture
342
- if (this.pendingInteractionTimeout) {
343
- clearTimeout(this.pendingInteractionTimeout);
344
- this.pendingInteractionTimeout = null;
345
- this.pendingInteractionPoint = undefined;
346
- this.pendingInteractionScreen = undefined;
347
- }
348
-
349
- // Clear late absorption tracking
350
- this.lastCompletedInteraction = null;
351
-
352
- // Clear in-flight interaction tracking
353
- this._inFlightInteractionScreen = undefined;
354
- this._inFlightInteractionPoint = undefined;
355
- this._suppressInFlightInteraction = false;
356
-
357
- // Clear dedup state
358
- this.lastCaptureIntent = null;
359
-
360
- logger.debug('[ReplayCaptureManager] Stopped (all timers cancelled, generation incremented)');
361
- }
362
-
363
- /** Notify of a screen change triggers cancellable delayed capture */
364
- onScreenChange(screenName: string): void {
365
- this.currentScreen = screenName;
366
-
367
- if (!this.capturing) return;
368
- if (this._isExcludedScreen(screenName)) return;
369
-
370
- if (this.config.captureMode === 'navigation' || this.config.captureMode === 'interactions') {
371
- // Cancel any previous pending navigation capture (debounce rapid navigations)
372
- if (this.pendingNavTimeout) {
373
- clearTimeout(this.pendingNavTimeout);
374
- this.pendingNavTimeout = null;
375
- this.pendingNavScreen = null;
376
- }
377
-
378
- // Cancel any pending scroll capture — scroll on the old screen is now obsolete
379
- if (this.pendingScrollTimeout) {
380
- clearTimeout(this.pendingScrollTimeout);
381
- this.pendingScrollTimeout = null;
382
- }
383
-
384
- // Cancel pending loading capture ONLY if it was for a DIFFERENT screen.
385
- if (this.pendingLoadingTimeout && this.pendingLoadingScreen !== screenName) {
386
- clearTimeout(this.pendingLoadingTimeout);
387
- this.pendingLoadingTimeout = null;
388
- this.pendingLoadingScreen = null;
389
- }
390
-
391
- // ── Absorb pending interaction if tap caused this navigation ──────
392
- // If a tap was pending and the screen changed (tap → navigation),
393
- // cancel the stale interaction capture and carry its tap metadata
394
- // forward into the navigation capture.
395
- let absorbedInteractionPoint: ReplayFrame['interactionPoint'] | undefined;
396
- if (this.pendingInteractionTimeout) {
397
- clearTimeout(this.pendingInteractionTimeout);
398
- absorbedInteractionPoint = this.pendingInteractionPoint;
399
- this.pendingInteractionTimeout = null;
400
- this.pendingInteractionPoint = undefined;
401
- this.pendingInteractionScreen = undefined;
402
- logger.debug(
403
- `[ReplayCaptureManager] Pending interaction absorbed by navigation to ${screenName}`,
404
- );
405
- }
406
-
407
- // ── Late absorption: retroactively evict stale interaction frame ──
408
- // If an interaction capture ALREADY completed (settle window expired)
409
- // but navigation arrives within the grace window to a DIFFERENT screen,
410
- // the interaction frame is stale (captured old screen). Evict it and
411
- // carry its tap metadata forward to the navigation capture.
412
- if (
413
- !absorbedInteractionPoint &&
414
- this.lastCompletedInteraction &&
415
- this.lastCompletedInteraction.screen !== screenName &&
416
- (Date.now() - this.lastCompletedInteraction.ts) < LATE_ABSORPTION_GRACE_MS
417
- ) {
418
- const stale = this.lastCompletedInteraction;
419
- absorbedInteractionPoint = stale.interactionPoint;
420
- // Evict the stale frame from the frames list
421
- this.frames = this.frames.filter(f => f.frameId !== stale.frameId);
422
- logger.debug(
423
- `[ReplayCaptureManager] Late absorption: evicted stale interaction frame ` +
424
- `${stale.frameId} on ${stale.screen}, navigation to ${screenName}`,
425
- );
426
- this.lastCompletedInteraction = null;
427
- }
428
-
429
- // ── In-flight interaction suppression ─────────────────────────
430
- // If a native interaction capture started (settle timer already fired)
431
- // but hasn't returned yet, suppress it — the navigation represents
432
- // the correct visual state. Carry the tap point forward if available.
433
- if (
434
- !absorbedInteractionPoint &&
435
- this._inFlightInteractionScreen !== undefined &&
436
- this._inFlightInteractionScreen !== screenName
437
- ) {
438
- this._suppressInFlightInteraction = true;
439
- if (this._inFlightInteractionPoint) {
440
- absorbedInteractionPoint = this._inFlightInteractionPoint;
441
- }
442
- logger.debug(
443
- `[ReplayCaptureManager] In-flight interaction suppressed by navigation to ${screenName}`,
444
- );
445
- }
446
-
447
- // Track which screen this nav capture is for
448
- this.pendingNavScreen = screenName;
449
-
450
- // Brief delay to allow the new screen to render (but stay snappy)
451
- this.pendingNavTimeout = setTimeout(() => {
452
- this.pendingNavTimeout = null;
453
- this.pendingNavScreen = null;
454
- // Pass absorbed interaction point so the nav frame carries tap metadata
455
- this.triggerCapture('navigation', screenName, absorbedInteractionPoint).catch(() => { });
456
- }, 150);
457
- }
458
- }
459
-
460
- /**
461
- * Notify of a user interaction deferred capture with navigation absorption.
462
- *
463
- * Instead of capturing immediately (which would snapshot the OLD screen
464
- * when the tap causes navigation), the capture is deferred by
465
- * INTERACTION_SETTLE_MS. If onScreenChange fires within that window,
466
- * the pending interaction is absorbed into the navigation capture.
467
- * If no navigation follows, the interaction capture fires normally.
468
- */
469
- onInteraction(interactionPoint?: ReplayFrame['interactionPoint']): void {
470
- if (!this.capturing) return;
471
- if (this.currentScreen && this._isExcludedScreen(this.currentScreen)) return;
472
-
473
- // Throttle: prevent duplicate captures from rapid gestures (500ms)
474
- const now = Date.now();
475
- if (now - this.lastInteractionCapture < 500) return;
476
- this.lastInteractionCapture = now;
477
-
478
- const screen = this.currentScreen ?? undefined;
479
-
480
- // Semantic dedup: if a navigation capture is pending for the SAME screen,
481
- // the navigation frame will represent the post-interaction state.
482
- if (this.pendingNavTimeout && this.pendingNavScreen === screen) {
483
- logger.debug('[ReplayCaptureManager] Interaction suppressed navigation pending for same screen');
484
- return;
485
- }
486
-
487
- // Cancel any previous pending interaction (rapid tap replacement)
488
- if (this.pendingInteractionTimeout) {
489
- clearTimeout(this.pendingInteractionTimeout);
490
- }
491
-
492
- // Defer the interaction capture to allow navigation to absorb it
493
- this.pendingInteractionScreen = screen;
494
- this.pendingInteractionPoint = interactionPoint;
495
- this.pendingInteractionTimeout = setTimeout(() => {
496
- this.pendingInteractionTimeout = null;
497
- const captureScreen = this.pendingInteractionScreen;
498
- const capturePoint = this.pendingInteractionPoint;
499
- this.pendingInteractionScreen = undefined;
500
- this.pendingInteractionPoint = undefined;
501
- // No navigation followed capture the interaction on the current screen
502
- this.triggerCapture('interaction', captureScreen, capturePoint).catch(() => { });
503
- }, INTERACTION_SETTLE_MS);
504
- }
505
-
506
- /** Notify of scroll settle — triggers delayed capture for post-scroll state */
507
- onScrollSettle(screenName?: string): void {
508
- if (!this.capturing) return;
509
-
510
- // Cancel any previous pending scroll capture
511
- if (this.pendingScrollTimeout) {
512
- clearTimeout(this.pendingScrollTimeout);
513
- this.pendingScrollTimeout = null;
514
- }
515
-
516
- // Small delay to let post-scroll rendering settle
517
- this.pendingScrollTimeout = setTimeout(() => {
518
- this.pendingScrollTimeout = null;
519
- this.triggerCapture('scroll', screenName ?? this.currentScreen ?? undefined).catch(() => { });
520
- }, 150);
521
- }
522
-
523
- /** Notify of loading end — captures the settled loaded screen */
524
- onLoadingEnd(screenName?: string): void {
525
- if (!this.capturing) return;
526
-
527
- const screen = screenName ?? this.currentScreen ?? undefined;
528
-
529
- // Cancel any previous pending loading capture for ANY screen
530
- if (this.pendingLoadingTimeout) {
531
- clearTimeout(this.pendingLoadingTimeout);
532
- this.pendingLoadingTimeout = null;
533
- this.pendingLoadingScreen = null;
534
- }
535
-
536
- // If a navigation capture is pending for the SAME screen, cancel it.
537
- // The loading-end capture represents the final settled state and supersedes
538
- // the initial navigation capture (which would show loading/skeleton UI).
539
- if (this.pendingNavTimeout && this.pendingNavScreen === screen) {
540
- clearTimeout(this.pendingNavTimeout);
541
- this.pendingNavTimeout = null;
542
- this.pendingNavScreen = null;
543
- logger.debug('[ReplayCaptureManager] Navigation capture cancelled loading-end supersedes for same screen');
544
- }
545
-
546
- // Track which screen this loading capture is for
547
- this.pendingLoadingScreen = screen ?? null;
548
-
549
- // Slight delay to allow the loaded content to render
550
- this.pendingLoadingTimeout = setTimeout(() => {
551
- this.pendingLoadingTimeout = null;
552
- this.pendingLoadingScreen = null;
553
- this.triggerCapture('screen_loaded', screen).catch(() => { });
554
- }, 200);
555
- }
556
-
557
- /** Manual capture trigger (e.g. error-context) */
558
- async captureManual(reason: CaptureReason): Promise<ReplayFrame | null> {
559
- return this.triggerCapture(reason, this.currentScreen ?? undefined);
560
- }
561
-
562
- /** Protect frames near a crash from eviction */
563
- protectFramesNearCrash(crashTimestamp: number, windowMs: number = 10_000): string[] {
564
- const protectedIds: string[] = [];
565
- for (const frame of this.frames) {
566
- if (Math.abs(frame.ts - crashTimestamp) <= windowMs) {
567
- this.protectedFrameIds.add(frame.frameId);
568
- protectedIds.push(frame.frameId);
569
- }
570
- }
571
- return protectedIds;
572
- }
573
-
574
- /** Get all frames (read-only snapshot) */
575
- getFrames(): readonly ReplayFrame[] {
576
- return this.frames;
577
- }
578
-
579
- /** Get frame IDs for artifact index */
580
- getFrameRefs(): string[] {
581
- return this.frames.map(f => f.frameId);
582
- }
583
-
584
- /** Current frame count */
585
- get count(): number {
586
- return this.frames.length;
587
- }
588
-
589
- /** Clear all frames */
590
- clear(): void {
591
- this.frames = [];
592
- this.protectedFrameIds.clear();
593
- }
594
-
595
- // ─── Core Capture ───────────────────────────────────────────────────
596
-
597
- /**
598
- * Trigger a frame capture via native engine.
599
- * This method ONLY orchestrates — native does the real work.
600
- *
601
- * Semantic dedup: if the last completed capture has the same reason + screen
602
- * and happened within SAME_INTENT_COOLDOWN_MS, the capture is suppressed.
603
- * Bypass reasons (manual, error-context, frequency) skip this check entirely.
604
- *
605
- * Session-bound generation guard: captures the generation counter before
606
- * starting the async native capture and verifies it hasn't changed after.
607
- * If it has, the capture result is silently discarded — the session that
608
- * requested it no longer exists.
609
- */
610
- private async triggerCapture(
611
- reason: CaptureReason,
612
- screenName?: string,
613
- interactionPoint?: ReplayFrame['interactionPoint'],
614
- ): Promise<ReplayFrame | null> {
615
- if (!this.capturing) return null;
616
-
617
- // ── Semantic dedup check ────────────────────────────────────────
618
- if (!BYPASS_DEDUP_REASONS.has(reason) && this.lastCaptureIntent) {
619
- const last = this.lastCaptureIntent;
620
- const sameScreen = last.screen === screenName;
621
- const sameReason = last.reason === reason;
622
- const withinCooldown = (Date.now() - last.ts) < SAME_INTENT_COOLDOWN_MS;
623
-
624
- // Same reason + same screen within cooldown → semantic duplicate
625
- if (sameReason && sameScreen && withinCooldown) {
626
- logger.debug(
627
- `[ReplayCaptureManager] Semantic dedup: ${reason}@${screenName} suppressed ` +
628
- `(same intent within ${SAME_INTENT_COOLDOWN_MS}ms)`,
629
- );
630
- return null;
631
- }
632
- }
633
-
634
- // Capture generation at call time
635
- const gen = this.captureGeneration;
636
-
637
- // ── In-flight interaction tracking ─────────────────────────────
638
- // Mark this capture as in-flight so onScreenChange can suppress it
639
- // if navigation arrives before the native callback returns.
640
- if (reason === 'interaction') {
641
- this._inFlightInteractionScreen = screenName;
642
- this._inFlightInteractionPoint = interactionPoint;
643
- this._suppressInFlightInteraction = false;
644
- }
645
-
646
- try {
647
- // ── Capture path selection ──────────────────────────────────────
648
- // Prefer the native file-outbox staged path when ready: it captures +
649
- // masks + encodes natively and STAGES the image (bytes never cross the
650
- // bridge). If the outbox is off / unavailable / the staged capture fails,
651
- // fall back to the legacy native capture (base64 → JS upload). All
652
- // orchestration below (dedup, change-detection, keyframe/delta, sequencing)
653
- // is identical for both paths.
654
- const screen = screenName ?? this.currentScreen ?? undefined;
655
- let staged: StagedFrameResult | null = null;
656
- if (this.outboxCapture) {
657
- staged = await this.outboxCapture.capture(this.sessionId, screen, reason);
658
- }
659
- const usedStaged = staged !== null;
660
-
661
- let result: NativeFrameResult | null;
662
- if (staged) {
663
- result = {
664
- base64: '', // bytes stay native on the outbox path — never bridged
665
- width: staged.width,
666
- height: staged.height,
667
- byteSize: staged.byteSize,
668
- format: staged.format,
669
- frameHash: staged.frameHash,
670
- platform: staged.platform,
671
- };
672
- } else {
673
- result = await this.nativeCapture(this.sessionId, reason, this.config.quality);
674
- }
675
-
676
- // Drop a staged frame if any guard below rejects it (keeps the outbox clean).
677
- const discardStaged = (): void => {
678
- if (usedStaged && staged) {
679
- this.outboxCapture?.discard(this.sessionId, staged.frameId).catch(() => { });
680
- }
681
- };
682
-
683
- // ── In-flight suppression check ─────────────────────────────
684
- // Clear in-flight tracking first (before any early returns).
685
- if (reason === 'interaction') {
686
- this._inFlightInteractionScreen = undefined;
687
- this._inFlightInteractionPoint = undefined;
688
- if (this._suppressInFlightInteraction) {
689
- this._suppressInFlightInteraction = false;
690
- discardStaged();
691
- logger.debug('[ReplayCaptureManager] In-flight interaction suppressed — navigation arrived during capture');
692
- return null;
693
- }
694
- }
695
-
696
- // Generation guard: if session was stopped/restarted during async capture,
697
- // discard the result to prevent stale frames
698
- if (gen !== this.captureGeneration) {
699
- discardStaged();
700
- logger.debug('[ReplayCaptureManager] Stale capture discarded (generation mismatch)');
701
- return null;
702
- }
703
-
704
- if (!this.capturing) {
705
- discardStaged();
706
- return null;
707
- }
708
-
709
- if (!result) {
710
- // Native capture unavailable log warning, return null
711
- // NO JS fallback — this is by design
712
- logger.debug('[ReplayCaptureManager] Native capture returned null — frame not captured');
713
- return null;
714
- }
715
-
716
- // ── P2-1: change-triggered capture + heartbeat keyframe ─────────
717
- // Visual suppression applies ONLY to the periodic 'frequency' lane — the
718
- // sole source of redundant, visually-identical consecutive frames during
719
- // static viewing (the −40–60% lever). Semantic captures (navigation /
720
- // interaction / scroll / screen_loaded) are already change-driven and are
721
- // handled by the semantic dedup above, so they always emit — visual-hashing
722
- // them risks dropping a meaningful frame whose pixels happen to match.
723
- // manual / error-context are explicit intent and likewise always emit.
724
- // The heartbeat (maxKeyframeIntervalMs) forces a keyframe even when nothing
725
- // changed, so static periods still have a frame AND deltas keep a fresh base.
726
- // Suppressed frames do NOT consume a sequence number.
727
- const now = Date.now();
728
- const hash = result.frameHash ?? hashBase64(result.base64);
729
- const explicit = reason === 'manual' || reason === 'error-context';
730
- const maxKf = this.config.maxKeyframeIntervalMs ?? 5000;
731
- const heartbeatDue = (now - this._lastKeyframeTs) >= maxKf;
732
- const changed = hash !== this._lastFrameHash;
733
- const changeDetection = this.config.changeDetection !== false;
734
- if (changeDetection && reason === 'frequency' && !changed && !heartbeatDue) {
735
- discardStaged();
736
- logger.debug('[ReplayCaptureManager] Change-trigger suppressed identical frequency frame');
737
- return null;
738
- }
739
-
740
- // ── P2-5: keyframe vs delta decision ────────────────────────────
741
- // Force a keyframe when: delta encoding is off, no base exists yet, the
742
- // heartbeat is due, the keyframe-interval elapsed, or this is an explicit
743
- // capture (full frame is safest). Otherwise emit a delta against the last
744
- // keyframe. NOTE: real delta-byte encoding is native (pixel ops); JS owns
745
- // the decision/tagging — see P2_CONTRACT.md §3/§6.
746
- const deltaOn = this.config.deltaEncoding === true;
747
- const kfInterval = this.config.deltaKeyframeInterval ?? 10;
748
- const mustKeyframe =
749
- !deltaOn ||
750
- this._lastKeyframeId === null ||
751
- heartbeatDue ||
752
- explicit ||
753
- this._framesSinceKeyframe >= kfInterval;
754
- const frameType: 'keyframe' | 'delta' = mustKeyframe ? 'keyframe' : 'delta';
755
- const baseFrameId = frameType === 'delta' ? this._lastKeyframeId ?? undefined : undefined;
756
-
757
- // Build frame with artifact reference and screen context.
758
- // On the native-outbox staged path the image is ALREADY written to disk
759
- // under the native-assigned frameId; reuse it so commitOutboxFrame's
760
- // lookup resolves (minting a fresh id here makes the staged image
761
- // "missing" at commit the frame is silently dropped → zero frames).
762
- // Legacy (base64) path has no staged file, so mint a new id.
763
- const frameId = staged?.frameId ?? generateFrameId();
764
-
765
- // Fill interactionPoint screen dimensions from the capture result.
766
- // interactionPoint may come from an absorbed pending interaction
767
- // (tap navigation), so attach it regardless of capture reason.
768
- const resolvedInteraction = interactionPoint
769
- ? { ...interactionPoint, screenWidth: result.width, screenHeight: result.height }
770
- : undefined;
771
-
772
- const frame: ReplayFrame = {
773
- frameId,
774
- sessionId: this.sessionId,
775
- ts: now,
776
- sequenceNumber: ++this._sequenceCounter,
777
- frameType,
778
- ...(baseFrameId ? { baseFrameId } : {}),
779
- imageRef: frameId, // Artifact ref — transport resolves to actual content
780
- width: result.width,
781
- height: result.height,
782
- byteSize: result.byteSize ?? 0,
783
- format: result.format ?? 'jpeg',
784
- quality: this.config.quality,
785
- captureReason: reason,
786
- sourcePlatform: result.platform,
787
- screen: screenName ?? this.currentScreen ?? undefined,
788
- // Attach interaction point if this was an interaction-driven capture
789
- ...(resolvedInteraction ? { interactionPoint: resolvedInteraction } : {}),
790
- };
791
-
792
- // ── Record capture intent for dedup ─────────────────────────
793
- this.lastCaptureIntent = {
794
- reason,
795
- screen: screenName,
796
- ts: Date.now(),
797
- };
798
-
799
- // Enforce frame limit with priority-based eviction
800
- if (this.frames.length >= this.config.maxFrames) {
801
- this._evictLowestPriorityFrame();
802
- }
803
-
804
- this.frames.push(frame);
805
-
806
- // ── P2-1/5: commit change-detection + keyframe tracking ─────────
807
- this._lastFrameHash = hash;
808
- if (frameType === 'keyframe') {
809
- this._lastKeyframeId = frameId;
810
- this._lastKeyframeTs = now;
811
- this._framesSinceKeyframe = 0;
812
- } else {
813
- this._framesSinceKeyframe++;
814
- }
815
-
816
- // ── Deliver the frame ───────────────────────────────────────────
817
- // Staged (native outbox) path: commit JS-authoritative metadata so the
818
- // native uploader owns delivery. Do NOT also emit base64 to the JS
819
- // transport that would double-upload the frame. If commit fails the
820
- // image is left staged (no meta) and swept as an orphan on next recover().
821
- // Legacy path: emit base64 to the JS transport as before.
822
- if (usedStaged && staged) {
823
- const meta: OutboxFrameMeta = {
824
- frameId: frame.frameId,
825
- sessionId: this.sessionId,
826
- timestamp: frame.ts,
827
- sequenceNumber: frame.sequenceNumber,
828
- frameType,
829
- ...(baseFrameId ? { baseFrameId } : {}),
830
- screenName: frame.screen ?? 'unknown',
831
- trigger: reason,
832
- format: staged.format,
833
- contentType: staged.contentType,
834
- width: staged.width,
835
- height: staged.height,
836
- sizeBytes: staged.byteSize,
837
- masked: staged.masked,
838
- };
839
- try {
840
- const committed = await this.outboxCapture?.commit(meta);
841
- if (!committed) {
842
- logger.debug('[ReplayCaptureManager] Outbox commit failed — frame staged but not uploadable');
843
- }
844
- } catch {
845
- // Commit failure must not crash capture; orphan is swept later.
846
- }
847
- } else {
848
- // Emit to transport — pass base64 as transport-layer data (not domain)
849
- try {
850
- this.onFrameEmit?.(frame, result.base64);
851
- } catch {
852
- // Transport emission must not crash capture
853
- }
854
- }
855
-
856
- // ── Track completed interaction for late absorption ──────────
857
- // If this was an interaction capture, record its metadata so that
858
- // a delayed onScreenChange can retroactively evict it if navigation
859
- // follows within LATE_ABSORPTION_GRACE_MS.
860
- if (reason === 'interaction') {
861
- this.lastCompletedInteraction = {
862
- frameId: frame.frameId,
863
- screen: frame.screen,
864
- interactionPoint: frame.interactionPoint,
865
- ts: Date.now(),
866
- };
867
- } else {
868
- // Non-interaction captures clear the tracker — no late absorption needed
869
- this.lastCompletedInteraction = null;
870
- }
871
-
872
- return frame;
873
- } catch (err) {
874
- // Clear in-flight tracking on error too
875
- if (reason === 'interaction') {
876
- this._inFlightInteractionScreen = undefined;
877
- this._inFlightInteractionPoint = undefined;
878
- this._suppressInFlightInteraction = false;
879
- }
880
- logger.error('[ReplayCaptureManager] Capture failed:', err);
881
- return null;
882
- }
883
- }
884
-
885
- // ─── Frame Retention ────────────────────────────────────────────────
886
-
887
- /**
888
- * Evict the frame with the lowest retention priority.
889
- * Crash-adjacent and error-context frames are NEVER evicted before generic frames.
890
- */
891
- private _evictLowestPriorityFrame(): void {
892
- let lowestIdx = -1;
893
- let lowestPriority = Infinity;
894
- let oldestTs = Infinity;
895
-
896
- for (let i = 0; i < this.frames.length; i++) {
897
- const frame = this.frames[i];
898
- // Never evict protected (crash-adjacent) frames
899
- if (this.protectedFrameIds.has(frame.frameId)) continue;
900
-
901
- const priority = getFrameRetentionPriority(frame.captureReason);
902
- if (priority < lowestPriority || (priority === lowestPriority && frame.ts < oldestTs)) {
903
- lowestPriority = priority;
904
- lowestIdx = i;
905
- oldestTs = frame.ts;
906
- }
907
- }
908
-
909
- if (lowestIdx >= 0) {
910
- this.frames.splice(lowestIdx, 1);
911
- } else {
912
- // All protected drop oldest anyway
913
- this.frames.shift();
914
- }
915
- }
916
-
917
- // ─── Helpers ────────────────────────────────────────────────────────
918
-
919
- private _isExcludedScreen(screenName: string): boolean {
920
- return this.config.privacyPolicy.captureExclusions.includes(screenName);
921
- }
922
- }
923
-
924
- // ─── Utils ──────────────────────────────────────────────────────────────────
925
-
926
- function generateFrameId(): string {
927
- return `frm-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`;
928
- }
929
-
930
- /**
931
- * P2-1 change detection: cheap, allocation-light FNV-1a over the base64 string.
932
- * Exact-hash only — a perceptual/near-identical match is a native concern (the
933
- * native layer may supply `frameHash`; this is the JS fallback). Sampling every
934
- * Nth char keeps it O(1)-ish on large frames while still being change-sensitive.
935
- */
936
- function hashBase64(b64: string): string {
937
- let h = 0x811c9dc5;
938
- const len = b64.length;
939
- const step = len > 4096 ? Math.ceil(len / 4096) : 1;
940
- for (let i = 0; i < len; i += step) {
941
- h ^= b64.charCodeAt(i);
942
- h = Math.imul(h, 0x01000193);
943
- }
944
- // Fold in length so same-prefix different-length frames don't collide.
945
- return `${(h >>> 0).toString(36)}-${len.toString(36)}`;
946
- }
1
+ /**
2
+ * ScaleBun SDK — Replay Capture Manager
3
+ *
4
+ * Orchestration-only component for frame capture:
5
+ * - Decides WHEN to capture (navigation, interaction, scroll, loading, frequency triggers)
6
+ * - Delegates ALL frame capture to native engines via sessionReplayAdapter
7
+ * - NEVER performs screenshot logic itself
8
+ * - If native capture unavailable, returns null and logs warning
9
+ * - Manages frame retention with crash-adjacent priority
10
+ * - Uses session-bound generation guard to invalidate stale async work
11
+ * - All pending timers are cancelled on stop()
12
+ *
13
+ * Semantic Capture Coordination:
14
+ * - Tracks the last completed capture's reason + screen to prevent semantic duplicates
15
+ * - Navigation supersedes pending interaction for the SAME screen (interaction is already
16
+ * visually represented by the navigation frame)
17
+ * - Loading completion for the SAME screen coalesces with a pending navigation capture
18
+ * by cancelling the navigation capture (loading's delayed capture shows the final state)
19
+ * - Scroll captures have per-cycle identity and do not conflict with navigation/loading
20
+ * - Manual and error-context captures ALWAYS bypass coordination (explicit intent)
21
+ * - Genuinely distinct states (different screens, different reasons after settle) are never deduped
22
+ */
23
+
24
+ import { logger } from '../../core/logger/internalLogger';
25
+ import type {
26
+ ReplayFrame,
27
+ CaptureMode,
28
+ CaptureReason,
29
+ ReplayQuality,
30
+ SessionReplayConfig,
31
+ PrivacyPolicy,
32
+ NativeFrameResult,
33
+ } from './sessionTypes';
34
+ import {
35
+ FrameRetentionPriority,
36
+ getFrameRetentionPriority,
37
+ QUALITY_PRESETS,
38
+ } from './sessionTypes';
39
+ import type { PlatformOS } from '../../core/context/device';
40
+
41
+ // ─── Types ──────────────────────────────────────────────────────────────────
42
+
43
+ /**
44
+ * Native capture function provided by the adapter layer.
45
+ * Calls the platform native engine (PixelCopy on Android, UIWindow on iOS).
46
+ * Returns null if native capture is unavailable.
47
+ */
48
+ export type NativeCaptureFn = (
49
+ sessionId: string,
50
+ reason: string,
51
+ quality: ReplayQuality,
52
+ ) => Promise<NativeFrameResult | null>;
53
+
54
+ export type FrameEmitCallback = (frame: ReplayFrame, imageData: string) => void;
55
+
56
+ // ─── Native File-Outbox staged capture ───────────────────────────────────────
57
+
58
+ /**
59
+ * Metadata returned by a native STAGED capture-to-file. The image bytes are
60
+ * already written to the native outbox (staged, not yet uploadable) they NEVER
61
+ * cross the bridge. `frameHash` is a native content hash so JS change-detection
62
+ * works without base64.
63
+ */
64
+ export interface StagedFrameResult {
65
+ frameId: string;
66
+ width: number;
67
+ height: number;
68
+ byteSize: number;
69
+ format: string;
70
+ contentType: string;
71
+ frameHash: string;
72
+ masked: boolean;
73
+ timestamp: number;
74
+ // Widened: frames now carry the REAL Platform.OS instead of being relabelled 'android'.
75
+ platform: PlatformOS;
76
+ }
77
+
78
+ /** JS-authoritative frame metadata written to the outbox on commit. */
79
+ export interface OutboxFrameMeta {
80
+ frameId: string;
81
+ sessionId: string;
82
+ timestamp: number;
83
+ sequenceNumber: number;
84
+ frameType: 'keyframe' | 'delta';
85
+ baseFrameId?: string;
86
+ screenName: string;
87
+ trigger: string;
88
+ format: string;
89
+ contentType: string;
90
+ width: number;
91
+ height: number;
92
+ sizeBytes: number;
93
+ masked: boolean;
94
+ }
95
+
96
+ /**
97
+ * Native file-outbox frame capture. `capture` stages an image and returns metadata
98
+ * only (or null when the outbox is off / capture fails → caller falls back to the
99
+ * legacy native capture). `commit` writes the JS-decided meta (making the frame
100
+ * uploadable); `discard` drops a staged frame the orchestrator suppressed.
101
+ */
102
+ export interface OutboxFrameCapture {
103
+ capture(
104
+ sessionId: string,
105
+ screenName: string | undefined,
106
+ trigger: string,
107
+ ): Promise<StagedFrameResult | null>;
108
+ commit(meta: OutboxFrameMeta): Promise<boolean>;
109
+ discard(sessionId: string, frameId: string): Promise<void>;
110
+ }
111
+
112
+ // ─── Capture Intent ─────────────────────────────────────────────────────────
113
+
114
+ /**
115
+ * Represents the semantic identity of a completed capture.
116
+ * Used for dedup: two captures with the same intent fingerprint
117
+ * represent the same visual state and should not produce two frames.
118
+ */
119
+ interface CaptureIntent {
120
+ reason: CaptureReason;
121
+ screen: string | undefined;
122
+ ts: number;
123
+ }
124
+
125
+ /**
126
+ * Reasons that always bypass semantic dedup.
127
+ * These are explicit user/system requests that should ALWAYS produce a frame.
128
+ */
129
+ const BYPASS_DEDUP_REASONS: Set<CaptureReason> = new Set([
130
+ 'manual',
131
+ 'error-context',
132
+ 'frequency',
133
+ ]);
134
+
135
+ /**
136
+ * Minimum time (ms) between captures of the same semantic intent
137
+ * (same reason + same screen). Secondary heuristic only — the primary
138
+ * check is semantic (reason + screen identity).
139
+ */
140
+ const SAME_INTENT_COOLDOWN_MS = 300;
141
+
142
+ /**
143
+ * Time (ms) to defer an interaction capture before finalizing.
144
+ * If onScreenChange fires within this window (i.e. the tap caused navigation),
145
+ * the interaction capture is cancelled and absorbed into the navigation capture.
146
+ * If no navigation follows, the interaction captures normally after this delay.
147
+ * 200ms is long enough for most React navigation timings but short enough to feel instant.
148
+ */
149
+ const INTERACTION_SETTLE_MS = 200;
150
+
151
+ /**
152
+ * Grace window (ms) AFTER an interaction capture has already fired.
153
+ * If onScreenChange fires to a DIFFERENT screen within this window,
154
+ * the stale interaction frame is retroactively evicted and its tap
155
+ * metadata is carried forward to the navigation capture.
156
+ * Handles the intermittent case where navigation takes >INTERACTION_SETTLE_MS.
157
+ */
158
+ const LATE_ABSORPTION_GRACE_MS = 400;
159
+
160
+ // ─── Manager ────────────────────────────────────────────────────────────────
161
+
162
+ export class ReplayCaptureManager {
163
+ private sessionId: string;
164
+ private config: SessionReplayConfig;
165
+ private nativeCapture: NativeCaptureFn;
166
+ /** Optional native file-outbox path. When ready, frames stage→commit natively. */
167
+ private outboxCapture: OutboxFrameCapture | null;
168
+ private onFrameEmit: FrameEmitCallback | null = null;
169
+
170
+ private frames: ReplayFrame[] = [];
171
+ /** Set of frameIds near crashes never evict */
172
+ private protectedFrameIds = new Set<string>();
173
+ private frequencyTimer: ReturnType<typeof setInterval> | null = null;
174
+ private capturing = false;
175
+ private currentScreen: string | null = null;
176
+ private lastInteractionCapture = 0;
177
+
178
+ /**
179
+ * Session-bound generation counter.
180
+ * Incremented on stop(). All async capture work checks this before AND after
181
+ * native capture to ensure stale callbacks from a previous session lifecycle
182
+ * do not emit frames into a new session.
183
+ */
184
+ private captureGeneration = 0;
185
+
186
+ /**
187
+ * Tracked navigation capture timeout.
188
+ * Cancelled on stop() and on each new onScreenChange() call (debounce).
189
+ */
190
+ private pendingNavTimeout: ReturnType<typeof setTimeout> | null = null;
191
+ /** Screen associated with the pending navigation capture */
192
+ private pendingNavScreen: string | null = null;
193
+
194
+ /**
195
+ * Tracked scroll settle capture timeout.
196
+ * Cancelled on stop().
197
+ */
198
+ private pendingScrollTimeout: ReturnType<typeof setTimeout> | null = null;
199
+
200
+ /**
201
+ * Tracked loading end capture timeout.
202
+ * Cancelled on stop().
203
+ */
204
+ private pendingLoadingTimeout: ReturnType<typeof setTimeout> | null = null;
205
+ /** Screen associated with the pending loading capture */
206
+ private pendingLoadingScreen: string | null = null;
207
+
208
+ /**
209
+ * Pending interaction capture timeout.
210
+ * When a tap/gesture occurs, the capture is DEFERRED by INTERACTION_SETTLE_MS.
211
+ * If onScreenChange fires within that window (tap caused navigation), the
212
+ * pending interaction is cancelled and its tap metadata is carried forward
213
+ * to the navigation capture — ensuring the destination screen is captured
214
+ * instead of a stale pre-navigation screenshot.
215
+ * If no navigation follows, the interaction capture fires normally.
216
+ */
217
+ private pendingInteractionTimeout: ReturnType<typeof setTimeout> | null = null;
218
+ /** Interaction point metadata held while pending (carried to nav if absorbed) */
219
+ private pendingInteractionPoint: ReplayFrame['interactionPoint'] | undefined = undefined;
220
+ /** Screen at the time the pending interaction was created */
221
+ private pendingInteractionScreen: string | undefined = undefined;
222
+
223
+ /**
224
+ * Late absorption tracking.
225
+ * After an interaction capture fires, store its metadata so that
226
+ * a delayed onScreenChange can retroactively evict the stale frame
227
+ * and carry the tap metadata forward to the navigation capture.
228
+ */
229
+ private lastCompletedInteraction: {
230
+ frameId: string;
231
+ screen: string | undefined;
232
+ interactionPoint: ReplayFrame['interactionPoint'] | undefined;
233
+ ts: number;
234
+ } | null = null;
235
+
236
+ /**
237
+ * In-flight interaction tracking.
238
+ * Set when triggerCapture('interaction') starts the async native call and cleared
239
+ * when it completes. If onScreenChange fires for a DIFFERENT screen while a capture
240
+ * is in-flight, the capture is suppressed — the navigation frame is the correct state.
241
+ * Covers the race window between pendingInteractionTimeout firing and native returning,
242
+ * which neither pending-absorption nor late-absorption can reach.
243
+ */
244
+ private _inFlightInteractionScreen: string | undefined = undefined;
245
+ private _inFlightInteractionPoint: ReplayFrame['interactionPoint'] | undefined = undefined;
246
+ private _suppressInFlightInteraction = false;
247
+
248
+ /**
249
+ * Last completed capture intent — used for semantic dedup.
250
+ * Captures with the same reason + screen within SAME_INTENT_COOLDOWN_MS are suppressed.
251
+ */
252
+ private lastCaptureIntent: CaptureIntent | null = null;
253
+
254
+ // ── P2-0/1/5 capture state ──────────────────────────────────────────
255
+ /** P2-0: monotonic per-session sequence; first emitted frame is 1. */
256
+ private _sequenceCounter = 0;
257
+ /** P2-1: hash of the last EMITTED frame, for visual change detection. */
258
+ private _lastFrameHash: string | null = null;
259
+ /** P2-1/5: wall-clock of the last emitted keyframe (heartbeat base). */
260
+ private _lastKeyframeTs = 0;
261
+ /** P2-5: frameId of the last emitted keyframe — delta base reference. */
262
+ private _lastKeyframeId: string | null = null;
263
+ /**
264
+ * Screen the last emitted keyframe was captured on.
265
+ *
266
+ * Tracked alongside the id purely so `currentKeyframe()` can refuse to hand a frame to an
267
+ * event on a different screen. The id and timestamp alone cannot answer that, and a frame
268
+ * from the previous screen is worse than none — it attaches a tap to a photograph of
269
+ * somewhere else, which every layer downstream would then present with full confidence.
270
+ */
271
+ private _lastKeyframeScreen: string | null = null;
272
+ /** P2-5: emitted frames since the last keyframe (keyframe-interval guard). */
273
+ private _framesSinceKeyframe = 0;
274
+
275
+ constructor(
276
+ sessionId: string,
277
+ config: SessionReplayConfig,
278
+ nativeCapture: NativeCaptureFn,
279
+ outboxCapture?: OutboxFrameCapture | null,
280
+ ) {
281
+ this.sessionId = sessionId;
282
+ this.config = config;
283
+ this.nativeCapture = nativeCapture;
284
+ this.outboxCapture = outboxCapture ?? null;
285
+ }
286
+
287
+ // ─── Public API ─────────────────────────────────────────────────────
288
+
289
+ /**
290
+ * The keyframe that is still showing, or null.
291
+ *
292
+ * Answers "which picture was the user looking at" for an event that is about to be emitted,
293
+ * so a tap can carry the id of the frame it happened ON. Read-only; captures nothing.
294
+ *
295
+ * TWO CONDITIONS, both refusals rather than approximations:
296
+ *
297
+ * SAME SCREEN. A keyframe from the previous screen is not what the user was looking at.
298
+ * Navigation evicts the pending capture rather than re-pointing it, so after a screen
299
+ * change the newest keyframe genuinely belongs to somewhere else.
300
+ *
301
+ * STILL FRESH. A screen mutates constantly — a list loads, a banner rotates, a sheet is
302
+ * dismissed. Past `maxAgeMs` the stored picture stops being evidence of what is on screen,
303
+ * and stale evidence presented as current is the failure mode this whole feature exists to
304
+ * avoid. 10 s is deliberately conservative: the capture manager already photographs on
305
+ * interaction, navigation and scroll settle, so a genuinely active screen refreshes well
306
+ * inside it, and a screen quiet for longer than that is one nobody is interacting with.
307
+ *
308
+ * Returning null is a correct, common answer and downstream MUST treat it as "not captured"
309
+ * rather than as a default.
310
+ */
311
+ currentKeyframe(
312
+ screenName?: string,
313
+ maxAgeMs = 10_000,
314
+ now: number = Date.now(),
315
+ ): { frameId: string; screen: string | null; capturedAt: number } | null {
316
+ if (!this._lastKeyframeId || this._lastKeyframeTs <= 0) return null;
317
+ if (now - this._lastKeyframeTs > maxAgeMs) return null;
318
+ // Compared only when the caller knows its screen. An event with no screen cannot be shown
319
+ // to belong to this frame, so it does not get one.
320
+ if (!screenName || this._lastKeyframeScreen !== screenName) return null;
321
+ return {
322
+ frameId: this._lastKeyframeId,
323
+ screen: this._lastKeyframeScreen,
324
+ capturedAt: this._lastKeyframeTs,
325
+ };
326
+ }
327
+
328
+ /** Set callback for when a frame is captured */
329
+ setFrameEmitCallback(cb: FrameEmitCallback): void {
330
+ this.onFrameEmit = cb;
331
+ }
332
+
333
+ /** Start capture according to configured mode */
334
+ start(): void {
335
+ if (this.capturing) return;
336
+ this.capturing = true;
337
+
338
+ // P2-0/1/5: reset per-session capture state so sequence + keyframe tracking
339
+ // start clean for this session lifecycle.
340
+ this._sequenceCounter = 0;
341
+ this._lastFrameHash = null;
342
+ this._lastKeyframeTs = 0;
343
+ this._lastKeyframeId = null;
344
+ this._lastKeyframeScreen = null;
345
+ this._framesSinceKeyframe = 0;
346
+
347
+ // Start frequency timer if in frequency mode
348
+ if (this.config.captureMode === 'frequency') {
349
+ const intervalMs = Math.max(500, this.config.intervalMs);
350
+ this.frequencyTimer = setInterval(() => {
351
+ this.triggerCapture('frequency').catch(() => { });
352
+ }, intervalMs);
353
+ logger.debug(`[ReplayCaptureManager] Frequency mode: every ${intervalMs}ms`);
354
+ }
355
+
356
+ logger.debug(`[ReplayCaptureManager] Started (mode=${this.config.captureMode})`);
357
+ }
358
+
359
+ /** Stop capture — cancels ALL pending timers and increments generation */
360
+ stop(): void {
361
+ this.capturing = false;
362
+
363
+ // Increment generationinvalidates ALL in-flight async captures
364
+ this.captureGeneration++;
365
+
366
+ // Cancel frequency timer
367
+ if (this.frequencyTimer) {
368
+ clearInterval(this.frequencyTimer);
369
+ this.frequencyTimer = null;
370
+ }
371
+
372
+ // Cancel pending navigation capture
373
+ if (this.pendingNavTimeout) {
374
+ clearTimeout(this.pendingNavTimeout);
375
+ this.pendingNavTimeout = null;
376
+ this.pendingNavScreen = null;
377
+ }
378
+
379
+ // Cancel pending scroll capture
380
+ if (this.pendingScrollTimeout) {
381
+ clearTimeout(this.pendingScrollTimeout);
382
+ this.pendingScrollTimeout = null;
383
+ }
384
+
385
+ // Cancel pending loading capture
386
+ if (this.pendingLoadingTimeout) {
387
+ clearTimeout(this.pendingLoadingTimeout);
388
+ this.pendingLoadingTimeout = null;
389
+ this.pendingLoadingScreen = null;
390
+ }
391
+
392
+ // Cancel pending interaction capture
393
+ if (this.pendingInteractionTimeout) {
394
+ clearTimeout(this.pendingInteractionTimeout);
395
+ this.pendingInteractionTimeout = null;
396
+ this.pendingInteractionPoint = undefined;
397
+ this.pendingInteractionScreen = undefined;
398
+ }
399
+
400
+ // Clear late absorption tracking
401
+ this.lastCompletedInteraction = null;
402
+
403
+ // Clear in-flight interaction tracking
404
+ this._inFlightInteractionScreen = undefined;
405
+ this._inFlightInteractionPoint = undefined;
406
+ this._suppressInFlightInteraction = false;
407
+
408
+ // Clear dedup state
409
+ this.lastCaptureIntent = null;
410
+
411
+ logger.debug('[ReplayCaptureManager] Stopped (all timers cancelled, generation incremented)');
412
+ }
413
+
414
+ /** Notify of a screen change — triggers cancellable delayed capture */
415
+ onScreenChange(screenName: string): void {
416
+ this.currentScreen = screenName;
417
+
418
+ if (!this.capturing) return;
419
+ if (this._isExcludedScreen(screenName)) return;
420
+
421
+ if (this.config.captureMode === 'navigation' || this.config.captureMode === 'interactions') {
422
+ // Cancel any previous pending navigation capture (debounce rapid navigations)
423
+ if (this.pendingNavTimeout) {
424
+ clearTimeout(this.pendingNavTimeout);
425
+ this.pendingNavTimeout = null;
426
+ this.pendingNavScreen = null;
427
+ }
428
+
429
+ // Cancel any pending scroll capture — scroll on the old screen is now obsolete
430
+ if (this.pendingScrollTimeout) {
431
+ clearTimeout(this.pendingScrollTimeout);
432
+ this.pendingScrollTimeout = null;
433
+ }
434
+
435
+ // Cancel pending loading capture ONLY if it was for a DIFFERENT screen.
436
+ if (this.pendingLoadingTimeout && this.pendingLoadingScreen !== screenName) {
437
+ clearTimeout(this.pendingLoadingTimeout);
438
+ this.pendingLoadingTimeout = null;
439
+ this.pendingLoadingScreen = null;
440
+ }
441
+
442
+ // ── Absorb pending interaction if tap caused this navigation ──────
443
+ // If a tap was pending and the screen changed (tap → navigation),
444
+ // cancel the stale interaction capture and carry its tap metadata
445
+ // forward into the navigation capture.
446
+ let absorbedInteractionPoint: ReplayFrame['interactionPoint'] | undefined;
447
+ if (this.pendingInteractionTimeout) {
448
+ clearTimeout(this.pendingInteractionTimeout);
449
+ absorbedInteractionPoint = this.pendingInteractionPoint;
450
+ this.pendingInteractionTimeout = null;
451
+ this.pendingInteractionPoint = undefined;
452
+ this.pendingInteractionScreen = undefined;
453
+ logger.debug(
454
+ `[ReplayCaptureManager] Pending interaction absorbed by navigation to ${screenName}`,
455
+ );
456
+ }
457
+
458
+ // ── Late absorption: retroactively evict stale interaction frame ──
459
+ // If an interaction capture ALREADY completed (settle window expired)
460
+ // but navigation arrives within the grace window to a DIFFERENT screen,
461
+ // the interaction frame is stale (captured old screen). Evict it and
462
+ // carry its tap metadata forward to the navigation capture.
463
+ if (
464
+ !absorbedInteractionPoint &&
465
+ this.lastCompletedInteraction &&
466
+ this.lastCompletedInteraction.screen !== screenName &&
467
+ (Date.now() - this.lastCompletedInteraction.ts) < LATE_ABSORPTION_GRACE_MS
468
+ ) {
469
+ const stale = this.lastCompletedInteraction;
470
+ absorbedInteractionPoint = stale.interactionPoint;
471
+ // Evict the stale frame from the frames list
472
+ this.frames = this.frames.filter(f => f.frameId !== stale.frameId);
473
+ logger.debug(
474
+ `[ReplayCaptureManager] Late absorption: evicted stale interaction frame ` +
475
+ `${stale.frameId} on ${stale.screen}, navigation to ${screenName}`,
476
+ );
477
+ this.lastCompletedInteraction = null;
478
+ }
479
+
480
+ // ── In-flight interaction suppression ─────────────────────────
481
+ // If a native interaction capture started (settle timer already fired)
482
+ // but hasn't returned yet, suppress it — the navigation represents
483
+ // the correct visual state. Carry the tap point forward if available.
484
+ if (
485
+ !absorbedInteractionPoint &&
486
+ this._inFlightInteractionScreen !== undefined &&
487
+ this._inFlightInteractionScreen !== screenName
488
+ ) {
489
+ this._suppressInFlightInteraction = true;
490
+ if (this._inFlightInteractionPoint) {
491
+ absorbedInteractionPoint = this._inFlightInteractionPoint;
492
+ }
493
+ logger.debug(
494
+ `[ReplayCaptureManager] In-flight interaction suppressed by navigation to ${screenName}`,
495
+ );
496
+ }
497
+
498
+ // Track which screen this nav capture is for
499
+ this.pendingNavScreen = screenName;
500
+
501
+ // Brief delay to allow the new screen to render (but stay snappy)
502
+ this.pendingNavTimeout = setTimeout(() => {
503
+ this.pendingNavTimeout = null;
504
+ this.pendingNavScreen = null;
505
+ // Pass absorbed interaction point so the nav frame carries tap metadata
506
+ this.triggerCapture('navigation', screenName, absorbedInteractionPoint).catch(() => { });
507
+ }, 150);
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Notify of a user interaction — deferred capture with navigation absorption.
513
+ *
514
+ * Instead of capturing immediately (which would snapshot the OLD screen
515
+ * when the tap causes navigation), the capture is deferred by
516
+ * INTERACTION_SETTLE_MS. If onScreenChange fires within that window,
517
+ * the pending interaction is absorbed into the navigation capture.
518
+ * If no navigation follows, the interaction capture fires normally.
519
+ */
520
+ onInteraction(interactionPoint?: ReplayFrame['interactionPoint']): void {
521
+ if (!this.capturing) return;
522
+ if (this.currentScreen && this._isExcludedScreen(this.currentScreen)) return;
523
+
524
+ // Throttle: prevent duplicate captures from rapid gestures (500ms)
525
+ const now = Date.now();
526
+ if (now - this.lastInteractionCapture < 500) return;
527
+ this.lastInteractionCapture = now;
528
+
529
+ const screen = this.currentScreen ?? undefined;
530
+
531
+ // Semantic dedup: if a navigation capture is pending for the SAME screen,
532
+ // the navigation frame will represent the post-interaction state.
533
+ if (this.pendingNavTimeout && this.pendingNavScreen === screen) {
534
+ logger.debug('[ReplayCaptureManager] Interaction suppressed — navigation pending for same screen');
535
+ return;
536
+ }
537
+
538
+ // Cancel any previous pending interaction (rapid tap replacement)
539
+ if (this.pendingInteractionTimeout) {
540
+ clearTimeout(this.pendingInteractionTimeout);
541
+ }
542
+
543
+ // Defer the interaction capture to allow navigation to absorb it
544
+ this.pendingInteractionScreen = screen;
545
+ this.pendingInteractionPoint = interactionPoint;
546
+ this.pendingInteractionTimeout = setTimeout(() => {
547
+ this.pendingInteractionTimeout = null;
548
+ const captureScreen = this.pendingInteractionScreen;
549
+ const capturePoint = this.pendingInteractionPoint;
550
+ this.pendingInteractionScreen = undefined;
551
+ this.pendingInteractionPoint = undefined;
552
+ // No navigation followed → capture the interaction on the current screen
553
+ this.triggerCapture('interaction', captureScreen, capturePoint).catch(() => { });
554
+ }, INTERACTION_SETTLE_MS);
555
+ }
556
+
557
+ /** Notify of scroll settle — triggers delayed capture for post-scroll state */
558
+ onScrollSettle(screenName?: string): void {
559
+ if (!this.capturing) return;
560
+
561
+ // Cancel any previous pending scroll capture
562
+ if (this.pendingScrollTimeout) {
563
+ clearTimeout(this.pendingScrollTimeout);
564
+ this.pendingScrollTimeout = null;
565
+ }
566
+
567
+ // Small delay to let post-scroll rendering settle
568
+ this.pendingScrollTimeout = setTimeout(() => {
569
+ this.pendingScrollTimeout = null;
570
+ this.triggerCapture('scroll', screenName ?? this.currentScreen ?? undefined).catch(() => { });
571
+ }, 150);
572
+ }
573
+
574
+ /** Notify of loading end captures the settled loaded screen */
575
+ onLoadingEnd(screenName?: string): void {
576
+ if (!this.capturing) return;
577
+
578
+ const screen = screenName ?? this.currentScreen ?? undefined;
579
+
580
+ // Cancel any previous pending loading capture for ANY screen
581
+ if (this.pendingLoadingTimeout) {
582
+ clearTimeout(this.pendingLoadingTimeout);
583
+ this.pendingLoadingTimeout = null;
584
+ this.pendingLoadingScreen = null;
585
+ }
586
+
587
+ // If a navigation capture is pending for the SAME screen, cancel it.
588
+ // The loading-end capture represents the final settled state and supersedes
589
+ // the initial navigation capture (which would show loading/skeleton UI).
590
+ if (this.pendingNavTimeout && this.pendingNavScreen === screen) {
591
+ clearTimeout(this.pendingNavTimeout);
592
+ this.pendingNavTimeout = null;
593
+ this.pendingNavScreen = null;
594
+ logger.debug('[ReplayCaptureManager] Navigation capture cancelled — loading-end supersedes for same screen');
595
+ }
596
+
597
+ // Track which screen this loading capture is for
598
+ this.pendingLoadingScreen = screen ?? null;
599
+
600
+ // Slight delay to allow the loaded content to render
601
+ this.pendingLoadingTimeout = setTimeout(() => {
602
+ this.pendingLoadingTimeout = null;
603
+ this.pendingLoadingScreen = null;
604
+ this.triggerCapture('screen_loaded', screen).catch(() => { });
605
+ }, 200);
606
+ }
607
+
608
+ /** Manual capture trigger (e.g. error-context) */
609
+ async captureManual(reason: CaptureReason): Promise<ReplayFrame | null> {
610
+ return this.triggerCapture(reason, this.currentScreen ?? undefined);
611
+ }
612
+
613
+ /** Protect frames near a crash from eviction */
614
+ protectFramesNearCrash(crashTimestamp: number, windowMs: number = 10_000): string[] {
615
+ const protectedIds: string[] = [];
616
+ for (const frame of this.frames) {
617
+ if (Math.abs(frame.ts - crashTimestamp) <= windowMs) {
618
+ this.protectedFrameIds.add(frame.frameId);
619
+ protectedIds.push(frame.frameId);
620
+ }
621
+ }
622
+ return protectedIds;
623
+ }
624
+
625
+ /** Get all frames (read-only snapshot) */
626
+ getFrames(): readonly ReplayFrame[] {
627
+ return this.frames;
628
+ }
629
+
630
+ /** Get frame IDs for artifact index */
631
+ getFrameRefs(): string[] {
632
+ return this.frames.map(f => f.frameId);
633
+ }
634
+
635
+ /** Current frame count */
636
+ get count(): number {
637
+ return this.frames.length;
638
+ }
639
+
640
+ /** Clear all frames */
641
+ clear(): void {
642
+ this.frames = [];
643
+ this.protectedFrameIds.clear();
644
+ }
645
+
646
+ // ─── Core Capture ───────────────────────────────────────────────────
647
+
648
+ /**
649
+ * Trigger a frame capture via native engine.
650
+ * This method ONLY orchestrates native does the real work.
651
+ *
652
+ * Semantic dedup: if the last completed capture has the same reason + screen
653
+ * and happened within SAME_INTENT_COOLDOWN_MS, the capture is suppressed.
654
+ * Bypass reasons (manual, error-context, frequency) skip this check entirely.
655
+ *
656
+ * Session-bound generation guard: captures the generation counter before
657
+ * starting the async native capture and verifies it hasn't changed after.
658
+ * If it has, the capture result is silently discarded — the session that
659
+ * requested it no longer exists.
660
+ */
661
+ private async triggerCapture(
662
+ reason: CaptureReason,
663
+ screenName?: string,
664
+ interactionPoint?: ReplayFrame['interactionPoint'],
665
+ ): Promise<ReplayFrame | null> {
666
+ if (!this.capturing) return null;
667
+
668
+ // ── Semantic dedup check ────────────────────────────────────────
669
+ if (!BYPASS_DEDUP_REASONS.has(reason) && this.lastCaptureIntent) {
670
+ const last = this.lastCaptureIntent;
671
+ const sameScreen = last.screen === screenName;
672
+ const sameReason = last.reason === reason;
673
+ const withinCooldown = (Date.now() - last.ts) < SAME_INTENT_COOLDOWN_MS;
674
+
675
+ // Same reason + same screen within cooldown → semantic duplicate
676
+ if (sameReason && sameScreen && withinCooldown) {
677
+ logger.debug(
678
+ `[ReplayCaptureManager] Semantic dedup: ${reason}@${screenName} suppressed ` +
679
+ `(same intent within ${SAME_INTENT_COOLDOWN_MS}ms)`,
680
+ );
681
+ return null;
682
+ }
683
+ }
684
+
685
+ // Capture generation at call time
686
+ const gen = this.captureGeneration;
687
+
688
+ // ── In-flight interaction tracking ─────────────────────────────
689
+ // Mark this capture as in-flight so onScreenChange can suppress it
690
+ // if navigation arrives before the native callback returns.
691
+ if (reason === 'interaction') {
692
+ this._inFlightInteractionScreen = screenName;
693
+ this._inFlightInteractionPoint = interactionPoint;
694
+ this._suppressInFlightInteraction = false;
695
+ }
696
+
697
+ try {
698
+ // ── Capture path selection ──────────────────────────────────────
699
+ // Prefer the native file-outbox staged path when ready: it captures +
700
+ // masks + encodes natively and STAGES the image (bytes never cross the
701
+ // bridge). If the outbox is off / unavailable / the staged capture fails,
702
+ // fall back to the legacy native capture (base64 → JS upload). All
703
+ // orchestration below (dedup, change-detection, keyframe/delta, sequencing)
704
+ // is identical for both paths.
705
+ const screen = screenName ?? this.currentScreen ?? undefined;
706
+ let staged: StagedFrameResult | null = null;
707
+ if (this.outboxCapture) {
708
+ staged = await this.outboxCapture.capture(this.sessionId, screen, reason);
709
+ }
710
+ const usedStaged = staged !== null;
711
+
712
+ let result: NativeFrameResult | null;
713
+ if (staged) {
714
+ result = {
715
+ base64: '', // bytes stay native on the outbox path — never bridged
716
+ width: staged.width,
717
+ height: staged.height,
718
+ byteSize: staged.byteSize,
719
+ format: staged.format,
720
+ frameHash: staged.frameHash,
721
+ platform: staged.platform,
722
+ };
723
+ } else {
724
+ result = await this.nativeCapture(this.sessionId, reason, this.config.quality);
725
+ }
726
+
727
+ // Drop a staged frame if any guard below rejects it (keeps the outbox clean).
728
+ const discardStaged = (): void => {
729
+ if (usedStaged && staged) {
730
+ this.outboxCapture?.discard(this.sessionId, staged.frameId).catch(() => { });
731
+ }
732
+ };
733
+
734
+ // ── In-flight suppression check ─────────────────────────────
735
+ // Clear in-flight tracking first (before any early returns).
736
+ if (reason === 'interaction') {
737
+ this._inFlightInteractionScreen = undefined;
738
+ this._inFlightInteractionPoint = undefined;
739
+ if (this._suppressInFlightInteraction) {
740
+ this._suppressInFlightInteraction = false;
741
+ discardStaged();
742
+ logger.debug('[ReplayCaptureManager] In-flight interaction suppressed navigation arrived during capture');
743
+ return null;
744
+ }
745
+ }
746
+
747
+ // Generation guard: if session was stopped/restarted during async capture,
748
+ // discard the result to prevent stale frames
749
+ if (gen !== this.captureGeneration) {
750
+ discardStaged();
751
+ logger.debug('[ReplayCaptureManager] Stale capture discarded (generation mismatch)');
752
+ return null;
753
+ }
754
+
755
+ if (!this.capturing) {
756
+ discardStaged();
757
+ return null;
758
+ }
759
+
760
+ if (!result) {
761
+ // Native capture unavailable log warning, return null
762
+ // NO JS fallback this is by design
763
+ logger.debug('[ReplayCaptureManager] Native capture returned null — frame not captured');
764
+ return null;
765
+ }
766
+
767
+ // ── P2-1: change-triggered capture + heartbeat keyframe ─────────
768
+ // Visual suppression applies ONLY to the periodic 'frequency' lane — the
769
+ // sole source of redundant, visually-identical consecutive frames during
770
+ // static viewing (the −40–60% lever). Semantic captures (navigation /
771
+ // interaction / scroll / screen_loaded) are already change-driven and are
772
+ // handled by the semantic dedup above, so they always emit — visual-hashing
773
+ // them risks dropping a meaningful frame whose pixels happen to match.
774
+ // manual / error-context are explicit intent and likewise always emit.
775
+ // The heartbeat (maxKeyframeIntervalMs) forces a keyframe even when nothing
776
+ // changed, so static periods still have a frame AND deltas keep a fresh base.
777
+ // Suppressed frames do NOT consume a sequence number.
778
+ const now = Date.now();
779
+ const hash = result.frameHash ?? hashBase64(result.base64);
780
+ const explicit = reason === 'manual' || reason === 'error-context';
781
+ const maxKf = this.config.maxKeyframeIntervalMs ?? 5000;
782
+ const heartbeatDue = (now - this._lastKeyframeTs) >= maxKf;
783
+ const changed = hash !== this._lastFrameHash;
784
+ const changeDetection = this.config.changeDetection !== false;
785
+ if (changeDetection && reason === 'frequency' && !changed && !heartbeatDue) {
786
+ discardStaged();
787
+ logger.debug('[ReplayCaptureManager] Change-trigger suppressed identical frequency frame');
788
+ return null;
789
+ }
790
+
791
+ // ── P2-5: keyframe vs delta decision ────────────────────────────
792
+ // Force a keyframe when: delta encoding is off, no base exists yet, the
793
+ // heartbeat is due, the keyframe-interval elapsed, or this is an explicit
794
+ // capture (full frame is safest). Otherwise emit a delta against the last
795
+ // keyframe. NOTE: real delta-byte encoding is native (pixel ops); JS owns
796
+ // the decision/tagging — see P2_CONTRACT.md §3/§6.
797
+ const deltaOn = this.config.deltaEncoding === true;
798
+ const kfInterval = this.config.deltaKeyframeInterval ?? 10;
799
+ const mustKeyframe =
800
+ !deltaOn ||
801
+ this._lastKeyframeId === null ||
802
+ heartbeatDue ||
803
+ explicit ||
804
+ this._framesSinceKeyframe >= kfInterval;
805
+ const frameType: 'keyframe' | 'delta' = mustKeyframe ? 'keyframe' : 'delta';
806
+ const baseFrameId = frameType === 'delta' ? this._lastKeyframeId ?? undefined : undefined;
807
+
808
+ // Build frame with artifact reference and screen context.
809
+ // On the native-outbox staged path the image is ALREADY written to disk
810
+ // under the native-assigned frameId; reuse it so commitOutboxFrame's
811
+ // lookup resolves (minting a fresh id here makes the staged image
812
+ // "missing" at commit → the frame is silently dropped → zero frames).
813
+ // Legacy (base64) path has no staged file, so mint a new id.
814
+ const frameId = staged?.frameId ?? generateFrameId();
815
+
816
+ // Fill interactionPoint screen dimensions from the capture result.
817
+ // interactionPoint may come from an absorbed pending interaction
818
+ // (tap navigation), so attach it regardless of capture reason.
819
+ const resolvedInteraction = interactionPoint
820
+ ? { ...interactionPoint, screenWidth: result.width, screenHeight: result.height }
821
+ : undefined;
822
+
823
+ const frame: ReplayFrame = {
824
+ frameId,
825
+ sessionId: this.sessionId,
826
+ ts: now,
827
+ sequenceNumber: ++this._sequenceCounter,
828
+ frameType,
829
+ ...(baseFrameId ? { baseFrameId } : {}),
830
+ imageRef: frameId, // Artifact ref — transport resolves to actual content
831
+ width: result.width,
832
+ height: result.height,
833
+ byteSize: result.byteSize ?? 0,
834
+ format: result.format ?? 'jpeg',
835
+ quality: this.config.quality,
836
+ captureReason: reason,
837
+ sourcePlatform: result.platform,
838
+ screen: screenName ?? this.currentScreen ?? undefined,
839
+ // Attach interaction point if this was an interaction-driven capture
840
+ ...(resolvedInteraction ? { interactionPoint: resolvedInteraction } : {}),
841
+ };
842
+
843
+ // ── Record capture intent for dedup ─────────────────────────
844
+ this.lastCaptureIntent = {
845
+ reason,
846
+ screen: screenName,
847
+ ts: Date.now(),
848
+ };
849
+
850
+ // Enforce frame limit with priority-based eviction
851
+ if (this.frames.length >= this.config.maxFrames) {
852
+ this._evictLowestPriorityFrame();
853
+ }
854
+
855
+ this.frames.push(frame);
856
+
857
+ // ── P2-1/5: commit change-detection + keyframe tracking ─────────
858
+ this._lastFrameHash = hash;
859
+ if (frameType === 'keyframe') {
860
+ this._lastKeyframeId = frameId;
861
+ this._lastKeyframeTs = now;
862
+ this._lastKeyframeScreen = screenName ?? null;
863
+ this._framesSinceKeyframe = 0;
864
+ } else {
865
+ this._framesSinceKeyframe++;
866
+ }
867
+
868
+ // ── Deliver the frame ───────────────────────────────────────────
869
+ // Staged (native outbox) path: commit JS-authoritative metadata so the
870
+ // native uploader owns delivery. Do NOT also emit base64 to the JS
871
+ // transport — that would double-upload the frame. If commit fails the
872
+ // image is left staged (no meta) and swept as an orphan on next recover().
873
+ // Legacy path: emit base64 to the JS transport as before.
874
+ if (usedStaged && staged) {
875
+ const meta: OutboxFrameMeta = {
876
+ frameId: frame.frameId,
877
+ sessionId: this.sessionId,
878
+ timestamp: frame.ts,
879
+ sequenceNumber: frame.sequenceNumber,
880
+ frameType,
881
+ ...(baseFrameId ? { baseFrameId } : {}),
882
+ screenName: frame.screen ?? 'unknown',
883
+ trigger: reason,
884
+ format: staged.format,
885
+ contentType: staged.contentType,
886
+ width: staged.width,
887
+ height: staged.height,
888
+ sizeBytes: staged.byteSize,
889
+ masked: staged.masked,
890
+ };
891
+ try {
892
+ const committed = await this.outboxCapture?.commit(meta);
893
+ if (!committed) {
894
+ logger.debug('[ReplayCaptureManager] Outbox commit failed — frame staged but not uploadable');
895
+ }
896
+ } catch {
897
+ // Commit failure must not crash capture; orphan is swept later.
898
+ }
899
+ } else {
900
+ // Emit to transport — pass base64 as transport-layer data (not domain)
901
+ try {
902
+ this.onFrameEmit?.(frame, result.base64);
903
+ } catch {
904
+ // Transport emission must not crash capture
905
+ }
906
+ }
907
+
908
+ // ── Track completed interaction for late absorption ──────────
909
+ // If this was an interaction capture, record its metadata so that
910
+ // a delayed onScreenChange can retroactively evict it if navigation
911
+ // follows within LATE_ABSORPTION_GRACE_MS.
912
+ if (reason === 'interaction') {
913
+ this.lastCompletedInteraction = {
914
+ frameId: frame.frameId,
915
+ screen: frame.screen,
916
+ interactionPoint: frame.interactionPoint,
917
+ ts: Date.now(),
918
+ };
919
+ } else {
920
+ // Non-interaction captures clear the tracker — no late absorption needed
921
+ this.lastCompletedInteraction = null;
922
+ }
923
+
924
+ return frame;
925
+ } catch (err) {
926
+ // Clear in-flight tracking on error too
927
+ if (reason === 'interaction') {
928
+ this._inFlightInteractionScreen = undefined;
929
+ this._inFlightInteractionPoint = undefined;
930
+ this._suppressInFlightInteraction = false;
931
+ }
932
+ logger.error('[ReplayCaptureManager] Capture failed:', err);
933
+ return null;
934
+ }
935
+ }
936
+
937
+ // ─── Frame Retention ────────────────────────────────────────────────
938
+
939
+ /**
940
+ * Evict the frame with the lowest retention priority.
941
+ * Crash-adjacent and error-context frames are NEVER evicted before generic frames.
942
+ */
943
+ private _evictLowestPriorityFrame(): void {
944
+ let lowestIdx = -1;
945
+ let lowestPriority = Infinity;
946
+ let oldestTs = Infinity;
947
+
948
+ for (let i = 0; i < this.frames.length; i++) {
949
+ const frame = this.frames[i];
950
+ // Never evict protected (crash-adjacent) frames
951
+ if (this.protectedFrameIds.has(frame.frameId)) continue;
952
+
953
+ const priority = getFrameRetentionPriority(frame.captureReason);
954
+ if (priority < lowestPriority || (priority === lowestPriority && frame.ts < oldestTs)) {
955
+ lowestPriority = priority;
956
+ lowestIdx = i;
957
+ oldestTs = frame.ts;
958
+ }
959
+ }
960
+
961
+ if (lowestIdx >= 0) {
962
+ this.frames.splice(lowestIdx, 1);
963
+ } else {
964
+ // All protected — drop oldest anyway
965
+ this.frames.shift();
966
+ }
967
+ }
968
+
969
+ // ─── Helpers ────────────────────────────────────────────────────────
970
+
971
+ private _isExcludedScreen(screenName: string): boolean {
972
+ return this.config.privacyPolicy.captureExclusions.includes(screenName);
973
+ }
974
+ }
975
+
976
+ // ─── Utils ──────────────────────────────────────────────────────────────────
977
+
978
+ function generateFrameId(): string {
979
+ return `frm-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`;
980
+ }
981
+
982
+ /**
983
+ * P2-1 change detection: cheap, allocation-light FNV-1a over the base64 string.
984
+ * Exact-hash only — a perceptual/near-identical match is a native concern (the
985
+ * native layer may supply `frameHash`; this is the JS fallback). Sampling every
986
+ * Nth char keeps it O(1)-ish on large frames while still being change-sensitive.
987
+ */
988
+ function hashBase64(b64: string): string {
989
+ let h = 0x811c9dc5;
990
+ const len = b64.length;
991
+ const step = len > 4096 ? Math.ceil(len / 4096) : 1;
992
+ for (let i = 0; i < len; i += step) {
993
+ h ^= b64.charCodeAt(i);
994
+ h = Math.imul(h, 0x01000193);
995
+ }
996
+ // Fold in length so same-prefix different-length frames don't collide.
997
+ return `${(h >>> 0).toString(36)}-${len.toString(36)}`;
998
+ }