@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,1209 +1,1248 @@
1
- /**
2
- * ScaleBun SDK — Session Manager
3
- *
4
- * Central orchestrator for the unified session system.
5
- * Manages session lifecycle, wires pipeline + capture + transport + sync.
6
- *
7
- * Architecture:
8
- * - Singleton per debug session
9
- * - Creates and owns JourneyEventPipeline, ReplayCaptureManager,
10
- * DesktopSessionTransport, SyncDecisionEngine
11
- * - Receives events from ScaleBunDebugRoot (nav, interactions), DebugEventStream
12
- * (network, logs), and breadcrumbs
13
- * - Coordinates crash anchoring across events AND frames
14
- * - Auto-timeout via maxDurationMs
15
- */
16
-
17
- import { logger } from '../../core/logger/internalLogger';
18
- import type { DebugTransport } from '../../debug/transport';
19
- import type {
20
- Session,
21
- SessionMetadata,
22
- SessionReplayConfig,
23
- JourneyEventType,
24
- JourneyEventSeverity,
25
- JourneyEventSource,
26
- CrashAnchor,
27
- NativeSyncMetadata,
28
- SyncDecisionCallback,
29
- } from './sessionTypes';
30
- import { DEFAULT_SESSION_REPLAY_CONFIG } from './sessionTypes';
31
- import { JourneyEventPipeline } from './JourneyEventPipeline';
32
- import { ReplayCaptureManager, type NativeCaptureFn, type OutboxFrameCapture } from './ReplayCaptureManager';
33
- import { makeOutboxFrameCapture } from './outboxFrameCapture';
34
- import { DesktopSessionTransport } from './DesktopSessionTransport';
35
- import { SyncDecisionEngine } from './SyncDecisionEngine';
36
- import { ScrollTracker, type ScrollMetadata } from './ScrollTracker';
37
- import type { BackendSessionAdapter } from './BackendSessionAdapter';
38
- import type { JourneyEvent } from './sessionTypes';
39
- import { generateEventId } from '../replay/core/ids/sessionId';
40
- import { bridgeAdapter } from '../replay/bridge/adapters/bridgeAdapter';
41
- import { redactBody } from '../../debug/redaction';
42
- import { consumeCalibrationTarget } from '../journey/calibrationContext';
43
-
44
- // ─── Types ──────────────────────────────────────────────────────────────────
45
-
46
- /**
47
- * Max analytics-lane heatmap interactions emitted per foreground (analytics
48
- * session) window. Bounds ingest volume now that capture defaults ON; enough to
49
- * resolve hotspot density, the long tail is dropped (drop-newest beyond cap).
50
- */
51
- const HEATMAP_MAX_INTERACTIONS_PER_WINDOW = 200;
52
-
53
- export interface SessionManagerConfig {
54
- sessionReplay?: Partial<SessionReplayConfig>;
55
- syncPolicy?: SyncDecisionCallback;
56
- /**
57
- * Feature #4 (heatmaps): when true, tap/gesture coordinates are ALSO routed
58
- * to the always-on analytics lane so coords are captured even when no replay
59
- * recording is active. Additive does NOT change replay-recording capture.
60
- * Unset false at this layer (safety floor for direct construction); the
61
- * product default (true) is applied by ConfigSchema and passed in by the
62
- * bootstrapper. See ConfigSchema.captureInteractionHeatmap.
63
- */
64
- captureInteractionHeatmap?: boolean;
65
- }
66
-
67
- // ─── Singleton ──────────────────────────────────────────────────────────────
68
-
69
- let _instance: SessionManager | null = null;
70
-
71
- // ─── Session Manager ────────────────────────────────────────────────────────
72
-
73
- export class SessionManager {
74
- private desktopTransport: DesktopSessionTransport | null = null;
75
- private pipeline: JourneyEventPipeline;
76
- private captureManager: ReplayCaptureManager;
77
- private syncEngine: SyncDecisionEngine;
78
- private scrollTracker: ScrollTracker | null = null;
79
- private _backendTransport: BackendSessionAdapter | null = null;
80
- private config: SessionReplayConfig;
81
- /**
82
- * Feature #4 (heatmaps): route tap/gesture coords to the always-on analytics
83
- * lane even when no replay recording is active. Additive, opt-in (default off).
84
- */
85
- private _captureInteractionHeatmap = false;
86
- /**
87
- * Sampling cap for the analytics-lane heatmap emission. Now that capture is
88
- * ON by default, an unbounded one-event-per-gesture stream could materially
89
- * inflate ingest volume. We cap emitted interactions per analytics-session
90
- * window (finalize-scoped per foreground): the first N gestures define the
91
- * hotspot shape; the long tail is dropped. Resets when the window changes.
92
- */
93
- private _heatmapWindowSessionId: string | null = null;
94
- private _heatmapWindowCount = 0;
95
-
96
- private session: Session | null = null;
97
- private active = false;
98
- private timeoutTimer: ReturnType<typeof setTimeout> | null = null;
99
- private crashAnchors: CrashAnchor[] = [];
100
- /** Tracks loading-start timestamps per screen for duration computation */
101
- private loadingStartTimes = new Map<string, number>();
102
- /**
103
- * Always-tracked current screen name.
104
- * Updated by onScreenChange even when session is inactive, so that when
105
- * startSession is called we know what screen the user is currently on and
106
- * can emit the initial SCREEN_VIEW + navigation capture immediately.
107
- * This is read-only metadata does NOT produce events or frames while inactive.
108
- */
109
- private _lastKnownScreen: string | null = null;
110
- /** When the current screen was entered — the basis for SCREEN_EXIT's measured dwellMs. */
111
- private _screenEnteredAt: number | null = null;
112
-
113
- /**
114
- * Last screenshot-base dimensions reported by the native interaction tracker.
115
- * Stored in JS-coordinate units (dp on Android, pt on iOS) — both are the same
116
- * unit RN uses for pageX/pageY, so JS-fallback taps can divide directly without
117
- * additional conversion. This is the EXACT base the native screenshot is captured
118
- * in, and avoids using Dimensions.get('window') (which excludes system insets
119
- * differently across devices and pushes markers ~10% off vertically).
120
- */
121
- private _lastNativeViewportJsUnits: { width: number; height: number; space: string } | null = null;
122
-
123
- private _nativeCapture: NativeCaptureFn;
124
- private _rawTransport: DebugTransport | null;
125
- /** Memoized native file-outbox frame adapter (gated by the backend transport). */
126
- private _outboxFrameCapture: OutboxFrameCapture | null = null;
127
-
128
- constructor(
129
- debugTransport: DebugTransport | null,
130
- nativeCapture: NativeCaptureFn,
131
- managerConfig?: SessionManagerConfig,
132
- ) {
133
- this._rawTransport = debugTransport;
134
- this._nativeCapture = nativeCapture;
135
-
136
- // Merge config with defaults
137
- this.config = {
138
- ...DEFAULT_SESSION_REPLAY_CONFIG,
139
- ...managerConfig?.sessionReplay,
140
- privacyPolicy: {
141
- ...DEFAULT_SESSION_REPLAY_CONFIG.privacyPolicy,
142
- ...managerConfig?.sessionReplay?.privacyPolicy,
143
- },
144
- };
145
-
146
- // Create subsystems
147
- this.desktopTransport = debugTransport ? new DesktopSessionTransport(debugTransport) : null;
148
-
149
- this.pipeline = new JourneyEventPipeline('', {
150
- maxEventCount: this.config.maxEventCount,
151
- });
152
-
153
- this.captureManager = new ReplayCaptureManager(
154
- '',
155
- this.config,
156
- nativeCapture,
157
- this._getOutboxFrameCapture(),
158
- );
159
-
160
- this._captureInteractionHeatmap = managerConfig?.captureInteractionHeatmap === true;
161
-
162
- this.syncEngine = new SyncDecisionEngine(managerConfig?.syncPolicy);
163
-
164
- // Wire pipeline → transport (desktop + optional backend)
165
- this.pipeline.setEmitCallback((event) => {
166
- this.desktopTransport?.sendEvent(event);
167
- this._backendTransport?.sendEvent(event);
168
- });
169
-
170
- // Wire capture → transport (desktop + optional backend)
171
- this.captureManager.setFrameEmitCallback((frame, imageData) => {
172
- this.desktopTransport?.sendFrame(frame, imageData);
173
- this._backendTransport?.sendFrame(frame, imageData);
174
- });
175
- }
176
-
177
- // ─── Singleton Access ───────────────────────────────────────────────
178
-
179
- static getInstance(
180
- debugTransport: DebugTransport | null,
181
- nativeCapture: NativeCaptureFn,
182
- config?: SessionManagerConfig,
183
- ): SessionManager {
184
- if (!_instance) {
185
- _instance = new SessionManager(debugTransport, nativeCapture, config);
186
- }
187
- return _instance;
188
- }
189
-
190
- static getExistingInstance(): SessionManager | null {
191
- return _instance;
192
- }
193
-
194
- static resetInstance(): void {
195
- if (_instance) {
196
- _instance.endSession();
197
- }
198
- _instance = null;
199
- }
200
-
201
- /**
202
- * Attach a backend transport for uploading replay data to the backend API.
203
- * This is additive the existing desktop transport remains active if present.
204
- */
205
- setBackendTransport(transport: BackendSessionAdapter): void {
206
- this._backendTransport = transport;
207
- logger.info('[SessionManager] Backend transport attached (replay → backend upload enabled)');
208
- }
209
-
210
- /** Expose the backend transport so features can queue network/errors/performance. */
211
- getBackendTransport(): BackendSessionAdapter | null {
212
- return this._backendTransport;
213
- }
214
-
215
- /**
216
- * Memoized native file-outbox frame adapter. Always injected into the capture
217
- * manager; its readiness gate (backed by the backend transport) resolves false
218
- * when the outbox flags are off / the binary is old, so capture transparently
219
- * falls back to the legacy `captureScreenshot` path. The closure reads the
220
- * backend transport lazily at capture time (it attaches after construction).
221
- */
222
- private _getOutboxFrameCapture(): OutboxFrameCapture {
223
- if (!this._outboxFrameCapture) {
224
- this._outboxFrameCapture = makeOutboxFrameCapture(
225
- () => this._backendTransport?.ensureNativeOutboxReady() ?? Promise.resolve(false),
226
- );
227
- }
228
- return this._outboxFrameCapture;
229
- }
230
-
231
- /**
232
- * Attach a desktop transport dynamically.
233
- * Called when debug mode connects after SDK initialization.
234
- */
235
- setDesktopTransport(debugTransport: DebugTransport): void {
236
- this.desktopTransport = new DesktopSessionTransport(debugTransport);
237
- logger.info('[SessionManager] Desktop transport attached');
238
- }
239
-
240
- // ─── Session Lifecycle ──────────────────────────────────────────────
241
-
242
- get isActive(): boolean {
243
- return this.active;
244
- }
245
-
246
- get currentSessionId(): string | null {
247
- return this.session?.sessionId ?? null;
248
- }
249
-
250
- get currentSessionMetadata(): SessionMetadata | null {
251
- return this.session?.metadata ?? null;
252
- }
253
-
254
- /**
255
- * The active RECORDING session ID (`ses-xxx`), or null when no recording
256
- * is in progress.
257
- *
258
- * This is the canonical field that DebugEventStream stamps into every
259
- * outgoing event's `data.recordingSessionId`. It is the single source of
260
- * truth for correlating network and performance events with the session
261
- * that was active when they were captured.
262
- *
263
- * Distinct from the TRANSPORT session ID (`debug-xxx`) which lives on
264
- * the wire envelope's top-level `sessionId` field and never changes.
265
- */
266
- get recordingSessionId(): string | null {
267
- return this.active ? (this.session?.sessionId ?? null) : null;
268
- }
269
-
270
- /**
271
- * Update the native capture function at runtime.
272
- * Called by ScaleBunDebugRoot once the root View ref is ready for ViewShot.
273
- * Also updates the active session's capture manager if one exists.
274
- */
275
- setNativeCapture(captureFn: NativeCaptureFn): void {
276
- this._nativeCapture = captureFn;
277
- // Hot-swap into active capture manager if session is running
278
- if (this.active && this.captureManager) {
279
- (this.captureManager as any).nativeCapture = captureFn;
280
- logger.info('[SessionManager] Capture function updated (hot-swap)');
281
- }
282
- }
283
-
284
- /**
285
- * Start a new session. Idempotent — no-op if already active.
286
- */
287
- startSession(metadata?: Partial<SessionMetadata>): void {
288
- try {
289
- if (this.active) {
290
- logger.debug('[SessionManager] Session already active, skipping start');
291
- return;
292
- }
293
-
294
- // One-row merge: adopt the always-on analytics ingestion id as this
295
- // recording session's id when the backend (SaaS) lane has one open.
296
- // This threads the analytics id through the pipeline + capture manager
297
- // below, so every frame/event body carries it AND it becomes
298
- // currentSessionId at sendSessionStart keeping endpoint id == body id
299
- // while attaching frames/journey to the single analytics row (no second
300
- // INGESTION_START). Legacy/no-clientKey mode has no analytics id mint
301
- // a fresh recording id and post to /replay/... as before.
302
- const sessionId = this._backendTransport?.analyticsSessionId ?? generateSessionId();
303
-
304
- // Create fresh subsystems for this session
305
- this.pipeline = new JourneyEventPipeline(sessionId, {
306
- maxEventCount: this.config.maxEventCount,
307
- });
308
- this.pipeline.setEmitCallback((event) => {
309
- this.desktopTransport?.sendEvent(event);
310
- this._backendTransport?.sendEvent(event);
311
- });
312
-
313
- this.captureManager = new ReplayCaptureManager(
314
- sessionId,
315
- this.config,
316
- this._nativeCapture,
317
- this._getOutboxFrameCapture(),
318
- );
319
- this.captureManager.setFrameEmitCallback((frame, imageData) => {
320
- this.desktopTransport?.sendFrame(frame, imageData);
321
- this._backendTransport?.sendFrame(frame, imageData);
322
- });
323
-
324
- // Create scroll tracker — wired to emit events + trigger capture on settle
325
- this.scrollTracker = new ScrollTracker((scrollMeta: ScrollMetadata) => {
326
- if (!this.active) return;
327
-
328
- // Synthesize representative coordinates for the scroll.
329
- // ScrollTracker only knows content deltas — it has no absolute touch
330
- // point but the dashboard CorrelationEngine DROPS any interaction
331
- // without x/y, and the replay overlay draws scroll/swipe as an arrow
332
- // that needs normalizedEnd coords. Without this, ScaleBunScrollView scrolls
333
- // were invisible AND uncounted. Anchor the gesture at screen center and
334
- // extend by the finger displacement (opposite the content offset delta),
335
- // matching the finger-path convention native swipes already use.
336
- const vw = this.session?.metadata?.screenWidth ?? 0;
337
- const vh = this.session?.metadata?.screenHeight ?? 0;
338
- const coords: Record<string, number | boolean> = {};
339
- if (vw > 0 && vh > 0) {
340
- const cx = vw / 2;
341
- const cy = vh / 2;
342
- const ex = Math.max(0, Math.min(vw, cx - scrollMeta.totalDeltaX));
343
- const ey = Math.max(0, Math.min(vh, cy - scrollMeta.totalDeltaY));
344
- coords.x = cx;
345
- coords.y = cy;
346
- coords.endX = ex;
347
- coords.endY = ey;
348
- coords.normalizedX = cx / vw;
349
- coords.normalizedY = cy / vh;
350
- coords.normalizedEndX = ex / vw;
351
- coords.normalizedEndY = ey / vh;
352
- coords.viewportWidth = vw;
353
- coords.viewportHeight = vh;
354
- coords.normalizedPrecomputed = true;
355
- }
356
-
357
- // Emit gesture:scroll event.
358
- // emitEvent() triggers captureManager.onScrollSettle() internally
359
- // for USER_ACTION events with gestureType='scroll' — no explicit call needed.
360
- this.emitEvent('USER_ACTION', {
361
- subtype: 'gesture:scroll',
362
- payload: {
363
- gestureType: 'scroll',
364
- totalDeltaX: scrollMeta.totalDeltaX,
365
- totalDeltaY: scrollMeta.totalDeltaY,
366
- dominantDirection: scrollMeta.dominantDirection,
367
- direction: scrollMeta.dominantDirection,
368
- durationMs: scrollMeta.durationMs,
369
- startTs: scrollMeta.startTs,
370
- endTs: scrollMeta.endTs,
371
- confidence: 'high',
372
- ...coords,
373
- },
374
- source: 'user',
375
- });
376
- });
377
-
378
- this.crashAnchors = [];
379
- this.loadingStartTimes.clear();
380
-
381
- // Build session object
382
- this.session = {
383
- sessionId,
384
- deviceId: this._rawTransport?.deviceId ?? 'unknown',
385
- startedAt: Date.now(),
386
- status: 'active',
387
- metadata: {
388
- platform: (() => {
389
- try {
390
- const { Platform } = require('react-native');
391
- return Platform.OS === 'ios' ? 'ios' : 'android';
392
- } catch { return 'android'; }
393
- })(), // Real OS; enriched by native device info when available
394
- buildType: __DEV__ ? 'debug' : 'release',
395
- ...metadata,
396
- // Capture window dp dims here so emitEvent() can normalize coords
397
- // without re-querying Dimensions on every gesture event.
398
- ...(() => {
399
- if (metadata?.screenWidth && metadata?.screenHeight) return {};
400
- try {
401
- const { Dimensions } = require('react-native');
402
- const dims = Dimensions.get('window');
403
- if (dims.width > 0 && dims.height > 0) {
404
- return { screenWidth: dims.width, screenHeight: dims.height };
405
- }
406
- } catch { /* no-throw */ }
407
- return {};
408
- })(),
409
- },
410
- transportState: 'local',
411
- syncState: 'pending-evaluation',
412
- artifactIndex: {
413
- frameRefs: [],
414
- eventRefs: [],
415
- networkRefs: [],
416
- logRefs: [],
417
- crashAnchors: [],
418
- },
419
- };
420
-
421
- this.active = true;
422
-
423
- // Enrich the live session metadata with native device info (appVersion,
424
- // deviceModel, osVersion, …) so synchronous consumers — e.g. the engage
425
- // response builder reading `currentSessionMetadata.appVersion` — see real
426
- // values rather than the platform-only subset known at create time. The
427
- // session-start metadata above is the fallback when the bridge is
428
- // unavailable (old native binary). Fire-and-forget, never throws.
429
- Promise.resolve()
430
- .then(() => bridgeAdapter.getDeviceInfo())
431
- .then(info => {
432
- const s = this.session;
433
- if (!info || !s) return;
434
- const m = s.metadata;
435
- s.metadata = {
436
- ...m,
437
- appVersion: info.appVersion ?? m.appVersion,
438
- appName: info.appName ?? m.appName,
439
- bundleId: info.bundleId ?? m.bundleId,
440
- osVersion: info.osVersion ?? m.osVersion,
441
- deviceModel: info.deviceModel ?? m.deviceModel,
442
- };
443
- })
444
- .catch(() => {
445
- /* no-throw: metadata-only fallback */
446
- });
447
-
448
- // Notify transport (desktop + optional backend)
449
- this.desktopTransport?.sendSessionStart(this.session);
450
- this._backendTransport?.sendSessionStart(this.session);
451
-
452
- // Emit SESSION_STARTED event
453
- this.pipeline.emit('SESSION_STARTED', {
454
- payload: { sessionId },
455
- source: 'system',
456
- });
457
-
458
- // Start capture manager
459
- this.captureManager.start();
460
-
461
- // Set timeout
462
- if (this.config.maxDurationMs > 0) {
463
- this.timeoutTimer = setTimeout(() => {
464
- logger.debug('[SessionManager] Session timeout reached');
465
- this.endSession('timeout');
466
- }, this.config.maxDurationMs);
467
- }
468
-
469
- logger.info(`[SessionManager] Session started: ${sessionId}`);
470
-
471
- // ── Replay initial screen ──────────────────────────────────────
472
- // If the user was already on a screen before pressing Record
473
- // (typical: app mounted → screen hook fired → screen tracked),
474
- // emit the initial SCREEN_VIEW now so the session captures the
475
- // starting screen and triggers the first navigation frame.
476
- if (this._lastKnownScreen) {
477
- this.emitEvent('SCREEN_VIEW', {
478
- screen: this._lastKnownScreen,
479
- subtype: this._lastKnownScreen,
480
- source: 'sdk',
481
- });
482
- }
483
- } catch (err) {
484
- logger.error('[SessionManager] Failed to start session:', err);
485
- }
486
- }
487
-
488
- /**
489
- * End the current session.
490
- */
491
- endSession(reason: 'ended' | 'timeout' = 'ended'): void {
492
- // Fully idempotent — safe to call multiple times
493
- if (!this.active) {
494
- return;
495
- }
496
-
497
- // Disable collection FIRST to prevent any re-entrant emission during teardown
498
- this.active = false;
499
-
500
- // Guard: session must exist (should always be true if active was true)
501
- if (!this.session) return;
502
-
503
- try {
504
-
505
- // Clear timeout
506
- if (this.timeoutTimer) {
507
- clearTimeout(this.timeoutTimer);
508
- this.timeoutTimer = null;
509
- }
510
-
511
- // Dispose scroll tracker — cancels pending settle timer
512
- if (this.scrollTracker) {
513
- this.scrollTracker.dispose();
514
- this.scrollTracker = null;
515
- }
516
-
517
- // Clear loading state
518
- this.loadingStartTimes.clear();
519
-
520
- // Emit SESSION_ENDED event
521
- this.pipeline.emit('SESSION_ENDED', {
522
- payload: { reason },
523
- source: 'system',
524
- });
525
-
526
- // Stop capture — this cancels ALL pending timers and increments generation
527
- this.captureManager.stop();
528
-
529
- // Build final artifact index
530
- const eventRefs = this.pipeline.buildEventRefs();
531
- this.session.artifactIndex = {
532
- ...eventRefs,
533
- frameRefs: this.captureManager.getFrameRefs(),
534
- crashAnchors: this.crashAnchors,
535
- };
536
-
537
- // Finalize session
538
- this.session.endedAt = Date.now();
539
- this.session.status = reason === 'timeout' ? 'timeout' : 'ended';
540
-
541
- // Run sync evaluation
542
- const hasCrash = this.crashAnchors.length > 0;
543
- const hasError = this.pipeline.getEvents().some(
544
- e => e.type === 'ERROR_CAPTURED',
545
- );
546
-
547
- const candidate = SyncDecisionEngine.buildCandidate(
548
- this.session.sessionId,
549
- this.session.metadata,
550
- this.pipeline.count,
551
- this.captureManager.count,
552
- (this.session.endedAt - this.session.startedAt),
553
- hasCrash,
554
- hasError,
555
- );
556
-
557
- const decision = this.syncEngine.evaluate(candidate);
558
- this.session.syncState = decision.shouldSync ? 'eligible' : 'ineligible';
559
-
560
- // Notify transport (desktop + optional backend)
561
- this.desktopTransport?.sendSessionEnd(this.session);
562
- this._backendTransport?.sendSessionEnd(this.session);
563
-
564
- // Clean up
565
- this.pipeline.clear();
566
- this.captureManager.clear();
567
- // (this.active already set to false above)
568
-
569
- logger.info(
570
- `[SessionManager] Session ended: ${this.session.sessionId} ` +
571
- `(${reason}, sync=${decision.shouldSync}, priority=${decision.priority})`,
572
- );
573
- } catch (err) {
574
- logger.error('[SessionManager] Failed to end session:', err);
575
- // active is already false — no further cleanup needed
576
- }
577
- }
578
-
579
- // ─── Event Emission ─────────────────────────────────────────────────
580
-
581
- /**
582
- * Resolve the dp-space base used to normalize JS-fallback tap coordinates.
583
- *
584
- * The screenshot is captured by native in the content-view at its physical
585
- * pixel size. Normalized coords must divide by that SAME region (converted
586
- * to dp, since pageX/pageY are dp). Using Dimensions.get('window') (or
587
- * session.metadata, which is seeded from it) excludes system insets and is
588
- * ~10% smaller than the content-view — pushing markers off. Preference order:
589
- * native content-view (px→dp) → session metadata → payload → Dimensions.
590
- */
591
- private _resolveNormalizationBaseDp(
592
- p: Record<string, any>,
593
- ): { width: number; height: number; space: string } | null {
594
- // Native screenshot-base size in JS-coordinate units (dp on Android, pt on iOS).
595
- // This is the EXACT region the native screenshot was captured in, so JS-fallback
596
- // taps (pageX/pageY in dp/pt) divide directly into the same coord space the
597
- // marker overlay uses on the dashboard. Highest priority — session metadata
598
- // and Dimensions.get('window') report the app window which excludes system
599
- // insets differently across devices and pushes markers off vertically.
600
- if (this._lastNativeViewportJsUnits) {
601
- return {
602
- width: this._lastNativeViewportJsUnits.width,
603
- height: this._lastNativeViewportJsUnits.height,
604
- space: this._lastNativeViewportJsUnits.space,
605
- };
606
- }
607
-
608
- const mw = this.session?.metadata?.screenWidth;
609
- const mh = this.session?.metadata?.screenHeight;
610
- if (mw && mh) return { width: mw, height: mh, space: 'session-metadata-dp' };
611
-
612
- if (typeof p.viewportWidth === 'number' && p.viewportWidth > 0
613
- && typeof p.viewportHeight === 'number' && p.viewportHeight > 0) {
614
- return { width: p.viewportWidth, height: p.viewportHeight, space: 'payload-viewport-dp' };
615
- }
616
-
617
- try {
618
- const { Dimensions } = require('react-native');
619
- const dims = Dimensions.get('window');
620
- if (dims.width > 0 && dims.height > 0) {
621
- return { width: dims.width, height: dims.height, space: 'root-view-dp' };
622
- }
623
- } catch { /* no-throw */ }
624
-
625
- return null;
626
- }
627
-
628
- /**
629
- * Inject/resolve normalized tap coordinates into a USER_ACTION payload, in place.
630
- *
631
- * Mutates `p` to carry normalizedX/Y (+ end coords for swipes/scrolls) so the
632
- * heatmap can overlay them across viewport sizes. Returns true when the source
633
- * already provided high-confidence / pre-computed normalized coords (native or
634
- * JS-root-measured), false when this method JS-estimated them.
635
- *
636
- * Extracted from emitEvent so BOTH the replay-recording lane AND the always-on
637
- * analytics lane (Feature #4) normalize identically — keeping the tap payload
638
- * keys byte-for-byte the same on both routes.
639
- */
640
- private _normalizeInteractionPayload(p: Record<string, unknown>): boolean {
641
- // If native tracker already provided high-confidence normalized coords,
642
- // OR the JS path measured the root-view rect and precomputed normalized
643
- // coords against it, do not overwrite them with JS estimation.
644
- const hasNormalizedXY = typeof p.normalizedX === 'number'
645
- && typeof p.normalizedY === 'number';
646
- const alreadyNormalized = hasNormalizedXY
647
- && (p.confidence === 'high' || p.normalizedPrecomputed === true);
648
-
649
- if (alreadyNormalized) {
650
- // Cache the native screenshot base in JS-coordinate units (dp/pt)
651
- // so subsequent JS-fallback taps normalize against the same region
652
- // the screenshot was captured from. Android sends px (suffix -px),
653
- // iOS sends pt (suffix -pt). Both are converted to the unit RN
654
- // pageX/pageY use, so JS taps divide directly with no extra math.
655
- const cs = typeof p.coordinateSpace === 'string' ? p.coordinateSpace : '';
656
- if (typeof p.viewportWidth === 'number' && p.viewportWidth > 0
657
- && typeof p.viewportHeight === 'number' && p.viewportHeight > 0) {
658
- if (cs.endsWith('-px')) {
659
- try {
660
- const { PixelRatio } = require('react-native');
661
- const density = PixelRatio.get();
662
- if (density > 0) {
663
- this._lastNativeViewportJsUnits = {
664
- width: p.viewportWidth / density,
665
- height: p.viewportHeight / density,
666
- space: 'native-content-view-dp',
667
- };
668
- }
669
- } catch { /* no-throw */ }
670
- } else if (cs.endsWith('-pt')) {
671
- // iOS already in pt — same unit as RN pageX/pageY
672
- this._lastNativeViewportJsUnits = {
673
- width: p.viewportWidth,
674
- height: p.viewportHeight,
675
- space: 'native-window-pt',
676
- };
677
- }
678
- }
679
- } else {
680
- // Resolve the normalization base (in dp). Priority:
681
- // 1. session metadata screen size
682
- // 2. native content-view size (px → dp via PixelRatio) — matches screenshot
683
- // 3. payload viewport
684
- // 4. Dimensions.get('window') — last resort (excludes insets, ~10% off)
685
- const base = this._resolveNormalizationBaseDp(p);
686
-
687
- const x = typeof p.x === 'number' ? p.x : undefined;
688
- const y = typeof p.y === 'number' ? p.y : undefined;
689
- if (x !== undefined && y !== undefined && base) {
690
- p.normalizedX = Math.max(0, Math.min(1, x / base.width));
691
- p.normalizedY = Math.max(0, Math.min(1, y / base.height));
692
- p.viewportWidth = base.width;
693
- p.viewportHeight = base.height;
694
- p.coordinateSpace = base.space;
695
- }
696
-
697
- const endX = typeof p.endX === 'number' ? p.endX : undefined;
698
- const endY = typeof p.endY === 'number' ? p.endY : undefined;
699
- if (endX !== undefined && endY !== undefined && base) {
700
- p.normalizedEndX = Math.max(0, Math.min(1, endX / base.width));
701
- p.normalizedEndY = Math.max(0, Math.min(1, endY / base.height));
702
- }
703
- }
704
-
705
- return alreadyNormalized;
706
- }
707
-
708
- /**
709
- * Feature #4 (heatmaps) — additive analytics emission.
710
- *
711
- * Routes a tap/gesture to the always-on ANALYTICS lane (BackendSessionAdapter
712
- * .trackEvent) so coords are captured even when no replay recording is active.
713
- *
714
- * Strictly additive and isolated:
715
- * - Only runs when `_captureInteractionHeatmap` is ON (opt-in flag) AND a
716
- * backend analytics transport is attached AND no recording is active
717
- * (when active, the recording lane already emits the SAME USER_ACTION —
718
- * emitting here too would duplicate it).
719
- * - Reuses the EXACT recording payload shape (USER_ACTION + the same keys:
720
- * normalizedX, normalizedY, gestureType, screen, …) so the backend
721
- * aggregate reads them identically (no protocol/schema change).
722
- * - Normalizes via the same _normalizeInteractionPayload used by recording.
723
- * - Respects redaction: payload is passed through redactBody so any caller-
724
- * injected sensitive keys (e.g. a label) are stripped before transport.
725
- * - Never throws.
726
- */
727
- private _emitInteractionToAnalytics(gestureType: string, payload: Record<string, unknown>): void {
728
- if (!this._captureInteractionHeatmap) return;
729
- if (this.active) return; // recording lane already carries this tap
730
- const adapter = this._backendTransport;
731
- if (!adapter) return;
732
-
733
- // Per-foreground sampling cap. Reset the counter when the analytics
734
- // session window rolls over, then drop anything past the cap.
735
- const windowId = adapter.analyticsSessionId ?? '';
736
- if (windowId !== this._heatmapWindowSessionId) {
737
- this._heatmapWindowSessionId = windowId;
738
- this._heatmapWindowCount = 0;
739
- }
740
- if (this._heatmapWindowCount >= HEATMAP_MAX_INTERACTIONS_PER_WINDOW) return;
741
- this._heatmapWindowCount++;
742
-
743
- try {
744
- // Normalize coords in place (same logic as the recording lane).
745
- this._normalizeInteractionPayload(payload);
746
-
747
- // Respect redaction before handing to transport. redactBody returns a
748
- // new object and strips known-sensitive keys; coords/gesture survive.
749
- const safePayload = redactBody(payload) as Record<string, unknown>;
750
-
751
- const event: JourneyEvent = {
752
- eventId: generateEventId(),
753
- // sessionId is (re)stamped by the analytics lane at flush time.
754
- sessionId: adapter.analyticsSessionId ?? '',
755
- ts: Date.now(),
756
- type: 'USER_ACTION',
757
- subtype: `gesture:${gestureType}`,
758
- screen: this._lastKnownScreen ?? undefined,
759
- payload: safePayload,
760
- source: 'user',
761
- };
762
- adapter.trackEvent(event);
763
- } catch (err) {
764
- logger.error('[SessionManager] heatmap analytics emit failed:', err);
765
- }
766
- }
767
-
768
- /**
769
- * Emit a canonical event into the session pipeline.
770
- * This is the primary entry point for all event sources.
771
- */
772
- emitEvent(
773
- type: JourneyEventType,
774
- opts?: {
775
- subtype?: string;
776
- severity?: JourneyEventSeverity;
777
- screen?: string;
778
- payload?: Record<string, unknown>;
779
- correlationId?: string;
780
- traceId?: string;
781
- source?: JourneyEventSource;
782
- journeyId?: string;
783
- },
784
- ): void {
785
- if (!this.active) return;
786
-
787
- try {
788
- // Pre-process USER_ACTION events to inject normalized coordinates for heatmap readiness
789
- if (type === 'USER_ACTION' && opts?.payload) {
790
- const p = opts.payload;
791
-
792
- const alreadyNormalized = this._normalizeInteractionPayload(p);
793
-
794
- logger.debug(
795
- `[TapAccuracy] sink platform=${p.platform ?? '?'} space=${p.coordinateSpace ?? '?'} ` +
796
- `source=${alreadyNormalized ? (p.confidence === 'high' ? 'native-high' : 'js-precomputed') : 'js-estimated'} ` +
797
- `norm=(${p.normalizedX},${p.normalizedY}) base=(${p.viewportWidth}x${p.viewportHeight})`,
798
- );
799
-
800
- // ─── Diagnostic: merge calibration expected target (if a calibration
801
- // screen stamped it within the TTL) and emit ONE unified [TapDiag]
802
- // JSON object per gesture. Observability only no math runs here.
803
- const cal = consumeCalibrationTarget();
804
- if (cal) {
805
- p.expectedTargetId = cal.targetId;
806
- p.expectedNX = cal.expectedNX;
807
- p.expectedNY = cal.expectedNY;
808
- }
809
-
810
- try {
811
- const meta = this.session?.metadata as any | undefined;
812
- const diag = {
813
- tag: 'TapDiag',
814
- side: 'sdk',
815
- platform: p.platform ?? null,
816
- coordinateSource: alreadyNormalized
817
- ? (p.confidence === 'high' ? 'native-high' : 'js-precomputed')
818
- : 'js-estimated',
819
- coordinateSpace: p.coordinateSpace ?? null,
820
- targetId: p.expectedTargetId ?? p.target ?? null,
821
- expectedNX: p.expectedNX ?? null,
822
- expectedNY: p.expectedNY ?? null,
823
- rawX: p.x ?? null,
824
- rawY: p.y ?? null,
825
- pageX: p.pageX ?? null,
826
- pageY: p.pageY ?? null,
827
- locationX: p.locationX ?? null,
828
- locationY: p.locationY ?? null,
829
- normalizedX: p.normalizedX ?? null,
830
- normalizedY: p.normalizedY ?? null,
831
- viewportWidth: p.viewportWidth ?? null,
832
- viewportHeight: p.viewportHeight ?? null,
833
- rootViewWidth: p.rootViewWidth ?? null,
834
- rootViewHeight: p.rootViewHeight ?? null,
835
- rootViewLeft: p.rootViewLeft ?? null,
836
- rootViewTop: p.rootViewTop ?? null,
837
- screenWidth: p.screenWidth ?? meta?.screenWidth ?? null,
838
- screenHeight: p.screenHeight ?? meta?.screenHeight ?? null,
839
- windowWidth: p.windowWidth ?? null,
840
- windowHeight: p.windowHeight ?? null,
841
- statusBarHeight: p.statusBarHeight ?? null,
842
- safeAreaTop: p.safeAreaTop ?? null,
843
- timestamp: Date.now(),
844
- confidence: p.confidence ?? null,
845
- source: p.source ?? null,
846
- };
847
- // eslint-disable-next-line no-console
848
- console.log('[TapDiag]', JSON.stringify(diag));
849
- } catch { /* no-throw */ }
850
- }
851
-
852
- const event = this.pipeline.emit(type, opts);
853
-
854
- // Trigger capture on screen view or interaction
855
- if (event) {
856
- if (type === 'SCREEN_VIEW' && opts?.screen) {
857
- this.captureManager.onScreenChange(opts.screen);
858
- } else if (type === 'USER_ACTION') {
859
- // Extract interaction coordinates from the gesture payload
860
- // so the captured frame carries tap location metadata.
861
- const p = opts?.payload;
862
- const x = typeof p?.x === 'number' ? p.x : undefined;
863
- const y = typeof p?.y === 'number' ? p.y : undefined;
864
- const gestureType = typeof p?.gestureType === 'string' ? p.gestureType : undefined;
865
-
866
- // Scroll gestures use onScrollSettle (which debounces into a single
867
- // capture). Using onInteraction for scroll would produce a DUPLICATE
868
- // screenshot alongside the ScrollTracker's onScrollSettle call.
869
- if (gestureType === 'scroll') {
870
- this.captureManager.onScrollSettle(opts?.screen ?? this._lastKnownScreen ?? undefined);
871
- } else {
872
- let interactionPoint: import('./sessionTypes').ReplayFrame['interactionPoint'];
873
- if (x !== undefined && y !== undefined && gestureType) {
874
- interactionPoint = {
875
- x,
876
- y,
877
- normalizedX: typeof p?.normalizedX === 'number' ? p.normalizedX : undefined,
878
- normalizedY: typeof p?.normalizedY === 'number' ? p.normalizedY : undefined,
879
- screenWidth: this.session?.metadata?.screenWidth ?? 0,
880
- screenHeight: this.session?.metadata?.screenHeight ?? 0,
881
- viewportWidth: typeof p?.viewportWidth === 'number' ? p.viewportWidth : undefined,
882
- viewportHeight: typeof p?.viewportHeight === 'number' ? p.viewportHeight : undefined,
883
- gestureType,
884
- endX: typeof p?.endX === 'number' ? p.endX : undefined,
885
- endY: typeof p?.endY === 'number' ? p.endY : undefined,
886
- normalizedEndX: typeof p?.normalizedEndX === 'number' ? p.normalizedEndX : undefined,
887
- normalizedEndY: typeof p?.normalizedEndY === 'number' ? p.normalizedEndY : undefined,
888
- durationMs: typeof p?.durationMs === 'number' ? p.durationMs : undefined,
889
- direction: typeof p?.direction === 'string' ? p.direction : undefined,
890
- };
891
- }
892
-
893
- this.captureManager.onInteraction(interactionPoint);
894
- }
895
- }
896
- }
897
- } catch (err) {
898
- logger.error('[SessionManager] emitEvent failed:', err);
899
- }
900
- }
901
-
902
- /**
903
- * Anchor a crash in the session context.
904
- * Protects nearby events and frames from eviction.
905
- */
906
- anchorCrash(crashEventId: string): CrashAnchor | null {
907
- if (!this.active) return null;
908
-
909
- try {
910
- // Anchor events
911
- const anchor = this.pipeline.anchorCrash(crashEventId);
912
-
913
- // Anchor frames (protect frames near the crash timestamp)
914
- const crashEvent = this.pipeline.getEvents().find(
915
- e => e.eventId === crashEventId,
916
- );
917
- if (crashEvent) {
918
- const protectedFrameIds = this.captureManager.protectFramesNearCrash(crashEvent.ts);
919
- anchor.nearbyFrameIds = protectedFrameIds;
920
- }
921
-
922
- // Capture an error-context frame
923
- this.captureManager.captureManual('error-context').catch(() => { });
924
-
925
- this.crashAnchors.push(anchor);
926
-
927
- logger.debug(
928
- `[SessionManager] Crash anchored: ${crashEventId}, ` +
929
- `protected ${anchor.nearbyEventIds.length} events, ` +
930
- `${anchor.nearbyFrameIds.length} frames`,
931
- );
932
-
933
- return anchor;
934
- } catch (err) {
935
- logger.error('[SessionManager] anchorCrash failed:', err);
936
- return null;
937
- }
938
- }
939
-
940
- // ─── Navigation / Screen Integration ────────────────────────────────
941
-
942
- /**
943
- * Notify of a screen change. Called by ScaleBunDebugRoot via NavDetector.
944
- */
945
- /** The screen currently on top, or null before the first navigation is observed. */
946
- getLastKnownScreen(): string | null {
947
- return this._lastKnownScreen;
948
- }
949
-
950
- onScreenChange(screenName: string): void {
951
- // Always track the current screen — even when inactive.
952
- // This allows startSession to emit the initial SCREEN_VIEW for
953
- // the screen that was already mounted before Record was pressed.
954
- const previous = this._lastKnownScreen;
955
- const enteredAt = this._screenEnteredAt;
956
- this._lastKnownScreen = screenName;
957
- this._screenEnteredAt = Date.now();
958
-
959
- if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
960
-
961
- // SCREEN_EXIT for the screen being left, carrying its dwell time.
962
- //
963
- // The exit was previously detectable ONLY inside the Engage trigger engine and never became an
964
- // event, so time-on-screen had to be inferred from the gap to the NEXT SCREEN_VIEW — which is
965
- // wrong whenever the app backgrounds in between, and impossible for the last screen of a
966
- // session. Emitting it here makes dwell a measured value rather than a derived guess.
967
- if (previous && previous !== screenName && enteredAt != null) {
968
- this.emitEvent('SCREEN_EXIT', {
969
- screen: previous,
970
- subtype: previous,
971
- source: 'sdk',
972
- payload: { dwellMs: Math.max(0, Date.now() - enteredAt), to: screenName },
973
- });
974
- }
975
-
976
- this.emitEvent('SCREEN_VIEW', {
977
- screen: screenName,
978
- subtype: screenName,
979
- source: 'sdk',
980
- ...(previous && previous !== screenName ? { payload: { from: previous } } : {}),
981
- });
982
- }
983
-
984
- /**
985
- * Notify of a user interaction. Called by ScaleBunDebugRoot touch handlers.
986
- * Also triggers frame capture for desktop-initiated recordings.
987
- */
988
- onUserAction(subtype: string, payload?: Record<string, unknown>): void {
989
- if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
990
- this.emitEvent('USER_ACTION', {
991
- subtype,
992
- screen: this._lastKnownScreen ?? undefined,
993
- payload,
994
- source: 'user',
995
- });
996
- // NOTE: Do NOT call captureManager.onInteraction() here.
997
- // emitEvent() already triggers onInteraction() for USER_ACTION events (line ~405).
998
- // Calling it again here caused DUPLICATE frame captures per gesture.
999
- }
1000
-
1001
- /**
1002
- * Detailed gesture detection called by ScaleBunDebugRoot touch handlers.
1003
- * Emits a USER_ACTION event with gesture-specific subtype and payload.
1004
- */
1005
- onGestureDetected(gestureType: string, details?: {
1006
- x?: number;
1007
- y?: number;
1008
- endX?: number;
1009
- endY?: number;
1010
- duration?: number;
1011
- durationMs?: number;
1012
- direction?: string;
1013
- target?: string;
1014
- viewportWidth?: number;
1015
- viewportHeight?: number;
1016
- pageX?: number;
1017
- pageY?: number;
1018
- locationX?: number;
1019
- locationY?: number;
1020
- normalizedX?: number;
1021
- normalizedY?: number;
1022
- normalizedEndX?: number;
1023
- normalizedEndY?: number;
1024
- confidence?: string;
1025
- coordinateSpace?: string;
1026
- source?: string;
1027
- // Pre-computed normalization flag set by JS fallback when it normalized
1028
- // against the measured root-view rect (the exact view the screenshot captures).
1029
- // Without this flag, SessionManager.emitEvent would overwrite the pre-computed
1030
- // values via _resolveNormalizationBaseDp using a potentially-different base.
1031
- normalizedPrecomputed?: boolean;
1032
- // Diagnostic fields used by the dashboard to verify capture-space alignment.
1033
- statusBarHeight?: number;
1034
- safeAreaTop?: number;
1035
- rootViewTop?: number;
1036
- rootViewLeft?: number;
1037
- rootViewWidth?: number;
1038
- rootViewHeight?: number;
1039
- windowWidth?: number;
1040
- windowHeight?: number;
1041
- screenshotCropTop?: number;
1042
- screenWidth?: number;
1043
- screenHeight?: number;
1044
- platform?: string;
1045
- }): void {
1046
- // Build the canonical gesture payload ONCE so the recording lane and the
1047
- // (additive) analytics lane carry byte-identical keys (normalizedX/Y,
1048
- // gestureType, etc.). Same object shape that was previously inlined.
1049
- const payload: Record<string, unknown> = {
1050
- gestureType,
1051
- x: details?.x,
1052
- y: details?.y,
1053
- endX: details?.endX,
1054
- endY: details?.endY,
1055
- duration: details?.duration ?? details?.durationMs,
1056
- durationMs: details?.durationMs ?? details?.duration,
1057
- direction: details?.direction,
1058
- target: details?.target,
1059
- viewportWidth: details?.viewportWidth,
1060
- viewportHeight: details?.viewportHeight,
1061
- pageX: details?.pageX,
1062
- pageY: details?.pageY,
1063
- locationX: details?.locationX,
1064
- locationY: details?.locationY,
1065
- // Native / JS-precomputed coords — passed through without overwriting
1066
- normalizedX: details?.normalizedX,
1067
- normalizedY: details?.normalizedY,
1068
- normalizedEndX: details?.normalizedEndX,
1069
- normalizedEndY: details?.normalizedEndY,
1070
- confidence: details?.confidence,
1071
- coordinateSpace: details?.coordinateSpace,
1072
- source: details?.source,
1073
- normalizedPrecomputed: details?.normalizedPrecomputed,
1074
- statusBarHeight: details?.statusBarHeight,
1075
- safeAreaTop: details?.safeAreaTop,
1076
- rootViewTop: details?.rootViewTop,
1077
- rootViewLeft: details?.rootViewLeft,
1078
- rootViewWidth: details?.rootViewWidth,
1079
- rootViewHeight: details?.rootViewHeight,
1080
- windowWidth: details?.windowWidth,
1081
- windowHeight: details?.windowHeight,
1082
- screenshotCropTop: details?.screenshotCropTop,
1083
- screenWidth: details?.screenWidth,
1084
- screenHeight: details?.screenHeight,
1085
- platform: details?.platform,
1086
- };
1087
-
1088
- // ── Feature #4 (heatmaps): additive analytics emission ──
1089
- // When NOT recording, route the tap to the always-on analytics lane so
1090
- // heatmaps still get coords (opt-in via captureInteractionHeatmap). No-op
1091
- // when the flag is OFF, no backend transport is attached, or recording is
1092
- // active (the recording path below already carries this tap). Uses a fresh
1093
- // payload clone so analytics normalization never mutates the recording one.
1094
- this._emitInteractionToAnalytics(gestureType, { ...payload });
1095
-
1096
- if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
1097
- // The subtype becomes `ReplayEvent.label`, which is what the Events explorer GROUPS BY. Naming
1098
- // the tapped control here is what splits taps per control instead of collapsing every tap in the
1099
- // app into one `gesture:tap` row. Falls back to the bare gesture when nothing identified the
1100
- // target, so behaviour is unchanged for taps that cannot be resolved.
1101
- //
1102
- // ⚠️ `gestureType` also travels in the payload, and the backend's `resolveGesture` reads THAT
1103
- // first — so enriching the label cannot change heatmap gesture classification.
1104
- const target = typeof details?.target === 'string' ? details.target.trim() : '';
1105
- this.onUserAction(target ? `gesture:${gestureType} · ${target}` : `gesture:${gestureType}`, payload);
1106
- }
1107
-
1108
- /**
1109
- * Manual frame capture — triggered by Desktop "Capture Step" button.
1110
- */
1111
- async captureManualFrame(): Promise<{ frameId?: string } | null> {
1112
- if (!this.active || !this.captureManager) return null; // No capture when recording is OFF
1113
- const frame = await this.captureManager.captureManual('manual');
1114
- return frame ? { frameId: frame.frameId } : null;
1115
- }
1116
-
1117
- /**
1118
- * Notify of app lifecycle change.
1119
- */
1120
- onLifecycleChange(state: 'foreground' | 'background'): void {
1121
- this.emitEvent(
1122
- state === 'foreground' ? 'APP_FOREGROUND' : 'APP_BACKGROUND',
1123
- { source: 'system' },
1124
- );
1125
- }
1126
-
1127
- // ─── Scroll Integration ─────────────────────────────────────────────
1128
-
1129
- /**
1130
- * Notify of a scroll event from a scrollable surface (ScaleBunScrollView).
1131
- * Delegates to ScrollTracker for accumulation and settle detection.
1132
- */
1133
- onScrollEvent(contentOffsetX: number, contentOffsetY: number): void {
1134
- if (!this.active) return;
1135
- this.scrollTracker?.onScrollEvent(contentOffsetX, contentOffsetY);
1136
- }
1137
-
1138
- // ─── Loading State Integration ──────────────────────────────────────
1139
-
1140
- /**
1141
- * Notify that a screen has started loading.
1142
- * Explicit instrumentation NOT auto-called on screen entry.
1143
- * Call from app code: ScaleBun.markLoadingStarted('ScreenName')
1144
- */
1145
- onLoadingStarted(screenName: string): void {
1146
- if (!this.active) return;
1147
-
1148
- this.loadingStartTimes.set(screenName, Date.now());
1149
-
1150
- this.emitEvent('LOADING_STARTED', {
1151
- screen: screenName,
1152
- subtype: screenName,
1153
- payload: { screen: screenName },
1154
- source: 'sdk',
1155
- });
1156
- }
1157
-
1158
- /**
1159
- * Notify that a screen has finished loading.
1160
- * Explicit instrumentation — call from app code.
1161
- * Triggers a 'screen_loaded' frame capture for the settled state.
1162
- */
1163
- onLoadingCompleted(screenName: string): void {
1164
- if (!this.active) return;
1165
-
1166
- const startTime = this.loadingStartTimes.get(screenName);
1167
- const durationMs = startTime ? Date.now() - startTime : undefined;
1168
- this.loadingStartTimes.delete(screenName);
1169
-
1170
- this.emitEvent('LOADING_COMPLETED', {
1171
- screen: screenName,
1172
- subtype: screenName,
1173
- payload: {
1174
- screen: screenName,
1175
- durationMs,
1176
- },
1177
- source: 'sdk',
1178
- });
1179
-
1180
- // Capture the settled loaded screen
1181
- this.captureManager.onLoadingEnd(screenName);
1182
- }
1183
-
1184
- // ─── Sync Policy ────────────────────────────────────────────────────
1185
-
1186
- /**
1187
- * Override the sync policy. SDK-owned — native only provides metadata.
1188
- */
1189
- setSyncPolicy(policy: SyncDecisionCallback): void {
1190
- this.syncEngine.setPolicy(policy);
1191
- }
1192
-
1193
- /**
1194
- * Provide native-gathered sync metadata for the current session.
1195
- * Does NOT make the sync decision — that stays in SDK's SyncDecisionEngine.
1196
- */
1197
- setNativeSyncMetadata(metadata: NativeSyncMetadata): void {
1198
- // Stored for use at session end evaluation
1199
- if (this.session) {
1200
- (this.session as any)._nativeSyncMetadata = metadata;
1201
- }
1202
- }
1203
- }
1204
-
1205
- // ─── Helpers ────────────────────────────────────────────────────────────────
1206
-
1207
- function generateSessionId(): string {
1208
- return `ses-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`;
1209
- }
1
+ /**
2
+ * ScaleBun SDK — Session Manager
3
+ *
4
+ * Central orchestrator for the unified session system.
5
+ * Manages session lifecycle, wires pipeline + capture + transport + sync.
6
+ *
7
+ * Architecture:
8
+ * - Singleton per debug session
9
+ * - Creates and owns JourneyEventPipeline, ReplayCaptureManager,
10
+ * DesktopSessionTransport, SyncDecisionEngine
11
+ * - Receives events from ScaleBunDebugRoot (nav, interactions), DebugEventStream
12
+ * (network, logs), and breadcrumbs
13
+ * - Coordinates crash anchoring across events AND frames
14
+ * - Auto-timeout via maxDurationMs
15
+ */
16
+
17
+ import { logger } from '../../core/logger/internalLogger';
18
+ import type { DebugTransport } from '../../debug/transport';
19
+ import type {
20
+ Session,
21
+ SessionMetadata,
22
+ SessionReplayConfig,
23
+ JourneyEventType,
24
+ JourneyEventSeverity,
25
+ JourneyEventSource,
26
+ CrashAnchor,
27
+ NativeSyncMetadata,
28
+ SyncDecisionCallback,
29
+ } from './sessionTypes';
30
+ import { DEFAULT_SESSION_REPLAY_CONFIG } from './sessionTypes';
31
+ import { JourneyEventPipeline } from './JourneyEventPipeline';
32
+ import { ReplayCaptureManager, type NativeCaptureFn, type OutboxFrameCapture } from './ReplayCaptureManager';
33
+ import { makeOutboxFrameCapture } from './outboxFrameCapture';
34
+ import { DesktopSessionTransport } from './DesktopSessionTransport';
35
+ import { SyncDecisionEngine } from './SyncDecisionEngine';
36
+ import { ScrollTracker, type ScrollMetadata } from './ScrollTracker';
37
+ import type { BackendSessionAdapter } from './BackendSessionAdapter';
38
+ import type { JourneyEvent } from './sessionTypes';
39
+ import { generateEventId } from '../replay/core/ids/sessionId';
40
+ import { bridgeAdapter } from '../replay/bridge/adapters/bridgeAdapter';
41
+ import { redactBody } from '../../debug/redaction';
42
+ import { consumeCalibrationTarget } from '../journey/calibrationContext';
43
+ import { resolvePlatformOS } from '../../core/context/device';
44
+
45
+ // ─── Types ──────────────────────────────────────────────────────────────────
46
+
47
+ /**
48
+ * Max analytics-lane heatmap interactions emitted per foreground (analytics
49
+ * session) window. Bounds ingest volume now that capture defaults ON; enough to
50
+ * resolve hotspot density, the long tail is dropped (drop-newest beyond cap).
51
+ */
52
+ const HEATMAP_MAX_INTERACTIONS_PER_WINDOW = 200;
53
+
54
+ export interface SessionManagerConfig {
55
+ sessionReplay?: Partial<SessionReplayConfig>;
56
+ syncPolicy?: SyncDecisionCallback;
57
+ /**
58
+ * Feature #4 (heatmaps): when true, tap/gesture coordinates are ALSO routed
59
+ * to the always-on analytics lane so coords are captured even when no replay
60
+ * recording is active. Additive does NOT change replay-recording capture.
61
+ * Unset false at this layer (safety floor for direct construction); the
62
+ * product default (true) is applied by ConfigSchema and passed in by the
63
+ * bootstrapper. See ConfigSchema.captureInteractionHeatmap.
64
+ */
65
+ captureInteractionHeatmap?: boolean;
66
+ }
67
+
68
+ // ─── Singleton ──────────────────────────────────────────────────────────────
69
+
70
+ let _instance: SessionManager | null = null;
71
+
72
+ // ─── Session Manager ────────────────────────────────────────────────────────
73
+
74
+ export class SessionManager {
75
+ private desktopTransport: DesktopSessionTransport | null = null;
76
+ private pipeline: JourneyEventPipeline;
77
+ private captureManager: ReplayCaptureManager;
78
+ private syncEngine: SyncDecisionEngine;
79
+ private scrollTracker: ScrollTracker | null = null;
80
+ private _backendTransport: BackendSessionAdapter | null = null;
81
+ private config: SessionReplayConfig;
82
+ /**
83
+ * Feature #4 (heatmaps): route tap/gesture coords to the always-on analytics
84
+ * lane even when no replay recording is active. Additive, opt-in (default off).
85
+ */
86
+ private _captureInteractionHeatmap = false;
87
+ /**
88
+ * Sampling cap for the analytics-lane heatmap emission. Now that capture is
89
+ * ON by default, an unbounded one-event-per-gesture stream could materially
90
+ * inflate ingest volume. We cap emitted interactions per analytics-session
91
+ * window (finalize-scoped per foreground): the first N gestures define the
92
+ * hotspot shape; the long tail is dropped. Resets when the window changes.
93
+ */
94
+ private _heatmapWindowSessionId: string | null = null;
95
+ private _heatmapWindowCount = 0;
96
+
97
+ private session: Session | null = null;
98
+ private active = false;
99
+ private timeoutTimer: ReturnType<typeof setTimeout> | null = null;
100
+ private crashAnchors: CrashAnchor[] = [];
101
+ /** Tracks loading-start timestamps per screen for duration computation */
102
+ private loadingStartTimes = new Map<string, number>();
103
+ /**
104
+ * Always-tracked current screen name.
105
+ * Updated by onScreenChange even when session is inactive, so that when
106
+ * startSession is called we know what screen the user is currently on and
107
+ * can emit the initial SCREEN_VIEW + navigation capture immediately.
108
+ * This is read-only metadata — does NOT produce events or frames while inactive.
109
+ */
110
+ private _lastKnownScreen: string | null = null;
111
+ /** When the current screen was entered — the basis for SCREEN_EXIT's measured dwellMs. */
112
+ private _screenEnteredAt: number | null = null;
113
+
114
+ /**
115
+ * Last screenshot-base dimensions reported by the native interaction tracker.
116
+ * Stored in JS-coordinate units (dp on Android, pt on iOS) both are the same
117
+ * unit RN uses for pageX/pageY, so JS-fallback taps can divide directly without
118
+ * additional conversion. This is the EXACT base the native screenshot is captured
119
+ * in, and avoids using Dimensions.get('window') (which excludes system insets
120
+ * differently across devices and pushes markers ~10% off vertically).
121
+ */
122
+ private _lastNativeViewportJsUnits: { width: number; height: number; space: string } | null = null;
123
+
124
+ private _nativeCapture: NativeCaptureFn;
125
+ private _rawTransport: DebugTransport | null;
126
+ /** Memoized native file-outbox frame adapter (gated by the backend transport). */
127
+ private _outboxFrameCapture: OutboxFrameCapture | null = null;
128
+
129
+ constructor(
130
+ debugTransport: DebugTransport | null,
131
+ nativeCapture: NativeCaptureFn,
132
+ managerConfig?: SessionManagerConfig,
133
+ ) {
134
+ this._rawTransport = debugTransport;
135
+ this._nativeCapture = nativeCapture;
136
+
137
+ // Merge config with defaults
138
+ this.config = {
139
+ ...DEFAULT_SESSION_REPLAY_CONFIG,
140
+ ...managerConfig?.sessionReplay,
141
+ privacyPolicy: {
142
+ ...DEFAULT_SESSION_REPLAY_CONFIG.privacyPolicy,
143
+ ...managerConfig?.sessionReplay?.privacyPolicy,
144
+ },
145
+ };
146
+
147
+ // Create subsystems
148
+ this.desktopTransport = debugTransport ? new DesktopSessionTransport(debugTransport) : null;
149
+
150
+ this.pipeline = new JourneyEventPipeline('', {
151
+ maxEventCount: this.config.maxEventCount,
152
+ });
153
+
154
+ this.captureManager = new ReplayCaptureManager(
155
+ '',
156
+ this.config,
157
+ nativeCapture,
158
+ this._getOutboxFrameCapture(),
159
+ );
160
+
161
+ this._captureInteractionHeatmap = managerConfig?.captureInteractionHeatmap === true;
162
+
163
+ this.syncEngine = new SyncDecisionEngine(managerConfig?.syncPolicy);
164
+
165
+ // Wire pipeline → transport (desktop + optional backend)
166
+ this.pipeline.setEmitCallback((event) => {
167
+ this.desktopTransport?.sendEvent(event);
168
+ this._backendTransport?.sendEvent(event);
169
+ });
170
+
171
+ // Wire capture → transport (desktop + optional backend)
172
+ this.captureManager.setFrameEmitCallback((frame, imageData) => {
173
+ this.desktopTransport?.sendFrame(frame, imageData);
174
+ this._backendTransport?.sendFrame(frame, imageData);
175
+ });
176
+ }
177
+
178
+ // ─── Singleton Access ───────────────────────────────────────────────
179
+
180
+ static getInstance(
181
+ debugTransport: DebugTransport | null,
182
+ nativeCapture: NativeCaptureFn,
183
+ config?: SessionManagerConfig,
184
+ ): SessionManager {
185
+ if (!_instance) {
186
+ _instance = new SessionManager(debugTransport, nativeCapture, config);
187
+ }
188
+ return _instance;
189
+ }
190
+
191
+ static getExistingInstance(): SessionManager | null {
192
+ return _instance;
193
+ }
194
+
195
+ static resetInstance(): void {
196
+ if (_instance) {
197
+ _instance.endSession();
198
+ }
199
+ _instance = null;
200
+ }
201
+
202
+ /**
203
+ * Attach a backend transport for uploading replay data to the backend API.
204
+ * This is additive — the existing desktop transport remains active if present.
205
+ */
206
+ setBackendTransport(transport: BackendSessionAdapter): void {
207
+ this._backendTransport = transport;
208
+ logger.info('[SessionManager] Backend transport attached (replay → backend upload enabled)');
209
+ }
210
+
211
+ /** Expose the backend transport so features can queue network/errors/performance. */
212
+ getBackendTransport(): BackendSessionAdapter | null {
213
+ return this._backendTransport;
214
+ }
215
+
216
+ /**
217
+ * Memoized native file-outbox frame adapter. Always injected into the capture
218
+ * manager; its readiness gate (backed by the backend transport) resolves false
219
+ * when the outbox flags are off / the binary is old, so capture transparently
220
+ * falls back to the legacy `captureScreenshot` path. The closure reads the
221
+ * backend transport lazily at capture time (it attaches after construction).
222
+ */
223
+ private _getOutboxFrameCapture(): OutboxFrameCapture {
224
+ if (!this._outboxFrameCapture) {
225
+ this._outboxFrameCapture = makeOutboxFrameCapture(
226
+ () => this._backendTransport?.ensureNativeOutboxReady() ?? Promise.resolve(false),
227
+ );
228
+ }
229
+ return this._outboxFrameCapture;
230
+ }
231
+
232
+ /**
233
+ * Attach a desktop transport dynamically.
234
+ * Called when debug mode connects after SDK initialization.
235
+ */
236
+ setDesktopTransport(debugTransport: DebugTransport): void {
237
+ this.desktopTransport = new DesktopSessionTransport(debugTransport);
238
+ logger.info('[SessionManager] Desktop transport attached');
239
+ }
240
+
241
+ // ─── Session Lifecycle ──────────────────────────────────────────────
242
+
243
+ get isActive(): boolean {
244
+ return this.active;
245
+ }
246
+
247
+ get currentSessionId(): string | null {
248
+ return this.session?.sessionId ?? null;
249
+ }
250
+
251
+ get currentSessionMetadata(): SessionMetadata | null {
252
+ return this.session?.metadata ?? null;
253
+ }
254
+
255
+ /**
256
+ * The active RECORDING session ID (`ses-xxx`), or null when no recording
257
+ * is in progress.
258
+ *
259
+ * This is the canonical field that DebugEventStream stamps into every
260
+ * outgoing event's `data.recordingSessionId`. It is the single source of
261
+ * truth for correlating network and performance events with the session
262
+ * that was active when they were captured.
263
+ *
264
+ * Distinct from the TRANSPORT session ID (`debug-xxx`) which lives on
265
+ * the wire envelope's top-level `sessionId` field and never changes.
266
+ */
267
+ get recordingSessionId(): string | null {
268
+ return this.active ? (this.session?.sessionId ?? null) : null;
269
+ }
270
+
271
+ /**
272
+ * Update the native capture function at runtime.
273
+ * Called by ScaleBunDebugRoot once the root View ref is ready for ViewShot.
274
+ * Also updates the active session's capture manager if one exists.
275
+ */
276
+ setNativeCapture(captureFn: NativeCaptureFn): void {
277
+ this._nativeCapture = captureFn;
278
+ // Hot-swap into active capture manager if session is running
279
+ if (this.active && this.captureManager) {
280
+ (this.captureManager as any).nativeCapture = captureFn;
281
+ logger.info('[SessionManager] Capture function updated (hot-swap)');
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Start a new session. Idempotent — no-op if already active.
287
+ */
288
+ startSession(metadata?: Partial<SessionMetadata>): void {
289
+ try {
290
+ if (this.active) {
291
+ logger.debug('[SessionManager] Session already active, skipping start');
292
+ return;
293
+ }
294
+
295
+ // One-row merge: adopt the always-on analytics ingestion id as this
296
+ // recording session's id when the backend (SaaS) lane has one open.
297
+ // This threads the analytics id through the pipeline + capture manager
298
+ // below, so every frame/event body carries it AND it becomes
299
+ // currentSessionId at sendSessionStart keeping endpoint id == body id
300
+ // while attaching frames/journey to the single analytics row (no second
301
+ // INGESTION_START). Legacy/no-clientKey mode has no analytics id mint
302
+ // a fresh recording id and post to /replay/... as before.
303
+ const sessionId = this._backendTransport?.analyticsSessionId ?? generateSessionId();
304
+
305
+ // Create fresh subsystems for this session
306
+ this.pipeline = new JourneyEventPipeline(sessionId, {
307
+ maxEventCount: this.config.maxEventCount,
308
+ });
309
+ this.pipeline.setEmitCallback((event) => {
310
+ this.desktopTransport?.sendEvent(event);
311
+ this._backendTransport?.sendEvent(event);
312
+ });
313
+
314
+ this.captureManager = new ReplayCaptureManager(
315
+ sessionId,
316
+ this.config,
317
+ this._nativeCapture,
318
+ this._getOutboxFrameCapture(),
319
+ );
320
+ this.captureManager.setFrameEmitCallback((frame, imageData) => {
321
+ this.desktopTransport?.sendFrame(frame, imageData);
322
+ this._backendTransport?.sendFrame(frame, imageData);
323
+ });
324
+
325
+ // Create scroll tracker wired to emit events + trigger capture on settle
326
+ this.scrollTracker = new ScrollTracker((scrollMeta: ScrollMetadata) => {
327
+ if (!this.active) return;
328
+
329
+ // Synthesize representative coordinates for the scroll.
330
+ // ScrollTracker only knows content deltas it has no absolute touch
331
+ // point but the dashboard CorrelationEngine DROPS any interaction
332
+ // without x/y, and the replay overlay draws scroll/swipe as an arrow
333
+ // that needs normalizedEnd coords. Without this, ScaleBunScrollView scrolls
334
+ // were invisible AND uncounted. Anchor the gesture at screen center and
335
+ // extend by the finger displacement (opposite the content offset delta),
336
+ // matching the finger-path convention native swipes already use.
337
+ const vw = this.session?.metadata?.screenWidth ?? 0;
338
+ const vh = this.session?.metadata?.screenHeight ?? 0;
339
+ const coords: Record<string, number | boolean> = {};
340
+ if (vw > 0 && vh > 0) {
341
+ const cx = vw / 2;
342
+ const cy = vh / 2;
343
+ const ex = Math.max(0, Math.min(vw, cx - scrollMeta.totalDeltaX));
344
+ const ey = Math.max(0, Math.min(vh, cy - scrollMeta.totalDeltaY));
345
+ coords.x = cx;
346
+ coords.y = cy;
347
+ coords.endX = ex;
348
+ coords.endY = ey;
349
+ coords.normalizedX = cx / vw;
350
+ coords.normalizedY = cy / vh;
351
+ coords.normalizedEndX = ex / vw;
352
+ coords.normalizedEndY = ey / vh;
353
+ coords.viewportWidth = vw;
354
+ coords.viewportHeight = vh;
355
+ coords.normalizedPrecomputed = true;
356
+ }
357
+
358
+ // Emit gesture:scroll event.
359
+ // emitEvent() triggers captureManager.onScrollSettle() internally
360
+ // for USER_ACTION events with gestureType='scroll' — no explicit call needed.
361
+ this.emitEvent('USER_ACTION', {
362
+ subtype: 'gesture:scroll',
363
+ payload: {
364
+ gestureType: 'scroll',
365
+ totalDeltaX: scrollMeta.totalDeltaX,
366
+ totalDeltaY: scrollMeta.totalDeltaY,
367
+ dominantDirection: scrollMeta.dominantDirection,
368
+ direction: scrollMeta.dominantDirection,
369
+ durationMs: scrollMeta.durationMs,
370
+ startTs: scrollMeta.startTs,
371
+ endTs: scrollMeta.endTs,
372
+ confidence: 'high',
373
+ ...coords,
374
+ },
375
+ source: 'user',
376
+ });
377
+ });
378
+
379
+ this.crashAnchors = [];
380
+ this.loadingStartTimes.clear();
381
+
382
+ // Build session object
383
+ this.session = {
384
+ sessionId,
385
+ deviceId: this._rawTransport?.deviceId ?? 'unknown',
386
+ startedAt: Date.now(),
387
+ status: 'active',
388
+ metadata: {
389
+ // The real Platform.OS. This used to be a ternary whose else-branch was 'android'
390
+ // and whose catch was ALSO 'android' — so a macOS session, a Windows session, and
391
+ // a failure to load react-native at all were reported identically, as Android.
392
+ // Enriched by native device info when the bridge answers.
393
+ platform: resolvePlatformOS(),
394
+ buildType: __DEV__ ? 'debug' : 'release',
395
+ ...metadata,
396
+ // Capture window dp dims here so emitEvent() can normalize coords
397
+ // without re-querying Dimensions on every gesture event.
398
+ ...(() => {
399
+ if (metadata?.screenWidth && metadata?.screenHeight) return {};
400
+ try {
401
+ const { Dimensions } = require('react-native');
402
+ const dims = Dimensions.get('window');
403
+ if (dims.width > 0 && dims.height > 0) {
404
+ return { screenWidth: dims.width, screenHeight: dims.height };
405
+ }
406
+ } catch { /* no-throw */ }
407
+ return {};
408
+ })(),
409
+ },
410
+ transportState: 'local',
411
+ syncState: 'pending-evaluation',
412
+ artifactIndex: {
413
+ frameRefs: [],
414
+ eventRefs: [],
415
+ networkRefs: [],
416
+ logRefs: [],
417
+ crashAnchors: [],
418
+ },
419
+ };
420
+
421
+ this.active = true;
422
+
423
+ // Enrich the live session metadata with native device info (appVersion,
424
+ // deviceModel, osVersion, …) so synchronous consumers — e.g. the engage
425
+ // response builder reading `currentSessionMetadata.appVersion` — see real
426
+ // values rather than the platform-only subset known at create time. The
427
+ // session-start metadata above is the fallback when the bridge is
428
+ // unavailable (old native binary). Fire-and-forget, never throws.
429
+ Promise.resolve()
430
+ .then(() => bridgeAdapter.getDeviceInfo())
431
+ .then(info => {
432
+ const s = this.session;
433
+ if (!info || !s) return;
434
+ const m = s.metadata;
435
+ s.metadata = {
436
+ ...m,
437
+ appVersion: info.appVersion ?? m.appVersion,
438
+ appName: info.appName ?? m.appName,
439
+ bundleId: info.bundleId ?? m.bundleId,
440
+ osVersion: info.osVersion ?? m.osVersion,
441
+ deviceModel: info.deviceModel ?? m.deviceModel,
442
+ };
443
+ })
444
+ .catch(() => {
445
+ /* no-throw: metadata-only fallback */
446
+ });
447
+
448
+ // Notify transport (desktop + optional backend)
449
+ this.desktopTransport?.sendSessionStart(this.session);
450
+ this._backendTransport?.sendSessionStart(this.session);
451
+
452
+ // Emit SESSION_STARTED event
453
+ this.pipeline.emit('SESSION_STARTED', {
454
+ payload: { sessionId },
455
+ source: 'system',
456
+ });
457
+
458
+ // Start capture manager
459
+ this.captureManager.start();
460
+
461
+ // Set timeout
462
+ if (this.config.maxDurationMs > 0) {
463
+ this.timeoutTimer = setTimeout(() => {
464
+ logger.debug('[SessionManager] Session timeout reached');
465
+ this.endSession('timeout');
466
+ }, this.config.maxDurationMs);
467
+ }
468
+
469
+ logger.info(`[SessionManager] Session started: ${sessionId}`);
470
+
471
+ // ── Replay initial screen ──────────────────────────────────────
472
+ // If the user was already on a screen before pressing Record
473
+ // (typical: app mounted → screen hook fired → screen tracked),
474
+ // emit the initial SCREEN_VIEW now so the session captures the
475
+ // starting screen and triggers the first navigation frame.
476
+ if (this._lastKnownScreen) {
477
+ this.emitEvent('SCREEN_VIEW', {
478
+ screen: this._lastKnownScreen,
479
+ subtype: this._lastKnownScreen,
480
+ source: 'sdk',
481
+ });
482
+ }
483
+ } catch (err) {
484
+ logger.error('[SessionManager] Failed to start session:', err);
485
+ }
486
+ }
487
+
488
+ /**
489
+ * End the current session.
490
+ */
491
+ endSession(reason: 'ended' | 'timeout' = 'ended'): void {
492
+ // Fully idempotent — safe to call multiple times
493
+ if (!this.active) {
494
+ return;
495
+ }
496
+
497
+ // Disable collection FIRST to prevent any re-entrant emission during teardown
498
+ this.active = false;
499
+
500
+ // Guard: session must exist (should always be true if active was true)
501
+ if (!this.session) return;
502
+
503
+ try {
504
+
505
+ // Clear timeout
506
+ if (this.timeoutTimer) {
507
+ clearTimeout(this.timeoutTimer);
508
+ this.timeoutTimer = null;
509
+ }
510
+
511
+ // Dispose scroll tracker — cancels pending settle timer
512
+ if (this.scrollTracker) {
513
+ this.scrollTracker.dispose();
514
+ this.scrollTracker = null;
515
+ }
516
+
517
+ // Clear loading state
518
+ this.loadingStartTimes.clear();
519
+
520
+ // Emit SESSION_ENDED event
521
+ this.pipeline.emit('SESSION_ENDED', {
522
+ payload: { reason },
523
+ source: 'system',
524
+ });
525
+
526
+ // Stop capture — this cancels ALL pending timers and increments generation
527
+ this.captureManager.stop();
528
+
529
+ // Build final artifact index
530
+ const eventRefs = this.pipeline.buildEventRefs();
531
+ this.session.artifactIndex = {
532
+ ...eventRefs,
533
+ frameRefs: this.captureManager.getFrameRefs(),
534
+ crashAnchors: this.crashAnchors,
535
+ };
536
+
537
+ // Finalize session
538
+ this.session.endedAt = Date.now();
539
+ this.session.status = reason === 'timeout' ? 'timeout' : 'ended';
540
+
541
+ // Run sync evaluation
542
+ const hasCrash = this.crashAnchors.length > 0;
543
+ const hasError = this.pipeline.getEvents().some(
544
+ e => e.type === 'ERROR_CAPTURED',
545
+ );
546
+
547
+ const candidate = SyncDecisionEngine.buildCandidate(
548
+ this.session.sessionId,
549
+ this.session.metadata,
550
+ this.pipeline.count,
551
+ this.captureManager.count,
552
+ (this.session.endedAt - this.session.startedAt),
553
+ hasCrash,
554
+ hasError,
555
+ );
556
+
557
+ const decision = this.syncEngine.evaluate(candidate);
558
+ this.session.syncState = decision.shouldSync ? 'eligible' : 'ineligible';
559
+
560
+ // Notify transport (desktop + optional backend)
561
+ this.desktopTransport?.sendSessionEnd(this.session);
562
+ this._backendTransport?.sendSessionEnd(this.session);
563
+
564
+ // Clean up
565
+ this.pipeline.clear();
566
+ this.captureManager.clear();
567
+ // (this.active already set to false above)
568
+
569
+ logger.info(
570
+ `[SessionManager] Session ended: ${this.session.sessionId} ` +
571
+ `(${reason}, sync=${decision.shouldSync}, priority=${decision.priority})`,
572
+ );
573
+ } catch (err) {
574
+ logger.error('[SessionManager] Failed to end session:', err);
575
+ // active is already false — no further cleanup needed
576
+ }
577
+ }
578
+
579
+ // ─── Event Emission ─────────────────────────────────────────────────
580
+
581
+ /**
582
+ * Resolve the dp-space base used to normalize JS-fallback tap coordinates.
583
+ *
584
+ * The screenshot is captured by native in the content-view at its physical
585
+ * pixel size. Normalized coords must divide by that SAME region (converted
586
+ * to dp, since pageX/pageY are dp). Using Dimensions.get('window') (or
587
+ * session.metadata, which is seeded from it) excludes system insets and is
588
+ * ~10% smaller than the content-view — pushing markers off. Preference order:
589
+ * native content-view (px→dp) → session metadata → payload → Dimensions.
590
+ */
591
+ private _resolveNormalizationBaseDp(
592
+ p: Record<string, any>,
593
+ ): { width: number; height: number; space: string } | null {
594
+ // Native screenshot-base size in JS-coordinate units (dp on Android, pt on iOS).
595
+ // This is the EXACT region the native screenshot was captured in, so JS-fallback
596
+ // taps (pageX/pageY in dp/pt) divide directly into the same coord space the
597
+ // marker overlay uses on the dashboard. Highest priority — session metadata
598
+ // and Dimensions.get('window') report the app window which excludes system
599
+ // insets differently across devices and pushes markers off vertically.
600
+ if (this._lastNativeViewportJsUnits) {
601
+ return {
602
+ width: this._lastNativeViewportJsUnits.width,
603
+ height: this._lastNativeViewportJsUnits.height,
604
+ space: this._lastNativeViewportJsUnits.space,
605
+ };
606
+ }
607
+
608
+ const mw = this.session?.metadata?.screenWidth;
609
+ const mh = this.session?.metadata?.screenHeight;
610
+ if (mw && mh) return { width: mw, height: mh, space: 'session-metadata-dp' };
611
+
612
+ if (typeof p.viewportWidth === 'number' && p.viewportWidth > 0
613
+ && typeof p.viewportHeight === 'number' && p.viewportHeight > 0) {
614
+ return { width: p.viewportWidth, height: p.viewportHeight, space: 'payload-viewport-dp' };
615
+ }
616
+
617
+ try {
618
+ const { Dimensions } = require('react-native');
619
+ const dims = Dimensions.get('window');
620
+ if (dims.width > 0 && dims.height > 0) {
621
+ return { width: dims.width, height: dims.height, space: 'root-view-dp' };
622
+ }
623
+ } catch { /* no-throw */ }
624
+
625
+ return null;
626
+ }
627
+
628
+ /**
629
+ * Inject/resolve normalized tap coordinates into a USER_ACTION payload, in place.
630
+ *
631
+ * Mutates `p` to carry normalizedX/Y (+ end coords for swipes/scrolls) so the
632
+ * heatmap can overlay them across viewport sizes. Returns true when the source
633
+ * already provided high-confidence / pre-computed normalized coords (native or
634
+ * JS-root-measured), false when this method JS-estimated them.
635
+ *
636
+ * Extracted from emitEvent so BOTH the replay-recording lane AND the always-on
637
+ * analytics lane (Feature #4) normalize identically — keeping the tap payload
638
+ * keys byte-for-byte the same on both routes.
639
+ */
640
+ private _normalizeInteractionPayload(p: Record<string, unknown>): boolean {
641
+ // If native tracker already provided high-confidence normalized coords,
642
+ // OR the JS path measured the root-view rect and precomputed normalized
643
+ // coords against it, do not overwrite them with JS estimation.
644
+ const hasNormalizedXY = typeof p.normalizedX === 'number'
645
+ && typeof p.normalizedY === 'number';
646
+ const alreadyNormalized = hasNormalizedXY
647
+ && (p.confidence === 'high' || p.normalizedPrecomputed === true);
648
+
649
+ if (alreadyNormalized) {
650
+ // Cache the native screenshot base in JS-coordinate units (dp/pt)
651
+ // so subsequent JS-fallback taps normalize against the same region
652
+ // the screenshot was captured from. Android sends px (suffix -px),
653
+ // iOS sends pt (suffix -pt). Both are converted to the unit RN
654
+ // pageX/pageY use, so JS taps divide directly with no extra math.
655
+ const cs = typeof p.coordinateSpace === 'string' ? p.coordinateSpace : '';
656
+ if (typeof p.viewportWidth === 'number' && p.viewportWidth > 0
657
+ && typeof p.viewportHeight === 'number' && p.viewportHeight > 0) {
658
+ if (cs.endsWith('-px')) {
659
+ try {
660
+ const { PixelRatio } = require('react-native');
661
+ const density = PixelRatio.get();
662
+ if (density > 0) {
663
+ this._lastNativeViewportJsUnits = {
664
+ width: p.viewportWidth / density,
665
+ height: p.viewportHeight / density,
666
+ space: 'native-content-view-dp',
667
+ };
668
+ }
669
+ } catch { /* no-throw */ }
670
+ } else if (cs.endsWith('-pt')) {
671
+ // iOS already in pt — same unit as RN pageX/pageY
672
+ this._lastNativeViewportJsUnits = {
673
+ width: p.viewportWidth,
674
+ height: p.viewportHeight,
675
+ space: 'native-window-pt',
676
+ };
677
+ }
678
+ }
679
+ } else {
680
+ // Resolve the normalization base (in dp). Priority:
681
+ // 1. session metadata screen size
682
+ // 2. native content-view size (px → dp via PixelRatio) — matches screenshot
683
+ // 3. payload viewport
684
+ // 4. Dimensions.get('window') — last resort (excludes insets, ~10% off)
685
+ const base = this._resolveNormalizationBaseDp(p);
686
+
687
+ const x = typeof p.x === 'number' ? p.x : undefined;
688
+ const y = typeof p.y === 'number' ? p.y : undefined;
689
+ if (x !== undefined && y !== undefined && base) {
690
+ p.normalizedX = Math.max(0, Math.min(1, x / base.width));
691
+ p.normalizedY = Math.max(0, Math.min(1, y / base.height));
692
+ p.viewportWidth = base.width;
693
+ p.viewportHeight = base.height;
694
+ p.coordinateSpace = base.space;
695
+ }
696
+
697
+ const endX = typeof p.endX === 'number' ? p.endX : undefined;
698
+ const endY = typeof p.endY === 'number' ? p.endY : undefined;
699
+ if (endX !== undefined && endY !== undefined && base) {
700
+ p.normalizedEndX = Math.max(0, Math.min(1, endX / base.width));
701
+ p.normalizedEndY = Math.max(0, Math.min(1, endY / base.height));
702
+ }
703
+ }
704
+
705
+ return alreadyNormalized;
706
+ }
707
+
708
+ /**
709
+ * Feature #4 (heatmaps) — additive analytics emission.
710
+ *
711
+ * Routes a tap/gesture to the always-on ANALYTICS lane (BackendSessionAdapter
712
+ * .trackEvent) so coords are captured even when no replay recording is active.
713
+ *
714
+ * Strictly additive and isolated:
715
+ * - Only runs when `_captureInteractionHeatmap` is ON (opt-in flag) AND a
716
+ * backend analytics transport is attached AND no recording is active
717
+ * (when active, the recording lane already emits the SAME USER_ACTION —
718
+ * emitting here too would duplicate it).
719
+ * - Reuses the EXACT recording payload shape (USER_ACTION + the same keys:
720
+ * normalizedX, normalizedY, gestureType, screen, …) so the backend
721
+ * aggregate reads them identically (no protocol/schema change).
722
+ * - Normalizes via the same _normalizeInteractionPayload used by recording.
723
+ * - Respects redaction: payload is passed through redactBody so any caller-
724
+ * injected sensitive keys (e.g. a label) are stripped before transport.
725
+ * - Never throws.
726
+ */
727
+ private _emitInteractionToAnalytics(gestureType: string, payload: Record<string, unknown>): void {
728
+ if (!this._captureInteractionHeatmap) return;
729
+ if (this.active) return; // recording lane already carries this tap
730
+ const adapter = this._backendTransport;
731
+ if (!adapter) return;
732
+
733
+ // Per-foreground sampling cap. Reset the counter when the analytics
734
+ // session window rolls over, then drop anything past the cap.
735
+ const windowId = adapter.analyticsSessionId ?? '';
736
+ if (windowId !== this._heatmapWindowSessionId) {
737
+ this._heatmapWindowSessionId = windowId;
738
+ this._heatmapWindowCount = 0;
739
+ }
740
+ if (this._heatmapWindowCount >= HEATMAP_MAX_INTERACTIONS_PER_WINDOW) return;
741
+ this._heatmapWindowCount++;
742
+
743
+ try {
744
+ // Normalize coords in place (same logic as the recording lane).
745
+ this._normalizeInteractionPayload(payload);
746
+
747
+ // Respect redaction before handing to transport. redactBody returns a
748
+ // new object and strips known-sensitive keys; coords/gesture survive.
749
+ const safePayload = redactBody(payload) as Record<string, unknown>;
750
+
751
+ /**
752
+ * NO `frameId` HERE, and it is not an oversight.
753
+ *
754
+ * This method is guarded by `if (this.active) return;` — it runs ONLY when no replay
755
+ * recording is active, which is precisely when no screenshots are being captured.
756
+ * There is no frame on screen to point at, so an analytics-lane tap can never be
757
+ * attributed to a visual state.
758
+ *
759
+ * That makes it a permanent property of this lane rather than a gap to close later,
760
+ * and the dashboard has to account for it: these taps live in the heatmap grid
761
+ * alongside recorded ones, so a state filter necessarily covers a subset of the
762
+ * traffic. `heat:screen-coverage` reports that subset's size per app for exactly this
763
+ * reason.
764
+ */
765
+ const event: JourneyEvent = {
766
+ eventId: generateEventId(),
767
+ // sessionId is (re)stamped by the analytics lane at flush time.
768
+ sessionId: adapter.analyticsSessionId ?? '',
769
+ ts: Date.now(),
770
+ type: 'USER_ACTION',
771
+ subtype: `gesture:${gestureType}`,
772
+ screen: this._lastKnownScreen ?? undefined,
773
+ payload: safePayload,
774
+ source: 'user',
775
+ };
776
+ adapter.trackEvent(event);
777
+ } catch (err) {
778
+ logger.error('[SessionManager] heatmap analytics emit failed:', err);
779
+ }
780
+ }
781
+
782
+ /**
783
+ * Emit a canonical event into the session pipeline.
784
+ * This is the primary entry point for all event sources.
785
+ */
786
+ emitEvent(
787
+ type: JourneyEventType,
788
+ opts?: {
789
+ subtype?: string;
790
+ severity?: JourneyEventSeverity;
791
+ screen?: string;
792
+ payload?: Record<string, unknown>;
793
+ correlationId?: string;
794
+ traceId?: string;
795
+ source?: JourneyEventSource;
796
+ journeyId?: string;
797
+ },
798
+ ): void {
799
+ if (!this.active) return;
800
+
801
+ try {
802
+ // Pre-process USER_ACTION events to inject normalized coordinates for heatmap readiness
803
+ if (type === 'USER_ACTION' && opts?.payload) {
804
+ const p = opts.payload;
805
+
806
+ const alreadyNormalized = this._normalizeInteractionPayload(p);
807
+
808
+ logger.debug(
809
+ `[TapAccuracy] sink platform=${p.platform ?? '?'} space=${p.coordinateSpace ?? '?'} ` +
810
+ `source=${alreadyNormalized ? (p.confidence === 'high' ? 'native-high' : 'js-precomputed') : 'js-estimated'} ` +
811
+ `norm=(${p.normalizedX},${p.normalizedY}) base=(${p.viewportWidth}x${p.viewportHeight})`,
812
+ );
813
+
814
+ // ─── Diagnostic: merge calibration expected target (if a calibration
815
+ // screen stamped it within the TTL) and emit ONE unified [TapDiag]
816
+ // JSON object per gesture. Observability only — no math runs here.
817
+ const cal = consumeCalibrationTarget();
818
+ if (cal) {
819
+ p.expectedTargetId = cal.targetId;
820
+ p.expectedNX = cal.expectedNX;
821
+ p.expectedNY = cal.expectedNY;
822
+ }
823
+
824
+ try {
825
+ const meta = this.session?.metadata as any | undefined;
826
+ const diag = {
827
+ tag: 'TapDiag',
828
+ side: 'sdk',
829
+ platform: p.platform ?? null,
830
+ coordinateSource: alreadyNormalized
831
+ ? (p.confidence === 'high' ? 'native-high' : 'js-precomputed')
832
+ : 'js-estimated',
833
+ coordinateSpace: p.coordinateSpace ?? null,
834
+ targetId: p.expectedTargetId ?? p.target ?? null,
835
+ expectedNX: p.expectedNX ?? null,
836
+ expectedNY: p.expectedNY ?? null,
837
+ rawX: p.x ?? null,
838
+ rawY: p.y ?? null,
839
+ pageX: p.pageX ?? null,
840
+ pageY: p.pageY ?? null,
841
+ locationX: p.locationX ?? null,
842
+ locationY: p.locationY ?? null,
843
+ normalizedX: p.normalizedX ?? null,
844
+ normalizedY: p.normalizedY ?? null,
845
+ viewportWidth: p.viewportWidth ?? null,
846
+ viewportHeight: p.viewportHeight ?? null,
847
+ rootViewWidth: p.rootViewWidth ?? null,
848
+ rootViewHeight: p.rootViewHeight ?? null,
849
+ rootViewLeft: p.rootViewLeft ?? null,
850
+ rootViewTop: p.rootViewTop ?? null,
851
+ screenWidth: p.screenWidth ?? meta?.screenWidth ?? null,
852
+ screenHeight: p.screenHeight ?? meta?.screenHeight ?? null,
853
+ windowWidth: p.windowWidth ?? null,
854
+ windowHeight: p.windowHeight ?? null,
855
+ statusBarHeight: p.statusBarHeight ?? null,
856
+ safeAreaTop: p.safeAreaTop ?? null,
857
+ timestamp: Date.now(),
858
+ confidence: p.confidence ?? null,
859
+ source: p.source ?? null,
860
+ };
861
+ // eslint-disable-next-line no-console
862
+ console.log('[TapDiag]', JSON.stringify(diag));
863
+ } catch { /* no-throw */ }
864
+ }
865
+
866
+ /**
867
+ * Which frame was on screen when this happened.
868
+ *
869
+ * Resolved BEFORE `pipeline.emit`, and deliberately before the capture triggers
870
+ * below: those capture the frame that shows the RESULT of the interaction, and a tap
871
+ * belongs to the state it was made IN, not the one it produced. Reading after them
872
+ * would attribute every tap to its own consequence.
873
+ *
874
+ * USER_ACTION only. A SCREEN_VIEW's frame is the screen being left, which is
875
+ * misleading rather than useful, and no consumer asks for it.
876
+ *
877
+ * `currentKeyframe` returns null unless the frame is from this same screen and still
878
+ * fresh see its contract. Null is the common, correct answer and stays absent on
879
+ * the event rather than becoming a default.
880
+ */
881
+ const framedOpts =
882
+ type === 'USER_ACTION'
883
+ ? {
884
+ ...opts,
885
+ frameId: this.captureManager?.currentKeyframe(
886
+ opts?.screen ?? this._lastKnownScreen ?? undefined,
887
+ )?.frameId,
888
+ }
889
+ : opts;
890
+
891
+ const event = this.pipeline.emit(type, framedOpts);
892
+
893
+ // Trigger capture on screen view or interaction
894
+ if (event) {
895
+ if (type === 'SCREEN_VIEW' && opts?.screen) {
896
+ this.captureManager.onScreenChange(opts.screen);
897
+ } else if (type === 'USER_ACTION') {
898
+ // Extract interaction coordinates from the gesture payload
899
+ // so the captured frame carries tap location metadata.
900
+ const p = opts?.payload;
901
+ const x = typeof p?.x === 'number' ? p.x : undefined;
902
+ const y = typeof p?.y === 'number' ? p.y : undefined;
903
+ const gestureType = typeof p?.gestureType === 'string' ? p.gestureType : undefined;
904
+
905
+ // Scroll gestures use onScrollSettle (which debounces into a single
906
+ // capture). Using onInteraction for scroll would produce a DUPLICATE
907
+ // screenshot alongside the ScrollTracker's onScrollSettle call.
908
+ if (gestureType === 'scroll') {
909
+ this.captureManager.onScrollSettle(opts?.screen ?? this._lastKnownScreen ?? undefined);
910
+ } else {
911
+ let interactionPoint: import('./sessionTypes').ReplayFrame['interactionPoint'];
912
+ if (x !== undefined && y !== undefined && gestureType) {
913
+ interactionPoint = {
914
+ x,
915
+ y,
916
+ normalizedX: typeof p?.normalizedX === 'number' ? p.normalizedX : undefined,
917
+ normalizedY: typeof p?.normalizedY === 'number' ? p.normalizedY : undefined,
918
+ screenWidth: this.session?.metadata?.screenWidth ?? 0,
919
+ screenHeight: this.session?.metadata?.screenHeight ?? 0,
920
+ viewportWidth: typeof p?.viewportWidth === 'number' ? p.viewportWidth : undefined,
921
+ viewportHeight: typeof p?.viewportHeight === 'number' ? p.viewportHeight : undefined,
922
+ gestureType,
923
+ endX: typeof p?.endX === 'number' ? p.endX : undefined,
924
+ endY: typeof p?.endY === 'number' ? p.endY : undefined,
925
+ normalizedEndX: typeof p?.normalizedEndX === 'number' ? p.normalizedEndX : undefined,
926
+ normalizedEndY: typeof p?.normalizedEndY === 'number' ? p.normalizedEndY : undefined,
927
+ durationMs: typeof p?.durationMs === 'number' ? p.durationMs : undefined,
928
+ direction: typeof p?.direction === 'string' ? p.direction : undefined,
929
+ };
930
+ }
931
+
932
+ this.captureManager.onInteraction(interactionPoint);
933
+ }
934
+ }
935
+ }
936
+ } catch (err) {
937
+ logger.error('[SessionManager] emitEvent failed:', err);
938
+ }
939
+ }
940
+
941
+ /**
942
+ * Anchor a crash in the session context.
943
+ * Protects nearby events and frames from eviction.
944
+ */
945
+ anchorCrash(crashEventId: string): CrashAnchor | null {
946
+ if (!this.active) return null;
947
+
948
+ try {
949
+ // Anchor events
950
+ const anchor = this.pipeline.anchorCrash(crashEventId);
951
+
952
+ // Anchor frames (protect frames near the crash timestamp)
953
+ const crashEvent = this.pipeline.getEvents().find(
954
+ e => e.eventId === crashEventId,
955
+ );
956
+ if (crashEvent) {
957
+ const protectedFrameIds = this.captureManager.protectFramesNearCrash(crashEvent.ts);
958
+ anchor.nearbyFrameIds = protectedFrameIds;
959
+ }
960
+
961
+ // Capture an error-context frame
962
+ this.captureManager.captureManual('error-context').catch(() => { });
963
+
964
+ this.crashAnchors.push(anchor);
965
+
966
+ logger.debug(
967
+ `[SessionManager] Crash anchored: ${crashEventId}, ` +
968
+ `protected ${anchor.nearbyEventIds.length} events, ` +
969
+ `${anchor.nearbyFrameIds.length} frames`,
970
+ );
971
+
972
+ return anchor;
973
+ } catch (err) {
974
+ logger.error('[SessionManager] anchorCrash failed:', err);
975
+ return null;
976
+ }
977
+ }
978
+
979
+ // ─── Navigation / Screen Integration ────────────────────────────────
980
+
981
+ /**
982
+ * Notify of a screen change. Called by ScaleBunDebugRoot via NavDetector.
983
+ */
984
+ /** The screen currently on top, or null before the first navigation is observed. */
985
+ getLastKnownScreen(): string | null {
986
+ return this._lastKnownScreen;
987
+ }
988
+
989
+ onScreenChange(screenName: string): void {
990
+ // Always track the current screen — even when inactive.
991
+ // This allows startSession to emit the initial SCREEN_VIEW for
992
+ // the screen that was already mounted before Record was pressed.
993
+ const previous = this._lastKnownScreen;
994
+ const enteredAt = this._screenEnteredAt;
995
+ this._lastKnownScreen = screenName;
996
+ this._screenEnteredAt = Date.now();
997
+
998
+ if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
999
+
1000
+ // SCREEN_EXIT for the screen being left, carrying its dwell time.
1001
+ //
1002
+ // The exit was previously detectable ONLY inside the Engage trigger engine and never became an
1003
+ // event, so time-on-screen had to be inferred from the gap to the NEXT SCREEN_VIEW — which is
1004
+ // wrong whenever the app backgrounds in between, and impossible for the last screen of a
1005
+ // session. Emitting it here makes dwell a measured value rather than a derived guess.
1006
+ if (previous && previous !== screenName && enteredAt != null) {
1007
+ this.emitEvent('SCREEN_EXIT', {
1008
+ screen: previous,
1009
+ subtype: previous,
1010
+ source: 'sdk',
1011
+ payload: { dwellMs: Math.max(0, Date.now() - enteredAt), to: screenName },
1012
+ });
1013
+ }
1014
+
1015
+ this.emitEvent('SCREEN_VIEW', {
1016
+ screen: screenName,
1017
+ subtype: screenName,
1018
+ source: 'sdk',
1019
+ ...(previous && previous !== screenName ? { payload: { from: previous } } : {}),
1020
+ });
1021
+ }
1022
+
1023
+ /**
1024
+ * Notify of a user interaction. Called by ScaleBunDebugRoot touch handlers.
1025
+ * Also triggers frame capture for desktop-initiated recordings.
1026
+ */
1027
+ onUserAction(subtype: string, payload?: Record<string, unknown>): void {
1028
+ if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
1029
+ this.emitEvent('USER_ACTION', {
1030
+ subtype,
1031
+ screen: this._lastKnownScreen ?? undefined,
1032
+ payload,
1033
+ source: 'user',
1034
+ });
1035
+ // NOTE: Do NOT call captureManager.onInteraction() here.
1036
+ // emitEvent() already triggers onInteraction() for USER_ACTION events (line ~405).
1037
+ // Calling it again here caused DUPLICATE frame captures per gesture.
1038
+ }
1039
+
1040
+ /**
1041
+ * Detailed gesture detection — called by ScaleBunDebugRoot touch handlers.
1042
+ * Emits a USER_ACTION event with gesture-specific subtype and payload.
1043
+ */
1044
+ onGestureDetected(gestureType: string, details?: {
1045
+ x?: number;
1046
+ y?: number;
1047
+ endX?: number;
1048
+ endY?: number;
1049
+ duration?: number;
1050
+ durationMs?: number;
1051
+ direction?: string;
1052
+ target?: string;
1053
+ viewportWidth?: number;
1054
+ viewportHeight?: number;
1055
+ pageX?: number;
1056
+ pageY?: number;
1057
+ locationX?: number;
1058
+ locationY?: number;
1059
+ normalizedX?: number;
1060
+ normalizedY?: number;
1061
+ normalizedEndX?: number;
1062
+ normalizedEndY?: number;
1063
+ confidence?: string;
1064
+ coordinateSpace?: string;
1065
+ source?: string;
1066
+ // Pre-computed normalization flag — set by JS fallback when it normalized
1067
+ // against the measured root-view rect (the exact view the screenshot captures).
1068
+ // Without this flag, SessionManager.emitEvent would overwrite the pre-computed
1069
+ // values via _resolveNormalizationBaseDp using a potentially-different base.
1070
+ normalizedPrecomputed?: boolean;
1071
+ // Diagnostic fields used by the dashboard to verify capture-space alignment.
1072
+ statusBarHeight?: number;
1073
+ safeAreaTop?: number;
1074
+ rootViewTop?: number;
1075
+ rootViewLeft?: number;
1076
+ rootViewWidth?: number;
1077
+ rootViewHeight?: number;
1078
+ windowWidth?: number;
1079
+ windowHeight?: number;
1080
+ screenshotCropTop?: number;
1081
+ screenWidth?: number;
1082
+ screenHeight?: number;
1083
+ platform?: string;
1084
+ }): void {
1085
+ // Build the canonical gesture payload ONCE so the recording lane and the
1086
+ // (additive) analytics lane carry byte-identical keys (normalizedX/Y,
1087
+ // gestureType, etc.). Same object shape that was previously inlined.
1088
+ const payload: Record<string, unknown> = {
1089
+ gestureType,
1090
+ x: details?.x,
1091
+ y: details?.y,
1092
+ endX: details?.endX,
1093
+ endY: details?.endY,
1094
+ duration: details?.duration ?? details?.durationMs,
1095
+ durationMs: details?.durationMs ?? details?.duration,
1096
+ direction: details?.direction,
1097
+ target: details?.target,
1098
+ viewportWidth: details?.viewportWidth,
1099
+ viewportHeight: details?.viewportHeight,
1100
+ pageX: details?.pageX,
1101
+ pageY: details?.pageY,
1102
+ locationX: details?.locationX,
1103
+ locationY: details?.locationY,
1104
+ // Native / JS-precomputed coords passed through without overwriting
1105
+ normalizedX: details?.normalizedX,
1106
+ normalizedY: details?.normalizedY,
1107
+ normalizedEndX: details?.normalizedEndX,
1108
+ normalizedEndY: details?.normalizedEndY,
1109
+ confidence: details?.confidence,
1110
+ coordinateSpace: details?.coordinateSpace,
1111
+ source: details?.source,
1112
+ normalizedPrecomputed: details?.normalizedPrecomputed,
1113
+ statusBarHeight: details?.statusBarHeight,
1114
+ safeAreaTop: details?.safeAreaTop,
1115
+ rootViewTop: details?.rootViewTop,
1116
+ rootViewLeft: details?.rootViewLeft,
1117
+ rootViewWidth: details?.rootViewWidth,
1118
+ rootViewHeight: details?.rootViewHeight,
1119
+ windowWidth: details?.windowWidth,
1120
+ windowHeight: details?.windowHeight,
1121
+ screenshotCropTop: details?.screenshotCropTop,
1122
+ screenWidth: details?.screenWidth,
1123
+ screenHeight: details?.screenHeight,
1124
+ platform: details?.platform,
1125
+ };
1126
+
1127
+ // ── Feature #4 (heatmaps): additive analytics emission ──
1128
+ // When NOT recording, route the tap to the always-on analytics lane so
1129
+ // heatmaps still get coords (opt-in via captureInteractionHeatmap). No-op
1130
+ // when the flag is OFF, no backend transport is attached, or recording is
1131
+ // active (the recording path below already carries this tap). Uses a fresh
1132
+ // payload clone so analytics normalization never mutates the recording one.
1133
+ this._emitInteractionToAnalytics(gestureType, { ...payload });
1134
+
1135
+ if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
1136
+ // The subtype becomes `ReplayEvent.label`, which is what the Events explorer GROUPS BY. Naming
1137
+ // the tapped control here is what splits taps per control instead of collapsing every tap in the
1138
+ // app into one `gesture:tap` row. Falls back to the bare gesture when nothing identified the
1139
+ // target, so behaviour is unchanged for taps that cannot be resolved.
1140
+ //
1141
+ // ⚠️ `gestureType` also travels in the payload, and the backend's `resolveGesture` reads THAT
1142
+ // firstso enriching the label cannot change heatmap gesture classification.
1143
+ const target = typeof details?.target === 'string' ? details.target.trim() : '';
1144
+ this.onUserAction(target ? `gesture:${gestureType} · ${target}` : `gesture:${gestureType}`, payload);
1145
+ }
1146
+
1147
+ /**
1148
+ * Manual frame capture — triggered by Desktop "Capture Step" button.
1149
+ */
1150
+ async captureManualFrame(): Promise<{ frameId?: string } | null> {
1151
+ if (!this.active || !this.captureManager) return null; // No capture when recording is OFF
1152
+ const frame = await this.captureManager.captureManual('manual');
1153
+ return frame ? { frameId: frame.frameId } : null;
1154
+ }
1155
+
1156
+ /**
1157
+ * Notify of app lifecycle change.
1158
+ */
1159
+ onLifecycleChange(state: 'foreground' | 'background'): void {
1160
+ this.emitEvent(
1161
+ state === 'foreground' ? 'APP_FOREGROUND' : 'APP_BACKGROUND',
1162
+ { source: 'system' },
1163
+ );
1164
+ }
1165
+
1166
+ // ─── Scroll Integration ─────────────────────────────────────────────
1167
+
1168
+ /**
1169
+ * Notify of a scroll event from a scrollable surface (ScaleBunScrollView).
1170
+ * Delegates to ScrollTracker for accumulation and settle detection.
1171
+ */
1172
+ onScrollEvent(contentOffsetX: number, contentOffsetY: number): void {
1173
+ if (!this.active) return;
1174
+ this.scrollTracker?.onScrollEvent(contentOffsetX, contentOffsetY);
1175
+ }
1176
+
1177
+ // ─── Loading State Integration ──────────────────────────────────────
1178
+
1179
+ /**
1180
+ * Notify that a screen has started loading.
1181
+ * Explicit instrumentation — NOT auto-called on screen entry.
1182
+ * Call from app code: ScaleBun.markLoadingStarted('ScreenName')
1183
+ */
1184
+ onLoadingStarted(screenName: string): void {
1185
+ if (!this.active) return;
1186
+
1187
+ this.loadingStartTimes.set(screenName, Date.now());
1188
+
1189
+ this.emitEvent('LOADING_STARTED', {
1190
+ screen: screenName,
1191
+ subtype: screenName,
1192
+ payload: { screen: screenName },
1193
+ source: 'sdk',
1194
+ });
1195
+ }
1196
+
1197
+ /**
1198
+ * Notify that a screen has finished loading.
1199
+ * Explicit instrumentation — call from app code.
1200
+ * Triggers a 'screen_loaded' frame capture for the settled state.
1201
+ */
1202
+ onLoadingCompleted(screenName: string): void {
1203
+ if (!this.active) return;
1204
+
1205
+ const startTime = this.loadingStartTimes.get(screenName);
1206
+ const durationMs = startTime ? Date.now() - startTime : undefined;
1207
+ this.loadingStartTimes.delete(screenName);
1208
+
1209
+ this.emitEvent('LOADING_COMPLETED', {
1210
+ screen: screenName,
1211
+ subtype: screenName,
1212
+ payload: {
1213
+ screen: screenName,
1214
+ durationMs,
1215
+ },
1216
+ source: 'sdk',
1217
+ });
1218
+
1219
+ // Capture the settled loaded screen
1220
+ this.captureManager.onLoadingEnd(screenName);
1221
+ }
1222
+
1223
+ // ─── Sync Policy ────────────────────────────────────────────────────
1224
+
1225
+ /**
1226
+ * Override the sync policy. SDK-owned — native only provides metadata.
1227
+ */
1228
+ setSyncPolicy(policy: SyncDecisionCallback): void {
1229
+ this.syncEngine.setPolicy(policy);
1230
+ }
1231
+
1232
+ /**
1233
+ * Provide native-gathered sync metadata for the current session.
1234
+ * Does NOT make the sync decision — that stays in SDK's SyncDecisionEngine.
1235
+ */
1236
+ setNativeSyncMetadata(metadata: NativeSyncMetadata): void {
1237
+ // Stored for use at session end evaluation
1238
+ if (this.session) {
1239
+ (this.session as any)._nativeSyncMetadata = metadata;
1240
+ }
1241
+ }
1242
+ }
1243
+
1244
+ // ─── Helpers ────────────────────────────────────────────────────────────────
1245
+
1246
+ function generateSessionId(): string {
1247
+ return `ses-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`;
1248
+ }