@scalebun-release/react-native 2.5.0

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 (1203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -0
  3. package/android/build.gradle +94 -0
  4. package/android/consumer-rules.pro +28 -0
  5. package/android/src/androidTest/java/com/scalebun/rn/ota/ScaleBunOtaVerifierInstrumentedTest.kt +112 -0
  6. package/android/src/main/AndroidManifest.xml +14 -0
  7. package/android/src/main/java/com/scalebun/core/crash/CrashStorage.kt +155 -0
  8. package/android/src/main/java/com/scalebun/core/crash/NativeCrashHandler.kt +93 -0
  9. package/android/src/main/java/com/scalebun/core/performance/ANRWatchdog.kt +100 -0
  10. package/android/src/main/java/com/scalebun/core/performance/AppStartCollector.kt +180 -0
  11. package/android/src/main/java/com/scalebun/core/performance/FrameMetricsCollector.kt +230 -0
  12. package/android/src/main/java/com/scalebun/core/performance/PerformanceCore.kt +165 -0
  13. package/android/src/main/java/com/scalebun/profiler/ProfilerModule.kt +398 -0
  14. package/android/src/main/java/com/scalebun/profiler/ProfilerPackage.kt +24 -0
  15. package/android/src/main/java/com/scalebun/profiler/collectors/CpuCollector.kt +161 -0
  16. package/android/src/main/java/com/scalebun/profiler/collectors/IncidentDetector.kt +223 -0
  17. package/android/src/main/java/com/scalebun/profiler/collectors/MemoryCollector.kt +157 -0
  18. package/android/src/main/java/com/scalebun/profiler/collectors/RenderCollector.kt +194 -0
  19. package/android/src/main/java/com/scalebun/profiler/collectors/SamplerScheduler.kt +218 -0
  20. package/android/src/main/java/com/scalebun/profiler/collectors/ThreadCollector.kt +142 -0
  21. package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkModule.kt +1117 -0
  22. package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkPackage.kt +24 -0
  23. package/android/src/main/java/com/scalebun/replaysdk/capture/CaptureReason.kt +47 -0
  24. package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureManager.kt +574 -0
  25. package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureScheduler.kt +187 -0
  26. package/android/src/main/java/com/scalebun/replaysdk/capture/UiStabilityDetector.kt +214 -0
  27. package/android/src/main/java/com/scalebun/replaysdk/core/ReplayConfig.kt +144 -0
  28. package/android/src/main/java/com/scalebun/replaysdk/core/ReplayLogger.kt +31 -0
  29. package/android/src/main/java/com/scalebun/replaysdk/core/SessionIdGenerator.kt +15 -0
  30. package/android/src/main/java/com/scalebun/replaysdk/models/ReplayModels.kt +94 -0
  31. package/android/src/main/java/com/scalebun/replaysdk/outbox/NativeOutbox.kt +574 -0
  32. package/android/src/main/java/com/scalebun/replaysdk/outbox/OutboxUploader.kt +559 -0
  33. package/android/src/main/java/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.kt +126 -0
  34. package/android/src/main/java/com/scalebun/replaysdk/session/SessionManager.kt +322 -0
  35. package/android/src/main/java/com/scalebun/replaysdk/storage/ReplayStorage.kt +136 -0
  36. package/android/src/main/java/com/scalebun/replaysdk/timeline/TimelineCollector.kt +28 -0
  37. package/android/src/main/java/com/scalebun/replaysdk/tracking/InteractionTracker.kt +470 -0
  38. package/android/src/main/java/com/scalebun/replaysdk/tracking/ScreenTracker.kt +20 -0
  39. package/android/src/main/java/com/scalebun/replaysdk/tracking/ScrollContextProbe.kt +188 -0
  40. package/android/src/main/java/com/scalebun/replaysdk/transport/ReplayTransport.kt +99 -0
  41. package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceRecorder.kt +121 -0
  42. package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceTranscriber.kt +170 -0
  43. package/android/src/main/java/com/scalebun/rn/ScaleBunPackage.kt +113 -0
  44. package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashModule.kt +188 -0
  45. package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashPackage.kt +22 -0
  46. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngageModule.kt +579 -0
  47. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngagePackage.kt +22 -0
  48. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunNotificationPresenter.kt +110 -0
  49. package/android/src/main/java/com/scalebun/rn/ota/BsPatch.kt +240 -0
  50. package/android/src/main/java/com/scalebun/rn/ota/BundleDownloader.kt +195 -0
  51. package/android/src/main/java/com/scalebun/rn/ota/DeviceIntegrity.kt +81 -0
  52. package/android/src/main/java/com/scalebun/rn/ota/DownloadFailure.kt +55 -0
  53. package/android/src/main/java/com/scalebun/rn/ota/OtaProtocol.kt +244 -0
  54. package/android/src/main/java/com/scalebun/rn/ota/ScaleBunOtaKeyRegistry.kt +100 -0
  55. package/android/src/main/java/com/scalebun/rn/ota/ScaleBunOtaModule.kt +683 -0
  56. package/android/src/main/java/com/scalebun/rn/ota/ScaleBunOtaReleaseVerifier.kt +136 -0
  57. package/android/src/main/java/com/scalebun/rn/ota/SlotManager.kt +578 -0
  58. package/android/src/main/java/com/scalebun/rn/ota/TlsPinning.kt +118 -0
  59. package/android/src/main/java/com/scalebun/rn/performance/PerformanceModule.kt +217 -0
  60. package/android/src/main/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.kt +77 -0
  61. package/android/src/main/java/com/scalebun/rn/storage/ScaleBunStorageModule.kt +68 -0
  62. package/android/src/main/java/com/scalebun/storage/KvFileStore.kt +174 -0
  63. package/android/src/newarch/java/com/scalebun/profiler/ProfilerSpec.kt +12 -0
  64. package/android/src/newarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +12 -0
  65. package/android/src/newarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +15 -0
  66. package/android/src/newarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +16 -0
  67. package/android/src/newarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +12 -0
  68. package/android/src/newarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +14 -0
  69. package/android/src/newarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +16 -0
  70. package/android/src/oldarch/java/com/scalebun/profiler/ProfilerSpec.kt +34 -0
  71. package/android/src/oldarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +77 -0
  72. package/android/src/oldarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +40 -0
  73. package/android/src/oldarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +42 -0
  74. package/android/src/oldarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +27 -0
  75. package/android/src/oldarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +18 -0
  76. package/android/src/oldarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +26 -0
  77. package/bin/lib/androidCodemod.js +370 -0
  78. package/bin/lib/iosCodemod.js +343 -0
  79. package/bin/scalebun.js +1004 -0
  80. package/dist/scalebun.full.js +37348 -0
  81. package/dist/scalebun.slim.js +34137 -0
  82. package/ios/Capture/InteractionTracker.swift +237 -0
  83. package/ios/Capture/PrivacyMaskProcessor.swift +158 -0
  84. package/ios/Capture/ScreenshotCaptureManager.swift +398 -0
  85. package/ios/Capture/WindowResolver.swift +63 -0
  86. package/ios/Core/DeviceIdentity.swift +50 -0
  87. package/ios/Core/ReplayConfig.swift +100 -0
  88. package/ios/Core/ReplayLogger.swift +22 -0
  89. package/ios/Core/SessionIdGenerator.swift +18 -0
  90. package/ios/Crash/ScaleBunCrashBridge.mm +74 -0
  91. package/ios/Crash/ScaleBunCrashHandler.swift +84 -0
  92. package/ios/Crash/ScaleBunCrashModule.swift +98 -0
  93. package/ios/Crash/ScaleBunCrashSignalBridge.h +49 -0
  94. package/ios/Crash/ScaleBunCrashSignalBridge.m +296 -0
  95. package/ios/Crash/ScaleBunCrashSignalStress.c +137 -0
  96. package/ios/Crash/ScaleBunCrashStorage.swift +121 -0
  97. package/ios/Crash/ScaleBunExceptionChain.swift +71 -0
  98. package/ios/CrashTests/ScaleBunExceptionChainTests.swift +144 -0
  99. package/ios/Engage/ScaleBunEngageBridge.m +32 -0
  100. package/ios/Engage/ScaleBunEngageModule.swift +250 -0
  101. package/ios/Engage/ScaleBunPushNotificationCenter.swift +185 -0
  102. package/ios/Ota/BsPatch.swift +203 -0
  103. package/ios/Ota/BundleDownloader.swift +249 -0
  104. package/ios/Ota/DeviceIntegrity.swift +112 -0
  105. package/ios/Ota/DownloadFailure.swift +56 -0
  106. package/ios/Ota/OtaProtocol.swift +246 -0
  107. package/ios/Ota/OtaSlotManager.swift +613 -0
  108. package/ios/Ota/ScaleBunOtaBridge.mm +92 -0
  109. package/ios/Ota/ScaleBunOtaEventsModule.swift +61 -0
  110. package/ios/Ota/ScaleBunOtaKeyRegistry.swift +147 -0
  111. package/ios/Ota/ScaleBunOtaModule.swift +587 -0
  112. package/ios/Ota/ScaleBunOtaReleaseVerifier.swift +119 -0
  113. package/ios/Ota/TlsPinning.swift +222 -0
  114. package/ios/OtaTests/DownloadFailureTests.swift +78 -0
  115. package/ios/OtaTests/ScaleBunOtaVerifierTests.swift +548 -0
  116. package/ios/Outbox/NativeOutbox.swift +632 -0
  117. package/ios/Outbox/OutboxUploader.swift +578 -0
  118. package/ios/Performance/ScaleBunPerformanceBridge.m +32 -0
  119. package/ios/Performance/ScaleBunPerformanceModule.swift +290 -0
  120. package/ios/PrivacyInfo.xcprivacy +97 -0
  121. package/ios/Profiler/ScaleBunProfilerBridge.m +55 -0
  122. package/ios/Profiler/ScaleBunProfilerModule.swift +966 -0
  123. package/ios/ReplaySdk-Bridging-Header.h +2 -0
  124. package/ios/ReplaySdk.swift +793 -0
  125. package/ios/ReplaySdkBridge.m +97 -0
  126. package/ios/Session/SessionManager.swift +273 -0
  127. package/ios/Skan/ScaleBunSkanBridge.m +14 -0
  128. package/ios/Skan/ScaleBunSkanModule.swift +61 -0
  129. package/ios/Storage/ReplayStorage.swift +61 -0
  130. package/ios/Storage/ScaleBunKvFileStore.swift +125 -0
  131. package/ios/Storage/ScaleBunStorageBridge.mm +72 -0
  132. package/ios/Storage/ScaleBunStorageModule.swift +57 -0
  133. package/ios/Transport/ReplayTransport.swift +70 -0
  134. package/ios/VoiceRecorder.swift +145 -0
  135. package/lib/commonjs/analytics/EventTracker.js +598 -0
  136. package/lib/commonjs/analytics/automaticEvents.js +71 -0
  137. package/lib/commonjs/analytics/batching.js +64 -0
  138. package/lib/commonjs/analytics/eventLane.js +55 -0
  139. package/lib/commonjs/analytics/revenue.js +125 -0
  140. package/lib/commonjs/analytics/subscription.js +94 -0
  141. package/lib/commonjs/bootstrap/FeatureRegistry.js +86 -0
  142. package/lib/commonjs/bootstrap/SDKBootstrapper.js +748 -0
  143. package/lib/commonjs/bucketing/fnv1a32.js +45 -0
  144. package/lib/commonjs/compat/codepush.js +153 -0
  145. package/lib/commonjs/config/ConfigManager.js +238 -0
  146. package/lib/commonjs/config/configTypes.js +16 -0
  147. package/lib/commonjs/config/otaPolicyState.js +85 -0
  148. package/lib/commonjs/config/quotaState.js +435 -0
  149. package/lib/commonjs/core/architecture.js +45 -0
  150. package/lib/commonjs/core/clock/now.js +13 -0
  151. package/lib/commonjs/core/config/defaults.js +2 -0
  152. package/lib/commonjs/core/config/schema.js +512 -0
  153. package/lib/commonjs/core/constants/endpoints.js +19 -0
  154. package/lib/commonjs/core/constants/protocol.js +31 -0
  155. package/lib/commonjs/core/constants/timings.js +39 -0
  156. package/lib/commonjs/core/constants/version.js +18 -0
  157. package/lib/commonjs/core/context/app.js +2 -0
  158. package/lib/commonjs/core/context/device.js +155 -0
  159. package/lib/commonjs/core/context/session.js +2 -0
  160. package/lib/commonjs/core/context/user.js +2 -0
  161. package/lib/commonjs/core/contracts/IFeature.js +2 -0
  162. package/lib/commonjs/core/di/container.js +29 -0
  163. package/lib/commonjs/core/encoding/base64.js +50 -0
  164. package/lib/commonjs/core/id/deviceId.js +52 -0
  165. package/lib/commonjs/core/id/installationId.js +55 -0
  166. package/lib/commonjs/core/id/sessionId.js +2 -0
  167. package/lib/commonjs/core/lifecycle/appLifecycle.js +31 -0
  168. package/lib/commonjs/core/lifecycle/crashSafe.js +33 -0
  169. package/lib/commonjs/core/logger/errorClassification.js +107 -0
  170. package/lib/commonjs/core/logger/internalLogger.js +63 -0
  171. package/lib/commonjs/core/logger/levels.js +2 -0
  172. package/lib/commonjs/crypto/hmacSha256.js +132 -0
  173. package/lib/commonjs/debug/bootstrap.js +429 -0
  174. package/lib/commonjs/debug/commands.js +732 -0
  175. package/lib/commonjs/debug/configBuilder.js +70 -0
  176. package/lib/commonjs/debug/exportBridge.js +155 -0
  177. package/lib/commonjs/debug/hostResolver.js +42 -0
  178. package/lib/commonjs/debug/index.js +141 -0
  179. package/lib/commonjs/debug/metrics.js +39 -0
  180. package/lib/commonjs/debug/perf.js +186 -0
  181. package/lib/commonjs/debug/perfWiring.js +109 -0
  182. package/lib/commonjs/debug/protocol.js +121 -0
  183. package/lib/commonjs/debug/redaction.js +422 -0
  184. package/lib/commonjs/debug/replayWiring.js +149 -0
  185. package/lib/commonjs/debug/screenTracking.js +60 -0
  186. package/lib/commonjs/debug/sessionWiring.js +48 -0
  187. package/lib/commonjs/debug/stream.js +542 -0
  188. package/lib/commonjs/debug/transport.js +368 -0
  189. package/lib/commonjs/features/bugreport/BugReportFeature.js +112 -0
  190. package/lib/commonjs/features/bugreport/buildPayload.js +97 -0
  191. package/lib/commonjs/features/bugreport/index.js +2 -0
  192. package/lib/commonjs/features/crash/CrashFeature.js +86 -0
  193. package/lib/commonjs/features/crash/CrashReporter.js +160 -0
  194. package/lib/commonjs/features/crash/NativeCrashFeature.js +42 -0
  195. package/lib/commonjs/features/crash/capture.js +48 -0
  196. package/lib/commonjs/features/crash/globalHandler.js +41 -0
  197. package/lib/commonjs/features/crash/index.js +14 -0
  198. package/lib/commonjs/features/crash/nativeCrashBridge.js +361 -0
  199. package/lib/commonjs/features/crash/rejectionHandler.js +180 -0
  200. package/lib/commonjs/features/crash/scrubCrash.js +158 -0
  201. package/lib/commonjs/features/engage/EngageAnchor.js +132 -0
  202. package/lib/commonjs/features/engage/EngageArchetypeRenderers.js +4292 -0
  203. package/lib/commonjs/features/engage/EngageInAppView.js +2670 -0
  204. package/lib/commonjs/features/engage/EngageInlinePlacement.js +133 -0
  205. package/lib/commonjs/features/engage/EngagePromptProvider.js +1063 -0
  206. package/lib/commonjs/features/engage/EngagePromptView.js +1252 -0
  207. package/lib/commonjs/features/engage/EngageTransport.js +608 -0
  208. package/lib/commonjs/features/engage/EngageVariantContent.js +1778 -0
  209. package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js +54 -0
  210. package/lib/commonjs/features/engage/attachmentCapture.js +48 -0
  211. package/lib/commonjs/features/engage/captureVoiceAttachment.js +88 -0
  212. package/lib/commonjs/features/engage/engageCoachmarkTour.js +106 -0
  213. package/lib/commonjs/features/engage/engageGameLogic.js +308 -0
  214. package/lib/commonjs/features/engage/engageMediaSizing.js +60 -0
  215. package/lib/commonjs/features/engage/engageMultiStepSheet.js +43 -0
  216. package/lib/commonjs/features/engage/engageOutcome.js +118 -0
  217. package/lib/commonjs/features/engage/engagePushTokenBridge.js +72 -0
  218. package/lib/commonjs/features/engage/engageShakeBridge.js +62 -0
  219. package/lib/commonjs/features/engage/engageSignals.js +39 -0
  220. package/lib/commonjs/features/engage/engageStoreReviewBridge.js +49 -0
  221. package/lib/commonjs/features/engage/engageTestSeenStore.js +99 -0
  222. package/lib/commonjs/features/engage/engageThrottle.js +404 -0
  223. package/lib/commonjs/features/engage/engageTriggerEngine.js +365 -0
  224. package/lib/commonjs/features/engage/engageTypes.js +116 -0
  225. package/lib/commonjs/features/engage/engageVariantResolver.js +143 -0
  226. package/lib/commonjs/features/engage/engageWindowInsets.js +98 -0
  227. package/lib/commonjs/features/engage/gestureTriggerDetector.js +85 -0
  228. package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js +55 -0
  229. package/lib/commonjs/features/install-referrer/installReferrer.js +113 -0
  230. package/lib/commonjs/features/journey/ScaleBunDebugRoot.js +1038 -0
  231. package/lib/commonjs/features/journey/ScaleBunFlatList.js +39 -0
  232. package/lib/commonjs/features/journey/ScaleBunImpression.js +113 -0
  233. package/lib/commonjs/features/journey/ScaleBunScrollView.js +102 -0
  234. package/lib/commonjs/features/journey/ScaleBunSectionList.js +39 -0
  235. package/lib/commonjs/features/journey/autoInstrumentScroll.js +161 -0
  236. package/lib/commonjs/features/journey/calibrationContext.js +42 -0
  237. package/lib/commonjs/features/journey/gestureBuffer.js +63 -0
  238. package/lib/commonjs/features/journey/gestureDetector.js +176 -0
  239. package/lib/commonjs/features/journey/impression.js +93 -0
  240. package/lib/commonjs/features/journey/interactionProtocol.js +168 -0
  241. package/lib/commonjs/features/journey/journeyManager.js +466 -0
  242. package/lib/commonjs/features/journey/journeyTypes.js +55 -0
  243. package/lib/commonjs/features/journey/nativeScroll.js +85 -0
  244. package/lib/commonjs/features/journey/navDetector.js +161 -0
  245. package/lib/commonjs/features/journey/screenshotHelper.js +136 -0
  246. package/lib/commonjs/features/journey/scrollContext.js +154 -0
  247. package/lib/commonjs/features/journey/targetGeometry.js +185 -0
  248. package/lib/commonjs/features/journey/targetRegistry.js +53 -0
  249. package/lib/commonjs/features/journey/touchTarget.js +249 -0
  250. package/lib/commonjs/features/journey/uiState.js +188 -0
  251. package/lib/commonjs/features/navigation/AutoScreenDetector.js +607 -0
  252. package/lib/commonjs/features/network/NetworkFeature.js +216 -0
  253. package/lib/commonjs/features/network/index.js +23 -0
  254. package/lib/commonjs/features/network/thirdParty.js +151 -0
  255. package/lib/commonjs/features/ota/OtaEventEmitter.js +129 -0
  256. package/lib/commonjs/features/ota/OtaOrchestrator.js +1309 -0
  257. package/lib/commonjs/features/ota/OtaTypes.js +6 -0
  258. package/lib/commonjs/features/ota/deviceAttributes.js +48 -0
  259. package/lib/commonjs/features/ota/environment.js +172 -0
  260. package/lib/commonjs/features/ota/geoCountry.js +93 -0
  261. package/lib/commonjs/features/ota/retry.js +96 -0
  262. package/lib/commonjs/features/ota/signedDownload.js +187 -0
  263. package/lib/commonjs/features/ota/useOtaUpdate.js +106 -0
  264. package/lib/commonjs/features/performance/PerformanceFeature.js +649 -0
  265. package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js +122 -0
  266. package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js +232 -0
  267. package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js +99 -0
  268. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js +184 -0
  269. package/lib/commonjs/features/performance/collectors/JsStallCollector.js +165 -0
  270. package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js +59 -0
  271. package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js +78 -0
  272. package/lib/commonjs/features/performance/collectors/UiHangCollector.js +78 -0
  273. package/lib/commonjs/features/performance/config.js +58 -0
  274. package/lib/commonjs/features/performance/getNativePerformanceModule.js +44 -0
  275. package/lib/commonjs/features/performance/index.js +58 -0
  276. package/lib/commonjs/features/performance/metrics/MetricsEngine.js +148 -0
  277. package/lib/commonjs/features/performance/models.js +48 -0
  278. package/lib/commonjs/features/performance/transport/PerformanceTransport.js +168 -0
  279. package/lib/commonjs/features/profiler/ProfilerFeature.js +600 -0
  280. package/lib/commonjs/features/profiler/config.js +151 -0
  281. package/lib/commonjs/features/profiler/contracts.js +62 -0
  282. package/lib/commonjs/features/profiler/index.js +40 -0
  283. package/lib/commonjs/features/profiler/models.js +112 -0
  284. package/lib/commonjs/features/profiler/transport/ProfilerTransport.js +94 -0
  285. package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js +203 -0
  286. package/lib/commonjs/features/replay/bridge/eventEmitter.js +128 -0
  287. package/lib/commonjs/features/replay/bridge/nativeModule.js +95 -0
  288. package/lib/commonjs/features/replay/bridge/nativeQuota.js +121 -0
  289. package/lib/commonjs/features/replay/core/clock/clock.js +47 -0
  290. package/lib/commonjs/features/replay/core/config/defaults.js +88 -0
  291. package/lib/commonjs/features/replay/core/config/validator.js +109 -0
  292. package/lib/commonjs/features/replay/core/env/environmentDetector.js +28 -0
  293. package/lib/commonjs/features/replay/core/errors/safeCall.js +42 -0
  294. package/lib/commonjs/features/replay/core/ids/sessionId.js +53 -0
  295. package/lib/commonjs/features/replay/core/logger/logger.js +36 -0
  296. package/lib/commonjs/features/replay/core/privacy/privacyTypes.js +34 -0
  297. package/lib/commonjs/features/replay/core/queue/boundedQueue.js +71 -0
  298. package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js +259 -0
  299. package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js +139 -0
  300. package/lib/commonjs/features/replay/integrations/network/networkAdapter.js +77 -0
  301. package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js +88 -0
  302. package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js +103 -0
  303. package/lib/commonjs/features/replay/pipeline/batching/batchManager.js +119 -0
  304. package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js +52 -0
  305. package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js +53 -0
  306. package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js +67 -0
  307. package/lib/commonjs/features/replay/public/api.js +336 -0
  308. package/lib/commonjs/features/replay/public/enums.js +85 -0
  309. package/lib/commonjs/features/replay/public/types.js +6 -0
  310. package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js +119 -0
  311. package/lib/commonjs/features/replay/replay/frames/frameModels.js +40 -0
  312. package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js +279 -0
  313. package/lib/commonjs/features/replay/replay/timeline/timelineModels.js +120 -0
  314. package/lib/commonjs/features/replay/transport/BackendReplayTransport.js +175 -0
  315. package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js +75 -0
  316. package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js +124 -0
  317. package/lib/commonjs/features/replay/transport/ReplayTransport.js +2 -0
  318. package/lib/commonjs/features/session/BackendSessionAdapter.js +1915 -0
  319. package/lib/commonjs/features/session/DesktopSessionTransport.js +124 -0
  320. package/lib/commonjs/features/session/JourneyEventPipeline.js +244 -0
  321. package/lib/commonjs/features/session/ReplayCaptureManager.js +1253 -0
  322. package/lib/commonjs/features/session/ScrollTracker.js +147 -0
  323. package/lib/commonjs/features/session/SessionManager.js +1448 -0
  324. package/lib/commonjs/features/session/SyncDecisionEngine.js +95 -0
  325. package/lib/commonjs/features/session/frameLink.js +36 -0
  326. package/lib/commonjs/features/session/frameScrollState.js +41 -0
  327. package/lib/commonjs/features/session/index.js +84 -0
  328. package/lib/commonjs/features/session/nativeCapture.js +53 -0
  329. package/lib/commonjs/features/session/outboxFrameCapture.js +83 -0
  330. package/lib/commonjs/features/session/sessionTypes.js +230 -0
  331. package/lib/commonjs/features/session/viewportPlausibility.js +143 -0
  332. package/lib/commonjs/features/skan/skanBridge.js +54 -0
  333. package/lib/commonjs/features/skan/skanConversionManager.js +134 -0
  334. package/lib/commonjs/index.js +267 -0
  335. package/lib/commonjs/integrations/fetch/fetchInterceptor.js +174 -0
  336. package/lib/commonjs/integrations/navigation/screenTracker.js +2 -0
  337. package/lib/commonjs/integrations/network/bodyCapture.js +336 -0
  338. package/lib/commonjs/integrations/xhr/xhrInterceptor.js +224 -0
  339. package/lib/commonjs/metro/composeSourceMap.js +105 -0
  340. package/lib/commonjs/metro/featureModules.js +131 -0
  341. package/lib/commonjs/metro/index.js +230 -0
  342. package/lib/commonjs/metro/optionalDependencyStub.js +6 -0
  343. package/lib/commonjs/metro/optionalModules.js +31 -0
  344. package/lib/commonjs/metro/serializerCompose.js +161 -0
  345. package/lib/commonjs/pipeline/dispatcher/dispatcher.js +28 -0
  346. package/lib/commonjs/pipeline/envelope/envelope.js +17 -0
  347. package/lib/commonjs/pipeline/envelope/serializer.js +14 -0
  348. package/lib/commonjs/pipeline/processors/dedupe.js +2 -0
  349. package/lib/commonjs/pipeline/processors/enrich.js +16 -0
  350. package/lib/commonjs/pipeline/processors/sampling.js +2 -0
  351. package/lib/commonjs/pipeline/processors/sanitize.js +28 -0
  352. package/lib/commonjs/pipeline/queue/flushQueue.js +107 -0
  353. package/lib/commonjs/pipeline/queue/memoryQueue.js +31 -0
  354. package/lib/commonjs/pipeline/queue/persistentQueue.js +342 -0
  355. package/lib/commonjs/pipeline/queue/queuePolicy.js +2 -0
  356. package/lib/commonjs/pipeline/scheduler/flushScheduler.js +45 -0
  357. package/lib/commonjs/pipeline/scheduler/retryPolicy.js +15 -0
  358. package/lib/commonjs/public/ScaleBunErrorBoundary.js +91 -0
  359. package/lib/commonjs/public/ScaleBunFacade.js +2044 -0
  360. package/lib/commonjs/public/ScaleBunProvider.js +62 -0
  361. package/lib/commonjs/public/typedTracker.js +79 -0
  362. package/lib/commonjs/public/types.js +6 -0
  363. package/lib/commonjs/push/PushManager.js +270 -0
  364. package/lib/commonjs/push/adapters/ManualAdapter.js +86 -0
  365. package/lib/commonjs/push/adapters/NativeBridgeAdapter.js +131 -0
  366. package/lib/commonjs/push/adapters/NoopAdapter.js +45 -0
  367. package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js +248 -0
  368. package/lib/commonjs/push/adapters/loadMessaging.js +29 -0
  369. package/lib/commonjs/push/adapters/loadNotifee.js +36 -0
  370. package/lib/commonjs/push/adapters/selectAdapter.js +153 -0
  371. package/lib/commonjs/push/detect/capabilities.js +136 -0
  372. package/lib/commonjs/push/index.js +33 -0
  373. package/lib/commonjs/push/native/nativeNotifications.js +168 -0
  374. package/lib/commonjs/push/types.js +2 -0
  375. package/lib/commonjs/specs/NativeReplaySdk.js +28 -0
  376. package/lib/commonjs/specs/NativeScaleBunCrash.js +30 -0
  377. package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js +24 -0
  378. package/lib/commonjs/specs/NativeScaleBunOta.js +32 -0
  379. package/lib/commonjs/specs/NativeScaleBunPerformance.js +25 -0
  380. package/lib/commonjs/specs/NativeScaleBunProfiler.js +26 -0
  381. package/lib/commonjs/specs/NativeScaleBunStorage.js +40 -0
  382. package/lib/commonjs/storage/StorageBackend.js +240 -0
  383. package/lib/commonjs/storage/db/sqlite.js +2 -0
  384. package/lib/commonjs/storage/files/fileStore.js +2 -0
  385. package/lib/commonjs/transport/auth/sdkSession.js +28 -0
  386. package/lib/commonjs/transport/backoff/exponentialJitter.js +16 -0
  387. package/lib/commonjs/transport/http/endpoints.js +46 -0
  388. package/lib/commonjs/transport/http/httpClient.js +72 -0
  389. package/lib/commonjs/transport/rateLimit/retryAfter.js +2 -0
  390. package/lib/commonjs/transport/signing/requestSigner.js +2 -0
  391. package/lib/commonjs/vendor/protocol/index.js +327 -0
  392. package/lib/commonjs/vendor/protocol/internal/validation.js +429 -0
  393. package/lib/commonjs/vendor/sdk-contracts/bridge.js +2 -0
  394. package/lib/commonjs/vendor/sdk-contracts/config.js +2 -0
  395. package/lib/commonjs/vendor/sdk-contracts/events.js +2 -0
  396. package/lib/commonjs/vendor/sdk-contracts/features.js +2 -0
  397. package/lib/commonjs/vendor/sdk-contracts/index.js +2 -0
  398. package/lib/commonjs/vendor/sdk-contracts/platform.js +2 -0
  399. package/lib/commonjs/vendor/sdk-contracts/session-boundary.js +6 -0
  400. package/lib/commonjs/vendor/sdk-contracts/session.js +2 -0
  401. package/lib/commonjs/vendor/vendor.manifest +10 -0
  402. package/lib/module/analytics/EventTracker.js +592 -0
  403. package/lib/module/analytics/automaticEvents.js +63 -0
  404. package/lib/module/analytics/batching.js +55 -0
  405. package/lib/module/analytics/eventLane.js +47 -0
  406. package/lib/module/analytics/revenue.js +117 -0
  407. package/lib/module/analytics/subscription.js +86 -0
  408. package/lib/module/bootstrap/FeatureRegistry.js +79 -0
  409. package/lib/module/bootstrap/SDKBootstrapper.js +742 -0
  410. package/lib/module/bucketing/fnv1a32.js +37 -0
  411. package/lib/module/compat/codepush.js +147 -0
  412. package/lib/module/config/ConfigManager.js +230 -0
  413. package/lib/module/config/configTypes.js +10 -0
  414. package/lib/module/config/otaPolicyState.js +76 -0
  415. package/lib/module/config/quotaState.js +423 -0
  416. package/lib/module/core/architecture.js +38 -0
  417. package/lib/module/core/clock/now.js +7 -0
  418. package/lib/module/core/config/defaults.js +2 -0
  419. package/lib/module/core/config/schema.js +506 -0
  420. package/lib/module/core/constants/endpoints.js +13 -0
  421. package/lib/module/core/constants/protocol.js +25 -0
  422. package/lib/module/core/constants/timings.js +26 -0
  423. package/lib/module/core/constants/version.js +12 -0
  424. package/lib/module/core/context/app.js +2 -0
  425. package/lib/module/core/context/device.js +143 -0
  426. package/lib/module/core/context/session.js +2 -0
  427. package/lib/module/core/context/user.js +2 -0
  428. package/lib/module/core/contracts/IFeature.js +2 -0
  429. package/lib/module/core/di/container.js +22 -0
  430. package/lib/module/core/encoding/base64.js +44 -0
  431. package/lib/module/core/id/deviceId.js +45 -0
  432. package/lib/module/core/id/installationId.js +50 -0
  433. package/lib/module/core/id/sessionId.js +2 -0
  434. package/lib/module/core/lifecycle/appLifecycle.js +25 -0
  435. package/lib/module/core/lifecycle/crashSafe.js +26 -0
  436. package/lib/module/core/logger/errorClassification.js +96 -0
  437. package/lib/module/core/logger/internalLogger.js +59 -0
  438. package/lib/module/core/logger/levels.js +2 -0
  439. package/lib/module/crypto/hmacSha256.js +126 -0
  440. package/lib/module/debug/bootstrap.js +393 -0
  441. package/lib/module/debug/commands.js +726 -0
  442. package/lib/module/debug/configBuilder.js +63 -0
  443. package/lib/module/debug/exportBridge.js +148 -0
  444. package/lib/module/debug/hostResolver.js +37 -0
  445. package/lib/module/debug/index.js +13 -0
  446. package/lib/module/debug/metrics.js +33 -0
  447. package/lib/module/debug/perf.js +180 -0
  448. package/lib/module/debug/perfWiring.js +102 -0
  449. package/lib/module/debug/protocol.js +19 -0
  450. package/lib/module/debug/redaction.js +411 -0
  451. package/lib/module/debug/replayWiring.js +139 -0
  452. package/lib/module/debug/screenTracking.js +53 -0
  453. package/lib/module/debug/sessionWiring.js +43 -0
  454. package/lib/module/debug/stream.js +536 -0
  455. package/lib/module/debug/transport.js +362 -0
  456. package/lib/module/features/bugreport/BugReportFeature.js +105 -0
  457. package/lib/module/features/bugreport/buildPayload.js +91 -0
  458. package/lib/module/features/bugreport/index.js +2 -0
  459. package/lib/module/features/crash/CrashFeature.js +79 -0
  460. package/lib/module/features/crash/CrashReporter.js +151 -0
  461. package/lib/module/features/crash/NativeCrashFeature.js +36 -0
  462. package/lib/module/features/crash/capture.js +42 -0
  463. package/lib/module/features/crash/globalHandler.js +36 -0
  464. package/lib/module/features/crash/index.js +8 -0
  465. package/lib/module/features/crash/nativeCrashBridge.js +350 -0
  466. package/lib/module/features/crash/rejectionHandler.js +171 -0
  467. package/lib/module/features/crash/scrubCrash.js +149 -0
  468. package/lib/module/features/engage/EngageAnchor.js +121 -0
  469. package/lib/module/features/engage/EngageArchetypeRenderers.js +4264 -0
  470. package/lib/module/features/engage/EngageInAppView.js +2656 -0
  471. package/lib/module/features/engage/EngageInlinePlacement.js +123 -0
  472. package/lib/module/features/engage/EngagePromptProvider.js +1054 -0
  473. package/lib/module/features/engage/EngagePromptView.js +1243 -0
  474. package/lib/module/features/engage/EngageTransport.js +602 -0
  475. package/lib/module/features/engage/EngageVariantContent.js +1771 -0
  476. package/lib/module/features/engage/__test-support__/reactNativeStub.js +52 -0
  477. package/lib/module/features/engage/attachmentCapture.js +42 -0
  478. package/lib/module/features/engage/captureVoiceAttachment.js +80 -0
  479. package/lib/module/features/engage/engageCoachmarkTour.js +94 -0
  480. package/lib/module/features/engage/engageGameLogic.js +287 -0
  481. package/lib/module/features/engage/engageMediaSizing.js +51 -0
  482. package/lib/module/features/engage/engageMultiStepSheet.js +35 -0
  483. package/lib/module/features/engage/engageOutcome.js +108 -0
  484. package/lib/module/features/engage/engagePushTokenBridge.js +65 -0
  485. package/lib/module/features/engage/engageShakeBridge.js +56 -0
  486. package/lib/module/features/engage/engageSignals.js +34 -0
  487. package/lib/module/features/engage/engageStoreReviewBridge.js +43 -0
  488. package/lib/module/features/engage/engageTestSeenStore.js +92 -0
  489. package/lib/module/features/engage/engageThrottle.js +390 -0
  490. package/lib/module/features/engage/engageTriggerEngine.js +360 -0
  491. package/lib/module/features/engage/engageTypes.js +110 -0
  492. package/lib/module/features/engage/engageVariantResolver.js +135 -0
  493. package/lib/module/features/engage/engageWindowInsets.js +89 -0
  494. package/lib/module/features/engage/gestureTriggerDetector.js +80 -0
  495. package/lib/module/features/engage/transcription/TranscriptionProvider.js +46 -0
  496. package/lib/module/features/install-referrer/installReferrer.js +104 -0
  497. package/lib/module/features/journey/ScaleBunDebugRoot.js +1030 -0
  498. package/lib/module/features/journey/ScaleBunFlatList.js +32 -0
  499. package/lib/module/features/journey/ScaleBunImpression.js +105 -0
  500. package/lib/module/features/journey/ScaleBunScrollView.js +95 -0
  501. package/lib/module/features/journey/ScaleBunSectionList.js +32 -0
  502. package/lib/module/features/journey/autoInstrumentScroll.js +155 -0
  503. package/lib/module/features/journey/calibrationContext.js +35 -0
  504. package/lib/module/features/journey/gestureBuffer.js +56 -0
  505. package/lib/module/features/journey/gestureDetector.js +169 -0
  506. package/lib/module/features/journey/impression.js +84 -0
  507. package/lib/module/features/journey/interactionProtocol.js +158 -0
  508. package/lib/module/features/journey/journeyManager.js +459 -0
  509. package/lib/module/features/journey/journeyTypes.js +49 -0
  510. package/lib/module/features/journey/nativeScroll.js +77 -0
  511. package/lib/module/features/journey/navDetector.js +154 -0
  512. package/lib/module/features/journey/screenshotHelper.js +129 -0
  513. package/lib/module/features/journey/scrollContext.js +142 -0
  514. package/lib/module/features/journey/targetGeometry.js +175 -0
  515. package/lib/module/features/journey/targetRegistry.js +44 -0
  516. package/lib/module/features/journey/touchTarget.js +241 -0
  517. package/lib/module/features/journey/uiState.js +176 -0
  518. package/lib/module/features/navigation/AutoScreenDetector.js +601 -0
  519. package/lib/module/features/network/NetworkFeature.js +209 -0
  520. package/lib/module/features/network/index.js +17 -0
  521. package/lib/module/features/network/thirdParty.js +142 -0
  522. package/lib/module/features/ota/OtaEventEmitter.js +123 -0
  523. package/lib/module/features/ota/OtaOrchestrator.js +1302 -0
  524. package/lib/module/features/ota/OtaTypes.js +2 -0
  525. package/lib/module/features/ota/deviceAttributes.js +43 -0
  526. package/lib/module/features/ota/environment.js +165 -0
  527. package/lib/module/features/ota/geoCountry.js +86 -0
  528. package/lib/module/features/ota/retry.js +87 -0
  529. package/lib/module/features/ota/signedDownload.js +174 -0
  530. package/lib/module/features/ota/useOtaUpdate.js +100 -0
  531. package/lib/module/features/performance/PerformanceFeature.js +643 -0
  532. package/lib/module/features/performance/collectors/AppLaunchCollector.js +115 -0
  533. package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js +225 -0
  534. package/lib/module/features/performance/collectors/CustomTraceCollector.js +92 -0
  535. package/lib/module/features/performance/collectors/FrameMetricsCollector.js +177 -0
  536. package/lib/module/features/performance/collectors/JsStallCollector.js +158 -0
  537. package/lib/module/features/performance/collectors/NetworkPerfCollector.js +52 -0
  538. package/lib/module/features/performance/collectors/ScreenLoadCollector.js +71 -0
  539. package/lib/module/features/performance/collectors/UiHangCollector.js +71 -0
  540. package/lib/module/features/performance/config.js +51 -0
  541. package/lib/module/features/performance/getNativePerformanceModule.js +39 -0
  542. package/lib/module/features/performance/index.js +9 -0
  543. package/lib/module/features/performance/metrics/MetricsEngine.js +139 -0
  544. package/lib/module/features/performance/models.js +42 -0
  545. package/lib/module/features/performance/transport/PerformanceTransport.js +162 -0
  546. package/lib/module/features/profiler/ProfilerFeature.js +594 -0
  547. package/lib/module/features/profiler/config.js +143 -0
  548. package/lib/module/features/profiler/contracts.js +56 -0
  549. package/lib/module/features/profiler/index.js +11 -0
  550. package/lib/module/features/profiler/models.js +106 -0
  551. package/lib/module/features/profiler/transport/ProfilerTransport.js +87 -0
  552. package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js +198 -0
  553. package/lib/module/features/replay/bridge/eventEmitter.js +122 -0
  554. package/lib/module/features/replay/bridge/nativeModule.js +89 -0
  555. package/lib/module/features/replay/bridge/nativeQuota.js +109 -0
  556. package/lib/module/features/replay/core/clock/clock.js +37 -0
  557. package/lib/module/features/replay/core/config/defaults.js +82 -0
  558. package/lib/module/features/replay/core/config/validator.js +103 -0
  559. package/lib/module/features/replay/core/env/environmentDetector.js +22 -0
  560. package/lib/module/features/replay/core/errors/safeCall.js +35 -0
  561. package/lib/module/features/replay/core/ids/sessionId.js +44 -0
  562. package/lib/module/features/replay/core/logger/logger.js +29 -0
  563. package/lib/module/features/replay/core/privacy/privacyTypes.js +27 -0
  564. package/lib/module/features/replay/core/queue/boundedQueue.js +64 -0
  565. package/lib/module/features/replay/integrations/alert/alertInstrumentation.js +252 -0
  566. package/lib/module/features/replay/integrations/logs/consoleIntegration.js +131 -0
  567. package/lib/module/features/replay/integrations/network/networkAdapter.js +70 -0
  568. package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js +82 -0
  569. package/lib/module/features/replay/integrations/touch/ReplayRoot.js +96 -0
  570. package/lib/module/features/replay/pipeline/batching/batchManager.js +113 -0
  571. package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js +43 -0
  572. package/lib/module/features/replay/pipeline/retry/retryPolicy.js +45 -0
  573. package/lib/module/features/replay/pipeline/transport/transportTypes.js +60 -0
  574. package/lib/module/features/replay/public/api.js +332 -0
  575. package/lib/module/features/replay/public/enums.js +85 -0
  576. package/lib/module/features/replay/public/types.js +2 -0
  577. package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js +113 -0
  578. package/lib/module/features/replay/replay/frames/frameModels.js +33 -0
  579. package/lib/module/features/replay/replay/session/sessionOrchestrator.js +272 -0
  580. package/lib/module/features/replay/replay/timeline/timelineModels.js +108 -0
  581. package/lib/module/features/replay/transport/BackendReplayTransport.js +169 -0
  582. package/lib/module/features/replay/transport/CompositeReplayTransport.js +68 -0
  583. package/lib/module/features/replay/transport/DesktopReplayTransport.js +119 -0
  584. package/lib/module/features/replay/transport/ReplayTransport.js +2 -0
  585. package/lib/module/features/session/BackendSessionAdapter.js +1908 -0
  586. package/lib/module/features/session/DesktopSessionTransport.js +118 -0
  587. package/lib/module/features/session/JourneyEventPipeline.js +239 -0
  588. package/lib/module/features/session/ReplayCaptureManager.js +1248 -0
  589. package/lib/module/features/session/ScrollTracker.js +141 -0
  590. package/lib/module/features/session/SessionManager.js +1443 -0
  591. package/lib/module/features/session/SyncDecisionEngine.js +88 -0
  592. package/lib/module/features/session/frameLink.js +29 -0
  593. package/lib/module/features/session/frameScrollState.js +34 -0
  594. package/lib/module/features/session/index.js +35 -0
  595. package/lib/module/features/session/nativeCapture.js +45 -0
  596. package/lib/module/features/session/outboxFrameCapture.js +77 -0
  597. package/lib/module/features/session/sessionTypes.js +226 -0
  598. package/lib/module/features/session/viewportPlausibility.js +137 -0
  599. package/lib/module/features/skan/skanBridge.js +48 -0
  600. package/lib/module/features/skan/skanConversionManager.js +128 -0
  601. package/lib/module/index.js +80 -0
  602. package/lib/module/integrations/fetch/fetchInterceptor.js +169 -0
  603. package/lib/module/integrations/navigation/screenTracker.js +2 -0
  604. package/lib/module/integrations/network/bodyCapture.js +320 -0
  605. package/lib/module/integrations/xhr/xhrInterceptor.js +219 -0
  606. package/lib/module/metro/composeSourceMap.js +97 -0
  607. package/lib/module/metro/featureModules.js +123 -0
  608. package/lib/module/metro/index.js +218 -0
  609. package/lib/module/metro/optionalDependencyStub.js +14 -0
  610. package/lib/module/metro/optionalModules.js +25 -0
  611. package/lib/module/metro/serializerCompose.js +152 -0
  612. package/lib/module/pipeline/dispatcher/dispatcher.js +21 -0
  613. package/lib/module/pipeline/envelope/envelope.js +11 -0
  614. package/lib/module/pipeline/envelope/serializer.js +8 -0
  615. package/lib/module/pipeline/processors/dedupe.js +2 -0
  616. package/lib/module/pipeline/processors/enrich.js +10 -0
  617. package/lib/module/pipeline/processors/sampling.js +2 -0
  618. package/lib/module/pipeline/processors/sanitize.js +22 -0
  619. package/lib/module/pipeline/queue/flushQueue.js +102 -0
  620. package/lib/module/pipeline/queue/memoryQueue.js +24 -0
  621. package/lib/module/pipeline/queue/persistentQueue.js +336 -0
  622. package/lib/module/pipeline/queue/queuePolicy.js +2 -0
  623. package/lib/module/pipeline/scheduler/flushScheduler.js +38 -0
  624. package/lib/module/pipeline/scheduler/retryPolicy.js +9 -0
  625. package/lib/module/public/ScaleBunErrorBoundary.js +82 -0
  626. package/lib/module/public/ScaleBunFacade.js +2038 -0
  627. package/lib/module/public/ScaleBunProvider.js +54 -0
  628. package/lib/module/public/typedTracker.js +72 -0
  629. package/lib/module/public/types.js +2 -0
  630. package/lib/module/push/PushManager.js +263 -0
  631. package/lib/module/push/adapters/ManualAdapter.js +79 -0
  632. package/lib/module/push/adapters/NativeBridgeAdapter.js +124 -0
  633. package/lib/module/push/adapters/NoopAdapter.js +38 -0
  634. package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js +241 -0
  635. package/lib/module/push/adapters/loadMessaging.js +23 -0
  636. package/lib/module/push/adapters/loadNotifee.js +30 -0
  637. package/lib/module/push/adapters/selectAdapter.js +147 -0
  638. package/lib/module/push/detect/capabilities.js +130 -0
  639. package/lib/module/push/index.js +9 -0
  640. package/lib/module/push/native/nativeNotifications.js +155 -0
  641. package/lib/module/push/types.js +2 -0
  642. package/lib/module/specs/NativeReplaySdk.js +24 -0
  643. package/lib/module/specs/NativeScaleBunCrash.js +26 -0
  644. package/lib/module/specs/NativeScaleBunInstallReferrer.js +20 -0
  645. package/lib/module/specs/NativeScaleBunOta.js +28 -0
  646. package/lib/module/specs/NativeScaleBunPerformance.js +21 -0
  647. package/lib/module/specs/NativeScaleBunProfiler.js +22 -0
  648. package/lib/module/specs/NativeScaleBunStorage.js +36 -0
  649. package/lib/module/storage/StorageBackend.js +231 -0
  650. package/lib/module/storage/db/sqlite.js +2 -0
  651. package/lib/module/storage/files/fileStore.js +2 -0
  652. package/lib/module/transport/auth/sdkSession.js +21 -0
  653. package/lib/module/transport/backoff/exponentialJitter.js +10 -0
  654. package/lib/module/transport/http/endpoints.js +40 -0
  655. package/lib/module/transport/http/httpClient.js +64 -0
  656. package/lib/module/transport/rateLimit/retryAfter.js +2 -0
  657. package/lib/module/transport/signing/requestSigner.js +2 -0
  658. package/lib/module/vendor/protocol/index.js +312 -0
  659. package/lib/module/vendor/protocol/internal/validation.js +423 -0
  660. package/lib/module/vendor/sdk-contracts/bridge.js +2 -0
  661. package/lib/module/vendor/sdk-contracts/config.js +2 -0
  662. package/lib/module/vendor/sdk-contracts/events.js +2 -0
  663. package/lib/module/vendor/sdk-contracts/features.js +2 -0
  664. package/lib/module/vendor/sdk-contracts/index.js +2 -0
  665. package/lib/module/vendor/sdk-contracts/platform.js +2 -0
  666. package/lib/module/vendor/sdk-contracts/session-boundary.js +2 -0
  667. package/lib/module/vendor/sdk-contracts/session.js +2 -0
  668. package/lib/module/vendor/vendor.manifest +10 -0
  669. package/lib/typescript/analytics/EventTracker.d.ts +197 -0
  670. package/lib/typescript/analytics/automaticEvents.d.ts +30 -0
  671. package/lib/typescript/analytics/batching.d.ts +33 -0
  672. package/lib/typescript/analytics/eventLane.d.ts +22 -0
  673. package/lib/typescript/analytics/revenue.d.ts +94 -0
  674. package/lib/typescript/analytics/subscription.d.ts +35 -0
  675. package/lib/typescript/bootstrap/FeatureRegistry.d.ts +36 -0
  676. package/lib/typescript/bootstrap/SDKBootstrapper.d.ts +82 -0
  677. package/lib/typescript/bucketing/fnv1a32.d.ts +20 -0
  678. package/lib/typescript/compat/codepush.d.ts +76 -0
  679. package/lib/typescript/config/ConfigManager.d.ts +82 -0
  680. package/lib/typescript/config/configTypes.d.ts +73 -0
  681. package/lib/typescript/config/otaPolicyState.d.ts +55 -0
  682. package/lib/typescript/config/quotaState.d.ts +155 -0
  683. package/lib/typescript/core/architecture.d.ts +29 -0
  684. package/lib/typescript/core/clock/now.d.ts +5 -0
  685. package/lib/typescript/core/config/defaults.d.ts +1 -0
  686. package/lib/typescript/core/config/schema.d.ts +107 -0
  687. package/lib/typescript/core/constants/endpoints.d.ts +13 -0
  688. package/lib/typescript/core/constants/protocol.d.ts +23 -0
  689. package/lib/typescript/core/constants/timings.d.ts +22 -0
  690. package/lib/typescript/core/constants/version.d.ts +12 -0
  691. package/lib/typescript/core/context/app.d.ts +1 -0
  692. package/lib/typescript/core/context/device.d.ts +61 -0
  693. package/lib/typescript/core/context/session.d.ts +1 -0
  694. package/lib/typescript/core/context/user.d.ts +24 -0
  695. package/lib/typescript/core/contracts/IFeature.d.ts +44 -0
  696. package/lib/typescript/core/di/container.d.ts +9 -0
  697. package/lib/typescript/core/encoding/base64.d.ts +13 -0
  698. package/lib/typescript/core/id/deviceId.d.ts +9 -0
  699. package/lib/typescript/core/id/installationId.d.ts +20 -0
  700. package/lib/typescript/core/id/sessionId.d.ts +1 -0
  701. package/lib/typescript/core/lifecycle/appLifecycle.d.ts +14 -0
  702. package/lib/typescript/core/lifecycle/crashSafe.d.ts +7 -0
  703. package/lib/typescript/core/logger/errorClassification.d.ts +46 -0
  704. package/lib/typescript/core/logger/internalLogger.d.ts +24 -0
  705. package/lib/typescript/core/logger/levels.d.ts +1 -0
  706. package/lib/typescript/crypto/hmacSha256.d.ts +10 -0
  707. package/lib/typescript/debug/bootstrap.d.ts +148 -0
  708. package/lib/typescript/debug/commands.d.ts +77 -0
  709. package/lib/typescript/debug/configBuilder.d.ts +13 -0
  710. package/lib/typescript/debug/exportBridge.d.ts +27 -0
  711. package/lib/typescript/debug/hostResolver.d.ts +14 -0
  712. package/lib/typescript/debug/index.d.ts +12 -0
  713. package/lib/typescript/debug/metrics.d.ts +2 -0
  714. package/lib/typescript/debug/perf.d.ts +43 -0
  715. package/lib/typescript/debug/perfWiring.d.ts +33 -0
  716. package/lib/typescript/debug/protocol.d.ts +15 -0
  717. package/lib/typescript/debug/redaction.d.ts +69 -0
  718. package/lib/typescript/debug/replayWiring.d.ts +25 -0
  719. package/lib/typescript/debug/screenTracking.d.ts +16 -0
  720. package/lib/typescript/debug/sessionWiring.d.ts +16 -0
  721. package/lib/typescript/debug/stream.d.ts +77 -0
  722. package/lib/typescript/debug/transport.d.ts +110 -0
  723. package/lib/typescript/features/bugreport/BugReportFeature.d.ts +59 -0
  724. package/lib/typescript/features/bugreport/buildPayload.d.ts +51 -0
  725. package/lib/typescript/features/bugreport/index.d.ts +1 -0
  726. package/lib/typescript/features/crash/CrashFeature.d.ts +21 -0
  727. package/lib/typescript/features/crash/CrashReporter.d.ts +107 -0
  728. package/lib/typescript/features/crash/NativeCrashFeature.d.ts +17 -0
  729. package/lib/typescript/features/crash/capture.d.ts +22 -0
  730. package/lib/typescript/features/crash/globalHandler.d.ts +14 -0
  731. package/lib/typescript/features/crash/index.d.ts +2 -0
  732. package/lib/typescript/features/crash/nativeCrashBridge.d.ts +43 -0
  733. package/lib/typescript/features/crash/rejectionHandler.d.ts +65 -0
  734. package/lib/typescript/features/crash/scrubCrash.d.ts +35 -0
  735. package/lib/typescript/features/engage/EngageAnchor.d.ts +36 -0
  736. package/lib/typescript/features/engage/EngageArchetypeRenderers.d.ts +66 -0
  737. package/lib/typescript/features/engage/EngageInAppView.d.ts +164 -0
  738. package/lib/typescript/features/engage/EngageInlinePlacement.d.ts +42 -0
  739. package/lib/typescript/features/engage/EngagePromptProvider.d.ts +233 -0
  740. package/lib/typescript/features/engage/EngagePromptView.d.ts +97 -0
  741. package/lib/typescript/features/engage/EngageTransport.d.ts +158 -0
  742. package/lib/typescript/features/engage/EngageVariantContent.d.ts +12 -0
  743. package/lib/typescript/features/engage/attachmentCapture.d.ts +17 -0
  744. package/lib/typescript/features/engage/captureVoiceAttachment.d.ts +31 -0
  745. package/lib/typescript/features/engage/engageCoachmarkTour.d.ts +18 -0
  746. package/lib/typescript/features/engage/engageGameLogic.d.ts +34 -0
  747. package/lib/typescript/features/engage/engageMediaSizing.d.ts +23 -0
  748. package/lib/typescript/features/engage/engageMultiStepSheet.d.ts +25 -0
  749. package/lib/typescript/features/engage/engageOutcome.d.ts +38 -0
  750. package/lib/typescript/features/engage/engagePushTokenBridge.d.ts +30 -0
  751. package/lib/typescript/features/engage/engageShakeBridge.d.ts +20 -0
  752. package/lib/typescript/features/engage/engageSignals.d.ts +13 -0
  753. package/lib/typescript/features/engage/engageStoreReviewBridge.d.ts +23 -0
  754. package/lib/typescript/features/engage/engageTestSeenStore.d.ts +46 -0
  755. package/lib/typescript/features/engage/engageThrottle.d.ts +180 -0
  756. package/lib/typescript/features/engage/engageTriggerEngine.d.ts +16 -0
  757. package/lib/typescript/features/engage/engageTypes.d.ts +576 -0
  758. package/lib/typescript/features/engage/engageVariantResolver.d.ts +46 -0
  759. package/lib/typescript/features/engage/engageWindowInsets.d.ts +25 -0
  760. package/lib/typescript/features/engage/gestureTriggerDetector.d.ts +20 -0
  761. package/lib/typescript/features/engage/transcription/TranscriptionProvider.d.ts +51 -0
  762. package/lib/typescript/features/install-referrer/installReferrer.d.ts +39 -0
  763. package/lib/typescript/features/journey/ScaleBunDebugRoot.d.ts +49 -0
  764. package/lib/typescript/features/journey/ScaleBunFlatList.d.ts +20 -0
  765. package/lib/typescript/features/journey/ScaleBunImpression.d.ts +30 -0
  766. package/lib/typescript/features/journey/ScaleBunScrollView.d.ts +25 -0
  767. package/lib/typescript/features/journey/ScaleBunSectionList.d.ts +20 -0
  768. package/lib/typescript/features/journey/autoInstrumentScroll.d.ts +46 -0
  769. package/lib/typescript/features/journey/calibrationContext.d.ts +26 -0
  770. package/lib/typescript/features/journey/gestureBuffer.d.ts +27 -0
  771. package/lib/typescript/features/journey/gestureDetector.d.ts +40 -0
  772. package/lib/typescript/features/journey/impression.d.ts +48 -0
  773. package/lib/typescript/features/journey/interactionProtocol.d.ts +159 -0
  774. package/lib/typescript/features/journey/journeyManager.d.ts +62 -0
  775. package/lib/typescript/features/journey/journeyTypes.d.ts +161 -0
  776. package/lib/typescript/features/journey/nativeScroll.d.ts +47 -0
  777. package/lib/typescript/features/journey/navDetector.d.ts +42 -0
  778. package/lib/typescript/features/journey/screenshotHelper.d.ts +33 -0
  779. package/lib/typescript/features/journey/scrollContext.d.ts +49 -0
  780. package/lib/typescript/features/journey/targetGeometry.d.ts +126 -0
  781. package/lib/typescript/features/journey/targetRegistry.d.ts +28 -0
  782. package/lib/typescript/features/journey/touchTarget.d.ts +174 -0
  783. package/lib/typescript/features/journey/uiState.d.ts +93 -0
  784. package/lib/typescript/features/navigation/AutoScreenDetector.d.ts +196 -0
  785. package/lib/typescript/features/network/NetworkFeature.d.ts +43 -0
  786. package/lib/typescript/features/network/index.d.ts +46 -0
  787. package/lib/typescript/features/network/thirdParty.d.ts +95 -0
  788. package/lib/typescript/features/ota/OtaEventEmitter.d.ts +93 -0
  789. package/lib/typescript/features/ota/OtaOrchestrator.d.ts +287 -0
  790. package/lib/typescript/features/ota/OtaTypes.d.ts +193 -0
  791. package/lib/typescript/features/ota/deviceAttributes.d.ts +18 -0
  792. package/lib/typescript/features/ota/environment.d.ts +99 -0
  793. package/lib/typescript/features/ota/geoCountry.d.ts +14 -0
  794. package/lib/typescript/features/ota/retry.d.ts +53 -0
  795. package/lib/typescript/features/ota/signedDownload.d.ts +81 -0
  796. package/lib/typescript/features/ota/useOtaUpdate.d.ts +72 -0
  797. package/lib/typescript/features/performance/PerformanceFeature.d.ts +132 -0
  798. package/lib/typescript/features/performance/collectors/AppLaunchCollector.d.ts +27 -0
  799. package/lib/typescript/features/performance/collectors/AutoScreenLoadCollector.d.ts +70 -0
  800. package/lib/typescript/features/performance/collectors/CustomTraceCollector.d.ts +35 -0
  801. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts +74 -0
  802. package/lib/typescript/features/performance/collectors/JsStallCollector.d.ts +45 -0
  803. package/lib/typescript/features/performance/collectors/NetworkPerfCollector.d.ts +23 -0
  804. package/lib/typescript/features/performance/collectors/ScreenLoadCollector.d.ts +30 -0
  805. package/lib/typescript/features/performance/collectors/UiHangCollector.d.ts +21 -0
  806. package/lib/typescript/features/performance/config.d.ts +73 -0
  807. package/lib/typescript/features/performance/getNativePerformanceModule.d.ts +2 -0
  808. package/lib/typescript/features/performance/index.d.ts +10 -0
  809. package/lib/typescript/features/performance/metrics/MetricsEngine.d.ts +69 -0
  810. package/lib/typescript/features/performance/models.d.ts +169 -0
  811. package/lib/typescript/features/performance/transport/PerformanceTransport.d.ts +40 -0
  812. package/lib/typescript/features/profiler/ProfilerFeature.d.ts +92 -0
  813. package/lib/typescript/features/profiler/config.d.ts +85 -0
  814. package/lib/typescript/features/profiler/contracts.d.ts +142 -0
  815. package/lib/typescript/features/profiler/index.d.ts +13 -0
  816. package/lib/typescript/features/profiler/models.d.ts +332 -0
  817. package/lib/typescript/features/profiler/transport/ProfilerTransport.d.ts +30 -0
  818. package/lib/typescript/features/replay/bridge/adapters/bridgeAdapter.d.ts +52 -0
  819. package/lib/typescript/features/replay/bridge/eventEmitter.d.ts +100 -0
  820. package/lib/typescript/features/replay/bridge/nativeModule.d.ts +166 -0
  821. package/lib/typescript/features/replay/bridge/nativeQuota.d.ts +26 -0
  822. package/lib/typescript/features/replay/core/clock/clock.d.ts +16 -0
  823. package/lib/typescript/features/replay/core/config/defaults.d.ts +28 -0
  824. package/lib/typescript/features/replay/core/config/validator.d.ts +13 -0
  825. package/lib/typescript/features/replay/core/env/environmentDetector.d.ts +14 -0
  826. package/lib/typescript/features/replay/core/errors/safeCall.d.ts +12 -0
  827. package/lib/typescript/features/replay/core/ids/sessionId.d.ts +15 -0
  828. package/lib/typescript/features/replay/core/logger/logger.d.ts +15 -0
  829. package/lib/typescript/features/replay/core/privacy/privacyTypes.d.ts +24 -0
  830. package/lib/typescript/features/replay/core/queue/boundedQueue.d.ts +29 -0
  831. package/lib/typescript/features/replay/integrations/alert/alertInstrumentation.d.ts +48 -0
  832. package/lib/typescript/features/replay/integrations/logs/consoleIntegration.d.ts +18 -0
  833. package/lib/typescript/features/replay/integrations/network/networkAdapter.d.ts +31 -0
  834. package/lib/typescript/features/replay/integrations/react-navigation/navigationIntegration.d.ts +25 -0
  835. package/lib/typescript/features/replay/integrations/touch/ReplayRoot.d.ts +26 -0
  836. package/lib/typescript/features/replay/pipeline/batching/batchManager.d.ts +47 -0
  837. package/lib/typescript/features/replay/pipeline/envelope/envelopeBuilder.d.ts +12 -0
  838. package/lib/typescript/features/replay/pipeline/retry/retryPolicy.d.ts +17 -0
  839. package/lib/typescript/features/replay/pipeline/transport/transportTypes.d.ts +40 -0
  840. package/lib/typescript/features/replay/public/api.d.ts +83 -0
  841. package/lib/typescript/features/replay/public/enums.d.ts +73 -0
  842. package/lib/typescript/features/replay/public/types.d.ts +249 -0
  843. package/lib/typescript/features/replay/replay/breadcrumbs/breadcrumbCollector.d.ts +26 -0
  844. package/lib/typescript/features/replay/replay/frames/frameModels.d.ts +23 -0
  845. package/lib/typescript/features/replay/replay/session/sessionOrchestrator.d.ts +53 -0
  846. package/lib/typescript/features/replay/replay/timeline/timelineModels.d.ts +29 -0
  847. package/lib/typescript/features/replay/transport/BackendReplayTransport.d.ts +45 -0
  848. package/lib/typescript/features/replay/transport/CompositeReplayTransport.d.ts +22 -0
  849. package/lib/typescript/features/replay/transport/DesktopReplayTransport.d.ts +35 -0
  850. package/lib/typescript/features/replay/transport/ReplayTransport.d.ts +72 -0
  851. package/lib/typescript/features/session/BackendSessionAdapter.d.ts +528 -0
  852. package/lib/typescript/features/session/DesktopSessionTransport.d.ts +28 -0
  853. package/lib/typescript/features/session/JourneyEventPipeline.d.ts +74 -0
  854. package/lib/typescript/features/session/ReplayCaptureManager.d.ts +391 -0
  855. package/lib/typescript/features/session/ScrollTracker.d.ts +48 -0
  856. package/lib/typescript/features/session/SessionManager.d.ts +414 -0
  857. package/lib/typescript/features/session/SyncDecisionEngine.d.ts +33 -0
  858. package/lib/typescript/features/session/frameLink.d.ts +27 -0
  859. package/lib/typescript/features/session/frameScrollState.d.ts +27 -0
  860. package/lib/typescript/features/session/index.d.ts +23 -0
  861. package/lib/typescript/features/session/nativeCapture.d.ts +18 -0
  862. package/lib/typescript/features/session/outboxFrameCapture.d.ts +20 -0
  863. package/lib/typescript/features/session/sessionTypes.d.ts +362 -0
  864. package/lib/typescript/features/session/viewportPlausibility.d.ts +72 -0
  865. package/lib/typescript/features/skan/skanBridge.d.ts +18 -0
  866. package/lib/typescript/features/skan/skanConversionManager.d.ts +69 -0
  867. package/lib/typescript/index.d.ts +59 -0
  868. package/lib/typescript/integrations/fetch/fetchInterceptor.d.ts +41 -0
  869. package/lib/typescript/integrations/navigation/screenTracker.d.ts +1 -0
  870. package/lib/typescript/integrations/network/bodyCapture.d.ts +101 -0
  871. package/lib/typescript/integrations/xhr/xhrInterceptor.d.ts +46 -0
  872. package/lib/typescript/metro/composeSourceMap.d.ts +26 -0
  873. package/lib/typescript/metro/featureModules.d.ts +49 -0
  874. package/lib/typescript/metro/index.d.ts +99 -0
  875. package/lib/typescript/metro/optionalDependencyStub.d.ts +14 -0
  876. package/lib/typescript/metro/optionalModules.d.ts +20 -0
  877. package/lib/typescript/metro/serializerCompose.d.ts +46 -0
  878. package/lib/typescript/pipeline/dispatcher/dispatcher.d.ts +7 -0
  879. package/lib/typescript/pipeline/envelope/envelope.d.ts +16 -0
  880. package/lib/typescript/pipeline/envelope/serializer.d.ts +7 -0
  881. package/lib/typescript/pipeline/processors/dedupe.d.ts +1 -0
  882. package/lib/typescript/pipeline/processors/enrich.d.ts +3 -0
  883. package/lib/typescript/pipeline/processors/sampling.d.ts +1 -0
  884. package/lib/typescript/pipeline/processors/sanitize.d.ts +3 -0
  885. package/lib/typescript/pipeline/queue/flushQueue.d.ts +12 -0
  886. package/lib/typescript/pipeline/queue/memoryQueue.d.ts +12 -0
  887. package/lib/typescript/pipeline/queue/persistentQueue.d.ts +120 -0
  888. package/lib/typescript/pipeline/queue/queuePolicy.d.ts +1 -0
  889. package/lib/typescript/pipeline/scheduler/flushScheduler.d.ts +9 -0
  890. package/lib/typescript/pipeline/scheduler/retryPolicy.d.ts +5 -0
  891. package/lib/typescript/public/ScaleBunErrorBoundary.d.ts +44 -0
  892. package/lib/typescript/public/ScaleBunFacade.d.ts +800 -0
  893. package/lib/typescript/public/ScaleBunProvider.d.ts +23 -0
  894. package/lib/typescript/public/typedTracker.d.ts +88 -0
  895. package/lib/typescript/public/types.d.ts +316 -0
  896. package/lib/typescript/push/PushManager.d.ts +69 -0
  897. package/lib/typescript/push/adapters/ManualAdapter.d.ts +40 -0
  898. package/lib/typescript/push/adapters/NativeBridgeAdapter.d.ts +37 -0
  899. package/lib/typescript/push/adapters/NoopAdapter.d.ts +21 -0
  900. package/lib/typescript/push/adapters/RNFirebaseMessagingAdapter.d.ts +39 -0
  901. package/lib/typescript/push/adapters/loadMessaging.d.ts +17 -0
  902. package/lib/typescript/push/adapters/loadNotifee.d.ts +15 -0
  903. package/lib/typescript/push/adapters/selectAdapter.d.ts +20 -0
  904. package/lib/typescript/push/detect/capabilities.d.ts +15 -0
  905. package/lib/typescript/push/index.d.ts +10 -0
  906. package/lib/typescript/push/native/nativeNotifications.d.ts +65 -0
  907. package/lib/typescript/push/types.d.ts +143 -0
  908. package/lib/typescript/specs/NativeReplaySdk.d.ts +69 -0
  909. package/lib/typescript/specs/NativeScaleBunCrash.d.ts +58 -0
  910. package/lib/typescript/specs/NativeScaleBunInstallReferrer.d.ts +28 -0
  911. package/lib/typescript/specs/NativeScaleBunOta.d.ts +141 -0
  912. package/lib/typescript/specs/NativeScaleBunPerformance.d.ts +31 -0
  913. package/lib/typescript/specs/NativeScaleBunProfiler.d.ts +38 -0
  914. package/lib/typescript/specs/NativeScaleBunStorage.d.ts +55 -0
  915. package/lib/typescript/storage/StorageBackend.d.ts +131 -0
  916. package/lib/typescript/storage/db/sqlite.d.ts +1 -0
  917. package/lib/typescript/storage/files/fileStore.d.ts +1 -0
  918. package/lib/typescript/transport/auth/sdkSession.d.ts +10 -0
  919. package/lib/typescript/transport/backoff/exponentialJitter.d.ts +5 -0
  920. package/lib/typescript/transport/http/endpoints.d.ts +26 -0
  921. package/lib/typescript/transport/http/httpClient.d.ts +23 -0
  922. package/lib/typescript/transport/rateLimit/retryAfter.d.ts +1 -0
  923. package/lib/typescript/transport/signing/requestSigner.d.ts +1 -0
  924. package/lib/typescript/vendor/protocol/index.d.ts +345 -0
  925. package/lib/typescript/vendor/protocol/internal/validation.d.ts +114 -0
  926. package/lib/typescript/vendor/sdk-contracts/bridge.d.ts +104 -0
  927. package/lib/typescript/vendor/sdk-contracts/config.d.ts +156 -0
  928. package/lib/typescript/vendor/sdk-contracts/events.d.ts +42 -0
  929. package/lib/typescript/vendor/sdk-contracts/features.d.ts +38 -0
  930. package/lib/typescript/vendor/sdk-contracts/index.d.ts +15 -0
  931. package/lib/typescript/vendor/sdk-contracts/platform.d.ts +35 -0
  932. package/lib/typescript/vendor/sdk-contracts/session-boundary.d.ts +42 -0
  933. package/lib/typescript/vendor/sdk-contracts/session.d.ts +157 -0
  934. package/package.json +153 -0
  935. package/react-native.config.js +24 -0
  936. package/scalebun-react-native.podspec +44 -0
  937. package/src/analytics/EventTracker.ts +654 -0
  938. package/src/analytics/automaticEvents.ts +109 -0
  939. package/src/analytics/batching.ts +54 -0
  940. package/src/analytics/eventLane.ts +48 -0
  941. package/src/analytics/revenue.ts +143 -0
  942. package/src/analytics/subscription.ts +145 -0
  943. package/src/bootstrap/FeatureRegistry.ts +81 -0
  944. package/src/bootstrap/SDKBootstrapper.ts +769 -0
  945. package/src/bucketing/fnv1a32.ts +40 -0
  946. package/src/compat/codepush.ts +189 -0
  947. package/src/config/ConfigManager.ts +233 -0
  948. package/src/config/configTypes.ts +62 -0
  949. package/src/config/otaPolicyState.ts +79 -0
  950. package/src/config/quotaState.ts +484 -0
  951. package/src/core/architecture.ts +39 -0
  952. package/src/core/clock/now.ts +6 -0
  953. package/src/core/config/defaults.ts +0 -0
  954. package/src/core/config/schema.ts +455 -0
  955. package/src/core/constants/endpoints.ts +12 -0
  956. package/src/core/constants/protocol.ts +24 -0
  957. package/src/core/constants/timings.ts +25 -0
  958. package/src/core/constants/version.ts +11 -0
  959. package/src/core/context/app.ts +0 -0
  960. package/src/core/context/device.ts +169 -0
  961. package/src/core/context/session.ts +0 -0
  962. package/src/core/context/user.ts +26 -0
  963. package/src/core/contracts/IFeature.ts +53 -0
  964. package/src/core/di/container.ts +26 -0
  965. package/src/core/encoding/base64.ts +46 -0
  966. package/src/core/id/deviceId.ts +51 -0
  967. package/src/core/id/installationId.ts +52 -0
  968. package/src/core/id/sessionId.ts +0 -0
  969. package/src/core/lifecycle/appLifecycle.ts +33 -0
  970. package/src/core/lifecycle/crashSafe.ts +29 -0
  971. package/src/core/logger/errorClassification.ts +108 -0
  972. package/src/core/logger/internalLogger.ts +65 -0
  973. package/src/core/logger/levels.ts +0 -0
  974. package/src/crypto/hmacSha256.ts +106 -0
  975. package/src/debug/bootstrap.ts +436 -0
  976. package/src/debug/commands.ts +597 -0
  977. package/src/debug/configBuilder.ts +56 -0
  978. package/src/debug/exportBridge.ts +155 -0
  979. package/src/debug/hostResolver.ts +34 -0
  980. package/src/debug/index.ts +25 -0
  981. package/src/debug/metrics.ts +29 -0
  982. package/src/debug/perf.ts +212 -0
  983. package/src/debug/perfWiring.ts +119 -0
  984. package/src/debug/protocol.ts +58 -0
  985. package/src/debug/redaction.ts +483 -0
  986. package/src/debug/replayWiring.ts +148 -0
  987. package/src/debug/screenTracking.ts +55 -0
  988. package/src/debug/sessionWiring.ts +59 -0
  989. package/src/debug/stream.ts +561 -0
  990. package/src/debug/transport.ts +440 -0
  991. package/src/features/bugreport/BugReportFeature.ts +128 -0
  992. package/src/features/bugreport/buildPayload.ts +116 -0
  993. package/src/features/bugreport/index.ts +0 -0
  994. package/src/features/crash/CrashFeature.ts +87 -0
  995. package/src/features/crash/CrashReporter.ts +189 -0
  996. package/src/features/crash/NativeCrashFeature.ts +42 -0
  997. package/src/features/crash/capture.ts +48 -0
  998. package/src/features/crash/globalHandler.ts +39 -0
  999. package/src/features/crash/index.ts +8 -0
  1000. package/src/features/crash/nativeCrashBridge.ts +352 -0
  1001. package/src/features/crash/rejectionHandler.ts +196 -0
  1002. package/src/features/crash/scrubCrash.ts +175 -0
  1003. package/src/features/engage/EngageAnchor.tsx +159 -0
  1004. package/src/features/engage/EngageArchetypeRenderers.tsx +3705 -0
  1005. package/src/features/engage/EngageInAppView.tsx +2678 -0
  1006. package/src/features/engage/EngageInlinePlacement.tsx +169 -0
  1007. package/src/features/engage/EngagePromptProvider.tsx +1318 -0
  1008. package/src/features/engage/EngagePromptView.tsx +1400 -0
  1009. package/src/features/engage/EngageTransport.ts +668 -0
  1010. package/src/features/engage/EngageVariantContent.tsx +1483 -0
  1011. package/src/features/engage/__test-support__/reactNativeStub.js +40 -0
  1012. package/src/features/engage/attachmentCapture.ts +45 -0
  1013. package/src/features/engage/captureVoiceAttachment.ts +81 -0
  1014. package/src/features/engage/engageCoachmarkTour.ts +120 -0
  1015. package/src/features/engage/engageGameLogic.ts +347 -0
  1016. package/src/features/engage/engageMediaSizing.ts +76 -0
  1017. package/src/features/engage/engageMultiStepSheet.ts +53 -0
  1018. package/src/features/engage/engageOutcome.ts +157 -0
  1019. package/src/features/engage/engagePushTokenBridge.ts +84 -0
  1020. package/src/features/engage/engageShakeBridge.ts +67 -0
  1021. package/src/features/engage/engageSignals.ts +40 -0
  1022. package/src/features/engage/engageStoreReviewBridge.ts +48 -0
  1023. package/src/features/engage/engageTestSeenStore.ts +95 -0
  1024. package/src/features/engage/engageThrottle.ts +478 -0
  1025. package/src/features/engage/engageTriggerEngine.ts +350 -0
  1026. package/src/features/engage/engageTypes.ts +712 -0
  1027. package/src/features/engage/engageVariantResolver.ts +364 -0
  1028. package/src/features/engage/engageWindowInsets.ts +108 -0
  1029. package/src/features/engage/gestureTriggerDetector.ts +83 -0
  1030. package/src/features/engage/transcription/TranscriptionProvider.ts +68 -0
  1031. package/src/features/install-referrer/installReferrer.ts +112 -0
  1032. package/src/features/journey/ScaleBunDebugRoot.tsx +1045 -0
  1033. package/src/features/journey/ScaleBunFlatList.tsx +39 -0
  1034. package/src/features/journey/ScaleBunImpression.tsx +109 -0
  1035. package/src/features/journey/ScaleBunScrollView.tsx +101 -0
  1036. package/src/features/journey/ScaleBunSectionList.tsx +39 -0
  1037. package/src/features/journey/autoInstrumentScroll.ts +155 -0
  1038. package/src/features/journey/calibrationContext.ts +44 -0
  1039. package/src/features/journey/gestureBuffer.ts +59 -0
  1040. package/src/features/journey/gestureDetector.ts +162 -0
  1041. package/src/features/journey/impression.ts +92 -0
  1042. package/src/features/journey/interactionProtocol.ts +243 -0
  1043. package/src/features/journey/journeyManager.ts +469 -0
  1044. package/src/features/journey/journeyTypes.ts +215 -0
  1045. package/src/features/journey/nativeScroll.ts +94 -0
  1046. package/src/features/journey/navDetector.ts +149 -0
  1047. package/src/features/journey/screenshotHelper.ts +137 -0
  1048. package/src/features/journey/scrollContext.ts +146 -0
  1049. package/src/features/journey/targetGeometry.ts +197 -0
  1050. package/src/features/journey/targetRegistry.ts +43 -0
  1051. package/src/features/journey/touchTarget.ts +339 -0
  1052. package/src/features/journey/uiState.ts +182 -0
  1053. package/src/features/navigation/AutoScreenDetector.ts +617 -0
  1054. package/src/features/network/NetworkFeature.ts +232 -0
  1055. package/src/features/network/index.ts +59 -0
  1056. package/src/features/network/thirdParty.ts +160 -0
  1057. package/src/features/ota/OtaEventEmitter.ts +187 -0
  1058. package/src/features/ota/OtaOrchestrator.ts +1513 -0
  1059. package/src/features/ota/OtaTypes.ts +230 -0
  1060. package/src/features/ota/deviceAttributes.ts +46 -0
  1061. package/src/features/ota/environment.ts +199 -0
  1062. package/src/features/ota/geoCountry.ts +85 -0
  1063. package/src/features/ota/retry.ts +123 -0
  1064. package/src/features/ota/signedDownload.ts +202 -0
  1065. package/src/features/ota/useOtaUpdate.ts +161 -0
  1066. package/src/features/performance/PerformanceFeature.ts +729 -0
  1067. package/src/features/performance/collectors/AppLaunchCollector.ts +131 -0
  1068. package/src/features/performance/collectors/AutoScreenLoadCollector.ts +258 -0
  1069. package/src/features/performance/collectors/CustomTraceCollector.ts +116 -0
  1070. package/src/features/performance/collectors/FrameMetricsCollector.ts +210 -0
  1071. package/src/features/performance/collectors/JsStallCollector.ts +184 -0
  1072. package/src/features/performance/collectors/NetworkPerfCollector.ts +69 -0
  1073. package/src/features/performance/collectors/ScreenLoadCollector.ts +95 -0
  1074. package/src/features/performance/collectors/UiHangCollector.ts +98 -0
  1075. package/src/features/performance/config.ts +136 -0
  1076. package/src/features/performance/getNativePerformanceModule.ts +38 -0
  1077. package/src/features/performance/index.ts +28 -0
  1078. package/src/features/performance/metrics/MetricsEngine.ts +152 -0
  1079. package/src/features/performance/models.ts +235 -0
  1080. package/src/features/performance/transport/PerformanceTransport.ts +161 -0
  1081. package/src/features/profiler/ProfilerFeature.ts +661 -0
  1082. package/src/features/profiler/config.ts +230 -0
  1083. package/src/features/profiler/contracts.ts +176 -0
  1084. package/src/features/profiler/index.ts +45 -0
  1085. package/src/features/profiler/models.ts +430 -0
  1086. package/src/features/profiler/transport/ProfilerTransport.ts +93 -0
  1087. package/src/features/replay/bridge/adapters/bridgeAdapter.ts +235 -0
  1088. package/src/features/replay/bridge/eventEmitter.ts +176 -0
  1089. package/src/features/replay/bridge/nativeModule.ts +252 -0
  1090. package/src/features/replay/bridge/nativeQuota.ts +111 -0
  1091. package/src/features/replay/core/clock/clock.ts +38 -0
  1092. package/src/features/replay/core/config/defaults.ts +66 -0
  1093. package/src/features/replay/core/config/validator.ts +113 -0
  1094. package/src/features/replay/core/env/environmentDetector.ts +21 -0
  1095. package/src/features/replay/core/errors/safeCall.ts +34 -0
  1096. package/src/features/replay/core/ids/sessionId.ts +44 -0
  1097. package/src/features/replay/core/logger/logger.ts +36 -0
  1098. package/src/features/replay/core/privacy/privacyTypes.ts +41 -0
  1099. package/src/features/replay/core/queue/boundedQueue.ts +71 -0
  1100. package/src/features/replay/integrations/alert/alertInstrumentation.ts +277 -0
  1101. package/src/features/replay/integrations/logs/consoleIntegration.ts +136 -0
  1102. package/src/features/replay/integrations/network/networkAdapter.ts +73 -0
  1103. package/src/features/replay/integrations/react-navigation/navigationIntegration.ts +89 -0
  1104. package/src/features/replay/integrations/touch/ReplayRoot.tsx +114 -0
  1105. package/src/features/replay/pipeline/batching/batchManager.ts +133 -0
  1106. package/src/features/replay/pipeline/envelope/envelopeBuilder.ts +66 -0
  1107. package/src/features/replay/pipeline/retry/retryPolicy.ts +62 -0
  1108. package/src/features/replay/pipeline/transport/transportTypes.ts +85 -0
  1109. package/src/features/replay/public/api.ts +364 -0
  1110. package/src/features/replay/public/enums.ts +78 -0
  1111. package/src/features/replay/public/types.ts +297 -0
  1112. package/src/features/replay/replay/breadcrumbs/breadcrumbCollector.ts +115 -0
  1113. package/src/features/replay/replay/frames/frameModels.ts +45 -0
  1114. package/src/features/replay/replay/session/sessionOrchestrator.ts +286 -0
  1115. package/src/features/replay/replay/timeline/timelineModels.ts +129 -0
  1116. package/src/features/replay/transport/BackendReplayTransport.ts +215 -0
  1117. package/src/features/replay/transport/CompositeReplayTransport.ts +82 -0
  1118. package/src/features/replay/transport/DesktopReplayTransport.ts +140 -0
  1119. package/src/features/replay/transport/ReplayTransport.ts +84 -0
  1120. package/src/features/session/BackendSessionAdapter.ts +1977 -0
  1121. package/src/features/session/DesktopSessionTransport.ts +130 -0
  1122. package/src/features/session/JourneyEventPipeline.ts +278 -0
  1123. package/src/features/session/ReplayCaptureManager.ts +1401 -0
  1124. package/src/features/session/ScrollTracker.ts +166 -0
  1125. package/src/features/session/SessionManager.ts +1687 -0
  1126. package/src/features/session/SyncDecisionEngine.ts +117 -0
  1127. package/src/features/session/frameLink.ts +41 -0
  1128. package/src/features/session/frameScrollState.ts +36 -0
  1129. package/src/features/session/index.ts +88 -0
  1130. package/src/features/session/nativeCapture.ts +43 -0
  1131. package/src/features/session/outboxFrameCapture.ts +79 -0
  1132. package/src/features/session/sessionTypes.ts +528 -0
  1133. package/src/features/session/viewportPlausibility.ts +134 -0
  1134. package/src/features/skan/skanBridge.ts +53 -0
  1135. package/src/features/skan/skanConversionManager.ts +173 -0
  1136. package/src/index.ts +206 -0
  1137. package/src/integrations/fetch/fetchInterceptor.ts +201 -0
  1138. package/src/integrations/navigation/screenTracker.ts +0 -0
  1139. package/src/integrations/network/bodyCapture.ts +328 -0
  1140. package/src/integrations/xhr/xhrInterceptor.ts +259 -0
  1141. package/src/metro/composeSourceMap.ts +104 -0
  1142. package/src/metro/featureModules.ts +143 -0
  1143. package/src/metro/index.ts +336 -0
  1144. package/src/metro/optionalDependencyStub.ts +13 -0
  1145. package/src/metro/optionalModules.ts +27 -0
  1146. package/src/metro/serializerCompose.ts +193 -0
  1147. package/src/pipeline/dispatcher/dispatcher.ts +22 -0
  1148. package/src/pipeline/envelope/envelope.ts +31 -0
  1149. package/src/pipeline/envelope/serializer.ts +14 -0
  1150. package/src/pipeline/processors/dedupe.ts +0 -0
  1151. package/src/pipeline/processors/enrich.ts +11 -0
  1152. package/src/pipeline/processors/sampling.ts +0 -0
  1153. package/src/pipeline/processors/sanitize.ts +23 -0
  1154. package/src/pipeline/queue/flushQueue.ts +144 -0
  1155. package/src/pipeline/queue/memoryQueue.ts +31 -0
  1156. package/src/pipeline/queue/persistentQueue.ts +385 -0
  1157. package/src/pipeline/queue/queuePolicy.ts +0 -0
  1158. package/src/pipeline/scheduler/flushScheduler.ts +47 -0
  1159. package/src/pipeline/scheduler/retryPolicy.ts +8 -0
  1160. package/src/public/ScaleBunErrorBoundary.tsx +91 -0
  1161. package/src/public/ScaleBunFacade.ts +2129 -0
  1162. package/src/public/ScaleBunProvider.tsx +91 -0
  1163. package/src/public/typedTracker.ts +123 -0
  1164. package/src/public/types.ts +362 -0
  1165. package/src/push/PushManager.ts +318 -0
  1166. package/src/push/adapters/ManualAdapter.ts +100 -0
  1167. package/src/push/adapters/NativeBridgeAdapter.ts +142 -0
  1168. package/src/push/adapters/NoopAdapter.ts +46 -0
  1169. package/src/push/adapters/RNFirebaseMessagingAdapter.ts +271 -0
  1170. package/src/push/adapters/loadMessaging.ts +24 -0
  1171. package/src/push/adapters/loadNotifee.ts +29 -0
  1172. package/src/push/adapters/selectAdapter.ts +176 -0
  1173. package/src/push/detect/capabilities.ts +124 -0
  1174. package/src/push/index.ts +22 -0
  1175. package/src/push/native/nativeNotifications.ts +207 -0
  1176. package/src/push/types.ts +159 -0
  1177. package/src/specs/NativeReplaySdk.ts +101 -0
  1178. package/src/specs/NativeScaleBunCrash.ts +64 -0
  1179. package/src/specs/NativeScaleBunInstallReferrer.ts +29 -0
  1180. package/src/specs/NativeScaleBunOta.ts +154 -0
  1181. package/src/specs/NativeScaleBunPerformance.ts +34 -0
  1182. package/src/specs/NativeScaleBunProfiler.ts +41 -0
  1183. package/src/specs/NativeScaleBunStorage.ts +59 -0
  1184. package/src/storage/StorageBackend.ts +272 -0
  1185. package/src/storage/db/sqlite.ts +0 -0
  1186. package/src/storage/files/fileStore.ts +0 -0
  1187. package/src/transport/auth/sdkSession.ts +27 -0
  1188. package/src/transport/backoff/exponentialJitter.ts +9 -0
  1189. package/src/transport/http/endpoints.ts +33 -0
  1190. package/src/transport/http/httpClient.ts +73 -0
  1191. package/src/transport/rateLimit/retryAfter.ts +0 -0
  1192. package/src/transport/signing/requestSigner.ts +0 -0
  1193. package/src/vendor/protocol/index.ts +391 -0
  1194. package/src/vendor/protocol/internal/validation.ts +497 -0
  1195. package/src/vendor/sdk-contracts/bridge.ts +162 -0
  1196. package/src/vendor/sdk-contracts/config.ts +192 -0
  1197. package/src/vendor/sdk-contracts/events.ts +50 -0
  1198. package/src/vendor/sdk-contracts/features.ts +42 -0
  1199. package/src/vendor/sdk-contracts/index.ts +98 -0
  1200. package/src/vendor/sdk-contracts/platform.ts +42 -0
  1201. package/src/vendor/sdk-contracts/session-boundary.ts +55 -0
  1202. package/src/vendor/sdk-contracts/session.ts +225 -0
  1203. package/src/vendor/vendor.manifest +10 -0
@@ -0,0 +1,1443 @@
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 { frameLinkVerdict } from './frameLink';
18
+ import { logger } from '../../core/logger/internalLogger';
19
+ import { DEFAULT_SESSION_REPLAY_CONFIG } from './sessionTypes';
20
+ import { JourneyEventPipeline } from './JourneyEventPipeline';
21
+ import { ReplayCaptureManager } from './ReplayCaptureManager';
22
+ import { makeOutboxFrameCapture } from './outboxFrameCapture';
23
+ import { DesktopSessionTransport } from './DesktopSessionTransport';
24
+ import { SyncDecisionEngine } from './SyncDecisionEngine';
25
+ import { ScrollTracker } from './ScrollTracker';
26
+ import { generateEventId } from '../replay/core/ids/sessionId';
27
+ import { bridgeAdapter } from '../replay/bridge/adapters/bridgeAdapter';
28
+ import { redactBody } from '../../debug/redaction';
29
+ import { consumeCalibrationTarget } from '../journey/calibrationContext';
30
+ import { resolvePlatformOS } from '../../core/context/device';
31
+ import { emitAutomaticEvent } from '../../analytics/automaticEvents';
32
+ import { checkViewport } from './viewportPlausibility';
33
+ import { quotaState } from '../../config/quotaState';
34
+ import { INTERACTION_PROTOCOL_VERSION, automaticInteractionProperties, generateInteractionId } from '../journey/interactionProtocol';
35
+
36
+ // ─── Types ──────────────────────────────────────────────────────────────────
37
+
38
+ // ─── Singleton ──────────────────────────────────────────────────────────────
39
+
40
+ let _instance = null;
41
+
42
+ // ─── Session Manager ────────────────────────────────────────────────────────
43
+
44
+ export class SessionManager {
45
+ desktopTransport = null;
46
+ scrollTracker = null;
47
+ _backendTransport = null;
48
+ /**
49
+ * Feature #4 (heatmaps): route tap/gesture coords to the always-on analytics
50
+ * lane even when no replay recording is active. Additive, opt-in (default off).
51
+ */
52
+ _captureInteractionHeatmap = false;
53
+ session = null;
54
+ active = false;
55
+ timeoutTimer = null;
56
+ crashAnchors = [];
57
+ /** Tracks loading-start timestamps per screen for duration computation */
58
+ loadingStartTimes = new Map();
59
+ /**
60
+ * Always-tracked current screen name.
61
+ * Updated by onScreenChange even when session is inactive, so that when
62
+ * startSession is called we know what screen the user is currently on and
63
+ * can emit the initial SCREEN_VIEW + navigation capture immediately.
64
+ * This is read-only metadata — does NOT produce events or frames while inactive.
65
+ */
66
+ _lastKnownScreen = null;
67
+ /** When the current screen was entered — the basis for SCREEN_EXIT's measured dwellMs. */
68
+ _screenEnteredAt = null;
69
+
70
+ /**
71
+ * Last screenshot-base dimensions reported by the native interaction tracker.
72
+ * Stored in JS-coordinate units (dp on Android, pt on iOS) — both are the same
73
+ * unit RN uses for pageX/pageY, so JS-fallback taps can divide directly without
74
+ * additional conversion. This is the EXACT base the native screenshot is captured
75
+ * in, and avoids using Dimensions.get('window') (which excludes system insets
76
+ * differently across devices and pushes markers ~10% off vertically).
77
+ */
78
+ _lastNativeViewportJsUnits = null;
79
+
80
+ /**
81
+ * Exact-duplicate gesture suppression (QA: one physical tap recorded 2–3×).
82
+ *
83
+ * Measured in production data: the native tracker re-emitted the SAME tap — identical
84
+ * gestureType and identical coordinates to the SUB-PIXEL (e.g. x=466.962890625) — at
85
+ * 160–240ms gaps, sometimes twice. A human re-tap cannot reproduce a sub-pixel float
86
+ * exactly, so exact coordinate equality within the window is a safe discriminator: real
87
+ * double-taps land on at least slightly different pixels and pass through untouched.
88
+ * The pipeline's own 100ms dedup was too narrow for these; this window covers what was
89
+ * actually observed with margin. Sits at the ONE entry point every gesture source funnels
90
+ * through, so recording and analytics lanes are protected equally.
91
+ */
92
+ _lastGestureSig = null;
93
+ _lastGestureTs = 0;
94
+ static GESTURE_DEDUP_WINDOW_MS = 400;
95
+ /** Memoized native file-outbox frame adapter (gated by the backend transport). */
96
+ _outboxFrameCapture = null;
97
+ /** Unsubscribe from quotaState (released in resetInstance). */
98
+ _quotaUnsub = null;
99
+ /** True while frame capture is paused by a `frames` quota block inside an active session. */
100
+ _framesQuotaPaused = false;
101
+ /**
102
+ * Whether capture has run at all in the CURRENT session. Decides start() vs resume() when a
103
+ * frames block lifts: resume() continues the session's sequence, which is only right if this
104
+ * session already produced frames; a session that began blocked gets a clean start().
105
+ */
106
+ _captureStartedThisSession = false;
107
+ constructor(debugTransport, nativeCapture, managerConfig) {
108
+ this._rawTransport = debugTransport;
109
+ this._nativeCapture = nativeCapture;
110
+
111
+ // Merge config with defaults
112
+ this.config = {
113
+ ...DEFAULT_SESSION_REPLAY_CONFIG,
114
+ ...managerConfig?.sessionReplay,
115
+ privacyPolicy: {
116
+ ...DEFAULT_SESSION_REPLAY_CONFIG.privacyPolicy,
117
+ ...managerConfig?.sessionReplay?.privacyPolicy
118
+ }
119
+ };
120
+
121
+ // Create subsystems
122
+ this.desktopTransport = debugTransport ? new DesktopSessionTransport(debugTransport) : null;
123
+ this.pipeline = new JourneyEventPipeline('', {
124
+ maxEventCount: this.config.maxEventCount
125
+ });
126
+ this.captureManager = new ReplayCaptureManager('', this.config, nativeCapture, this._getOutboxFrameCapture());
127
+ this._captureInteractionHeatmap = managerConfig?.captureInteractionHeatmap === true;
128
+ this.syncEngine = new SyncDecisionEngine(managerConfig?.syncPolicy);
129
+
130
+ // Wire pipeline → transport (desktop + optional backend)
131
+ this.pipeline.setEmitCallback(event => {
132
+ this.desktopTransport?.sendEvent(event);
133
+ this._backendTransport?.sendEvent(event);
134
+ });
135
+
136
+ // Wire capture → transport (desktop + optional backend)
137
+ this.captureManager.setFrameEmitCallback((frame, imageData) => {
138
+ this.desktopTransport?.sendFrame(frame, imageData);
139
+ this._backendTransport?.sendFrame(frame, imageData);
140
+ });
141
+ this._wireLoadingIntervals();
142
+
143
+ // Per-feature quota (contract v1): a `frames` block stops capture NOW (not just upload), and
144
+ // its end resumes capture in the SAME session starting from a fresh keyframe.
145
+ this._quotaUnsub = quotaState.subscribe((feature, blocked) => {
146
+ if (feature === 'frames') this._onFramesQuota(blocked);
147
+ });
148
+ }
149
+
150
+ /**
151
+ * Stop or resume frame capture for a `frames` quota block.
152
+ *
153
+ * Stopping goes through `captureManager.stop()` — every pending capture timer is cancelled and
154
+ * the generation bump discards captures already in flight. The adapter purges what was queued.
155
+ * The session itself keeps running: events, network and errors are governed by their own quotas.
156
+ */
157
+ _onFramesQuota(blocked) {
158
+ try {
159
+ if (blocked) {
160
+ if (this.active && !this._framesQuotaPaused) {
161
+ this.captureManager.stop('quota_pause');
162
+ this._framesQuotaPaused = true;
163
+ logger.warn('[SessionManager] Replay frames quota exceeded — frame capture stopped');
164
+ }
165
+ return;
166
+ }
167
+ if (!this._framesQuotaPaused) return;
168
+ this._framesQuotaPaused = false;
169
+ if (!this.active) return;
170
+ if (this._captureStartedThisSession) {
171
+ this.captureManager.resume();
172
+ } else {
173
+ this.captureManager.start(); // fresh per-session state: sequence 0, keyframe first
174
+ this._captureStartedThisSession = true;
175
+ }
176
+ // A keyframe right away: the frames before the pause were discarded, so without one the
177
+ // replay would show nothing until the next navigation/interaction capture.
178
+ this.captureManager.captureManual('manual').catch(() => {});
179
+ __DEV__ && logger.info('[SessionManager] Replay frames quota lifted — capture resumed with a keyframe');
180
+ } catch (err) {
181
+ logger.warn('[SessionManager] frames quota transition failed:', err);
182
+ }
183
+ }
184
+
185
+ /**
186
+ * A wait the capture manager sat through becomes a pair of journey events.
187
+ *
188
+ * The frame it eventually takes shows the LOADED screen, which leaves the span between the
189
+ * tap and that frame unaccounted for — and the player resolves an unaccounted playhead to the
190
+ * previous frame, so it would show the screen the visitor had already left. These two events
191
+ * are what lets the timeline say "this screen was loading, for this long" instead, at roughly
192
+ * 1 KB against the ~56 KB a second screenshot would cost.
193
+ *
194
+ * `reason` rides on the payload rather than becoming a third event type: `timeout` and
195
+ * `network_idle` are the same interval with different endings, and a consumer that does not
196
+ * know about the distinction should still see the band.
197
+ */
198
+ _wireLoadingIntervals() {
199
+ this.captureManager.setLoadingIntervalCallback((phase, screen, detail) => {
200
+ if (phase === 'start') {
201
+ this.emitEvent('LOADING_STARTED', {
202
+ screen,
203
+ payload: {
204
+ screen,
205
+ source: 'replay-hold'
206
+ },
207
+ source: 'sdk'
208
+ });
209
+ return;
210
+ }
211
+ this.emitEvent('LOADING_COMPLETED', {
212
+ screen,
213
+ payload: {
214
+ screen,
215
+ durationMs: detail.durationMs,
216
+ reason: detail.reason,
217
+ source: 'replay-hold'
218
+ },
219
+ source: 'sdk'
220
+ });
221
+ });
222
+ }
223
+
224
+ // ─── Singleton Access ───────────────────────────────────────────────
225
+
226
+ static getInstance(debugTransport, nativeCapture, config) {
227
+ if (!_instance) {
228
+ _instance = new SessionManager(debugTransport, nativeCapture, config);
229
+ }
230
+ return _instance;
231
+ }
232
+ static getExistingInstance() {
233
+ return _instance;
234
+ }
235
+ static resetInstance() {
236
+ if (_instance) {
237
+ _instance.endSession();
238
+ _instance._quotaUnsub?.();
239
+ _instance._quotaUnsub = null;
240
+ }
241
+ _instance = null;
242
+ }
243
+
244
+ /**
245
+ * Attach a backend transport for uploading replay data to the backend API.
246
+ * This is additive — the existing desktop transport remains active if present.
247
+ */
248
+ setBackendTransport(transport) {
249
+ this._backendTransport = transport;
250
+ // A session whose START the backend refused for quota has no row and never will: end the
251
+ // recording instead of capturing into a transport that drops everything for it.
252
+ transport.setSessionRefusedHandler?.(sessionId => {
253
+ if (this.active && this.currentSessionId === sessionId) this.endSession();
254
+ });
255
+ __DEV__ && logger.info('[SessionManager] Backend transport attached (replay → backend upload enabled)');
256
+ }
257
+
258
+ /** Expose the backend transport so features can queue network/errors/performance. */
259
+ getBackendTransport() {
260
+ return this._backendTransport;
261
+ }
262
+
263
+ /**
264
+ * Memoized native file-outbox frame adapter. Always injected into the capture
265
+ * manager; its readiness gate (backed by the backend transport) resolves false
266
+ * when the outbox flags are off / the binary is old, so capture transparently
267
+ * falls back to the legacy `captureScreenshot` path. The closure reads the
268
+ * backend transport lazily at capture time (it attaches after construction).
269
+ */
270
+ _getOutboxFrameCapture() {
271
+ if (!this._outboxFrameCapture) {
272
+ this._outboxFrameCapture = makeOutboxFrameCapture(() => this._backendTransport?.ensureNativeOutboxReady() ?? Promise.resolve(false));
273
+ }
274
+ return this._outboxFrameCapture;
275
+ }
276
+
277
+ /**
278
+ * Attach a desktop transport dynamically.
279
+ * Called when debug mode connects after SDK initialization.
280
+ */
281
+ setDesktopTransport(debugTransport) {
282
+ this.desktopTransport = new DesktopSessionTransport(debugTransport);
283
+ __DEV__ && logger.info('[SessionManager] Desktop transport attached');
284
+ }
285
+
286
+ // ─── Session Lifecycle ──────────────────────────────────────────────
287
+
288
+ get isActive() {
289
+ return this.active;
290
+ }
291
+ get currentSessionId() {
292
+ return this.session?.sessionId ?? null;
293
+ }
294
+ get currentSessionMetadata() {
295
+ return this.session?.metadata ?? null;
296
+ }
297
+
298
+ /**
299
+ * The active RECORDING session ID (`ses-xxx`), or null when no recording
300
+ * is in progress.
301
+ *
302
+ * This is the canonical field that DebugEventStream stamps into every
303
+ * outgoing event's `data.recordingSessionId`. It is the single source of
304
+ * truth for correlating network and performance events with the session
305
+ * that was active when they were captured.
306
+ *
307
+ * Distinct from the TRANSPORT session ID (`debug-xxx`) which lives on
308
+ * the wire envelope's top-level `sessionId` field and never changes.
309
+ */
310
+ get recordingSessionId() {
311
+ return this.active ? this.session?.sessionId ?? null : null;
312
+ }
313
+
314
+ /**
315
+ * Update the native capture function at runtime.
316
+ * Called by ScaleBunDebugRoot once the root View ref is ready for ViewShot.
317
+ * Also updates the active session's capture manager if one exists.
318
+ */
319
+ setNativeCapture(captureFn) {
320
+ this._nativeCapture = captureFn;
321
+ // Hot-swap into active capture manager if session is running
322
+ if (this.active && this.captureManager) {
323
+ this.captureManager.nativeCapture = captureFn;
324
+ __DEV__ && logger.info('[SessionManager] Capture function updated (hot-swap)');
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Start a new session. Idempotent — no-op if already active.
330
+ */
331
+ startSession(metadata) {
332
+ try {
333
+ if (this.active) {
334
+ __DEV__ && logger.debug('[SessionManager] Session already active, skipping start');
335
+ return;
336
+ }
337
+
338
+ // Quota (contract v1): a `sessions` block stops NEW sessions. Adopting an analytics
339
+ // session that is already open is not a new session, so that path stays allowed; minting
340
+ // a fresh recording id to post a new INGESTION_START is not.
341
+ if (this._backendTransport && !this._backendTransport.analyticsSessionId && quotaState.isBlocked('sessions')) {
342
+ logger.warn('[SessionManager] Session not started — sessions quota exceeded');
343
+ return;
344
+ }
345
+
346
+ // One-row merge: adopt the always-on analytics ingestion id as this
347
+ // recording session's id when the backend (SaaS) lane has one open.
348
+ // This threads the analytics id through the pipeline + capture manager
349
+ // below, so every frame/event body carries it AND it becomes
350
+ // currentSessionId at sendSessionStart — keeping endpoint id == body id
351
+ // while attaching frames/journey to the single analytics row (no second
352
+ // INGESTION_START). Legacy/no-clientKey mode has no analytics id → mint
353
+ // a fresh recording id and post to /replay/... as before.
354
+ const sessionId = this._backendTransport?.analyticsSessionId ?? generateSessionId();
355
+
356
+ // Create fresh subsystems for this session
357
+ this.pipeline = new JourneyEventPipeline(sessionId, {
358
+ maxEventCount: this.config.maxEventCount
359
+ });
360
+ this.pipeline.setEmitCallback(event => {
361
+ this.desktopTransport?.sendEvent(event);
362
+ this._backendTransport?.sendEvent(event);
363
+ });
364
+ this.captureManager = new ReplayCaptureManager(sessionId, this.config, this._nativeCapture, this._getOutboxFrameCapture());
365
+ this.captureManager.setFrameEmitCallback((frame, imageData) => {
366
+ this.desktopTransport?.sendFrame(frame, imageData);
367
+ this._backendTransport?.sendFrame(frame, imageData);
368
+ });
369
+
370
+ // A NEW capture manager starts with no callbacks. Frame emission is re-wired above;
371
+ // loading intervals have to be re-wired here for the same reason, or every session
372
+ // after the first records frames and silently stops recording the waits between them.
373
+ this._wireLoadingIntervals();
374
+
375
+ // Create scroll tracker — wired to emit events + trigger capture on settle
376
+ this.scrollTracker = new ScrollTracker(scrollMeta => {
377
+ if (!this.active) return;
378
+
379
+ // Synthesize representative coordinates for the scroll.
380
+ // ScrollTracker only knows content deltas — it has no absolute touch
381
+ // point — but the dashboard CorrelationEngine DROPS any interaction
382
+ // without x/y, and the replay overlay draws scroll/swipe as an arrow
383
+ // that needs normalizedEnd coords. Without this, ScaleBunScrollView scrolls
384
+ // were invisible AND uncounted. Anchor the gesture at screen center and
385
+ // extend by the finger displacement (opposite the content offset delta),
386
+ // matching the finger-path convention native swipes already use.
387
+ const vw = this.session?.metadata?.screenWidth ?? 0;
388
+ const vh = this.session?.metadata?.screenHeight ?? 0;
389
+ const coords = {};
390
+ if (vw > 0 && vh > 0) {
391
+ const cx = vw / 2;
392
+ const cy = vh / 2;
393
+ const ex = Math.max(0, Math.min(vw, cx - scrollMeta.totalDeltaX));
394
+ const ey = Math.max(0, Math.min(vh, cy - scrollMeta.totalDeltaY));
395
+ coords.x = cx;
396
+ coords.y = cy;
397
+ coords.endX = ex;
398
+ coords.endY = ey;
399
+ coords.normalizedX = cx / vw;
400
+ coords.normalizedY = cy / vh;
401
+ coords.normalizedEndX = ex / vw;
402
+ coords.normalizedEndY = ey / vh;
403
+ coords.viewportWidth = vw;
404
+ coords.viewportHeight = vh;
405
+ coords.normalizedPrecomputed = true;
406
+ }
407
+
408
+ // Emit gesture:scroll event.
409
+ // emitEvent() triggers captureManager.onScrollSettle() internally
410
+ // for USER_ACTION events with gestureType='scroll' — no explicit call needed.
411
+ this.emitEvent('USER_ACTION', {
412
+ subtype: 'gesture:scroll',
413
+ payload: {
414
+ gestureType: 'scroll',
415
+ totalDeltaX: scrollMeta.totalDeltaX,
416
+ totalDeltaY: scrollMeta.totalDeltaY,
417
+ dominantDirection: scrollMeta.dominantDirection,
418
+ direction: scrollMeta.dominantDirection,
419
+ durationMs: scrollMeta.durationMs,
420
+ startTs: scrollMeta.startTs,
421
+ endTs: scrollMeta.endTs,
422
+ confidence: 'high',
423
+ ...coords
424
+ },
425
+ source: 'user'
426
+ });
427
+ });
428
+ this.crashAnchors = [];
429
+ this.loadingStartTimes.clear();
430
+
431
+ // Build session object
432
+ this.session = {
433
+ sessionId,
434
+ deviceId: this._rawTransport?.deviceId ?? 'unknown',
435
+ startedAt: Date.now(),
436
+ status: 'active',
437
+ metadata: {
438
+ // The real Platform.OS. This used to be a ternary whose else-branch was 'android'
439
+ // and whose catch was ALSO 'android' — so a macOS session, a Windows session, and
440
+ // a failure to load react-native at all were reported identically, as Android.
441
+ // Enriched by native device info when the bridge answers.
442
+ platform: resolvePlatformOS(),
443
+ buildType: __DEV__ ? 'debug' : 'release',
444
+ ...metadata,
445
+ // Capture window dp dims here so emitEvent() can normalize coords
446
+ // without re-querying Dimensions on every gesture event.
447
+ ...(() => {
448
+ if (metadata?.screenWidth && metadata?.screenHeight) return {};
449
+ try {
450
+ const {
451
+ Dimensions
452
+ } = require('react-native');
453
+ const dims = Dimensions.get('window');
454
+ if (dims.width > 0 && dims.height > 0) {
455
+ return {
456
+ screenWidth: dims.width,
457
+ screenHeight: dims.height
458
+ };
459
+ }
460
+ } catch {/* no-throw */}
461
+ return {};
462
+ })()
463
+ },
464
+ transportState: 'local',
465
+ syncState: 'pending-evaluation',
466
+ artifactIndex: {
467
+ frameRefs: [],
468
+ eventRefs: [],
469
+ networkRefs: [],
470
+ logRefs: [],
471
+ crashAnchors: []
472
+ }
473
+ };
474
+ this.active = true;
475
+
476
+ // Enrich the live session metadata with native device info (appVersion,
477
+ // deviceModel, osVersion, …) so synchronous consumers — e.g. the engage
478
+ // response builder reading `currentSessionMetadata.appVersion` — see real
479
+ // values rather than the platform-only subset known at create time. The
480
+ // session-start metadata above is the fallback when the bridge is
481
+ // unavailable (old native binary). Fire-and-forget, never throws.
482
+ Promise.resolve().then(() => bridgeAdapter.getDeviceInfo()).then(info => {
483
+ const s = this.session;
484
+ if (!info || !s) return;
485
+ const m = s.metadata;
486
+ s.metadata = {
487
+ ...m,
488
+ appVersion: info.appVersion ?? m.appVersion,
489
+ appName: info.appName ?? m.appName,
490
+ bundleId: info.bundleId ?? m.bundleId,
491
+ osVersion: info.osVersion ?? m.osVersion,
492
+ deviceModel: info.deviceModel ?? m.deviceModel
493
+ };
494
+ }).catch(() => {
495
+ /* no-throw: metadata-only fallback */
496
+ });
497
+
498
+ // Notify transport (desktop + optional backend)
499
+ this.desktopTransport?.sendSessionStart(this.session);
500
+ this._backendTransport?.sendSessionStart(this.session);
501
+
502
+ // Emit SESSION_STARTED event
503
+ this.pipeline.emit('SESSION_STARTED', {
504
+ payload: {
505
+ sessionId
506
+ },
507
+ source: 'system'
508
+ });
509
+
510
+ // Start capture manager — unless the `frames` quota is spent, in which case the session
511
+ // runs without frame capture and resumes it (with a keyframe) when the block lifts.
512
+ if (quotaState.isBlocked('frames')) {
513
+ this._framesQuotaPaused = true;
514
+ this._captureStartedThisSession = false;
515
+ logger.warn('[SessionManager] Replay frames quota exceeded — session started without frame capture');
516
+ } else {
517
+ this._framesQuotaPaused = false;
518
+ this._captureStartedThisSession = true;
519
+ this.captureManager.start();
520
+ }
521
+
522
+ // Set timeout
523
+ if (this.config.maxDurationMs > 0) {
524
+ this.timeoutTimer = setTimeout(() => {
525
+ __DEV__ && logger.debug('[SessionManager] Session timeout reached');
526
+ this.endSession('timeout');
527
+ }, this.config.maxDurationMs);
528
+ }
529
+ __DEV__ && logger.info(`[SessionManager] Session started: ${sessionId}`);
530
+
531
+ // ── Replay initial screen ──────────────────────────────────────
532
+ // If the user was already on a screen before pressing Record
533
+ // (typical: app mounted → screen hook fired → screen tracked),
534
+ // emit the initial SCREEN_VIEW now so the session captures the
535
+ // starting screen and triggers the first navigation frame.
536
+ if (this._lastKnownScreen) {
537
+ this.emitEvent('SCREEN_VIEW', {
538
+ screen: this._lastKnownScreen,
539
+ subtype: this._lastKnownScreen,
540
+ source: 'sdk'
541
+ });
542
+ }
543
+ } catch (err) {
544
+ logger.error('[SessionManager] Failed to start session:', err);
545
+ }
546
+ }
547
+
548
+ /**
549
+ * End the current session.
550
+ */
551
+ endSession(reason = 'ended') {
552
+ // Fully idempotent — safe to call multiple times
553
+ if (!this.active) {
554
+ return;
555
+ }
556
+
557
+ // Disable collection FIRST to prevent any re-entrant emission during teardown
558
+ this.active = false;
559
+
560
+ // Guard: session must exist (should always be true if active was true)
561
+ if (!this.session) return;
562
+ try {
563
+ // Clear timeout
564
+ if (this.timeoutTimer) {
565
+ clearTimeout(this.timeoutTimer);
566
+ this.timeoutTimer = null;
567
+ }
568
+
569
+ // Dispose scroll tracker — cancels pending settle timer
570
+ if (this.scrollTracker) {
571
+ this.scrollTracker.dispose();
572
+ this.scrollTracker = null;
573
+ }
574
+
575
+ // Clear loading state
576
+ this.loadingStartTimes.clear();
577
+
578
+ // Emit SESSION_ENDED event
579
+ this.pipeline.emit('SESSION_ENDED', {
580
+ payload: {
581
+ reason
582
+ },
583
+ source: 'system'
584
+ });
585
+
586
+ // Stop capture — this cancels ALL pending timers and increments generation
587
+ this.captureManager.stop();
588
+
589
+ // Build final artifact index
590
+ const eventRefs = this.pipeline.buildEventRefs();
591
+ this.session.artifactIndex = {
592
+ ...eventRefs,
593
+ frameRefs: this.captureManager.getFrameRefs(),
594
+ crashAnchors: this.crashAnchors
595
+ };
596
+
597
+ // Finalize session
598
+ this.session.endedAt = Date.now();
599
+ this.session.status = reason === 'timeout' ? 'timeout' : 'ended';
600
+
601
+ // Run sync evaluation
602
+ const hasCrash = this.crashAnchors.length > 0;
603
+ const hasError = this.pipeline.getEvents().some(e => e.type === 'ERROR_CAPTURED');
604
+ const candidate = SyncDecisionEngine.buildCandidate(this.session.sessionId, this.session.metadata, this.pipeline.count, this.captureManager.count, this.session.endedAt - this.session.startedAt, hasCrash, hasError);
605
+ const decision = this.syncEngine.evaluate(candidate);
606
+ this.session.syncState = decision.shouldSync ? 'eligible' : 'ineligible';
607
+
608
+ // Notify transport (desktop + optional backend)
609
+ this.desktopTransport?.sendSessionEnd(this.session);
610
+ this._backendTransport?.sendSessionEnd(this.session);
611
+
612
+ // Clean up
613
+ this.pipeline.clear();
614
+ this.captureManager.clear();
615
+ // (this.active already set to false above)
616
+
617
+ __DEV__ && logger.info(`[SessionManager] Session ended: ${this.session.sessionId} ` + `(${reason}, sync=${decision.shouldSync}, priority=${decision.priority})`);
618
+ } catch (err) {
619
+ logger.error('[SessionManager] Failed to end session:', err);
620
+ // active is already false — no further cleanup needed
621
+ }
622
+ }
623
+
624
+ // ─── Event Emission ─────────────────────────────────────────────────
625
+
626
+ /**
627
+ * Resolve the dp-space base used to normalize JS-fallback tap coordinates.
628
+ *
629
+ * The screenshot is captured by native in the content-view at its physical
630
+ * pixel size. Normalized coords must divide by that SAME region (converted
631
+ * to dp, since pageX/pageY are dp). Using Dimensions.get('window') (or
632
+ * session.metadata, which is seeded from it) excludes system insets and is
633
+ * ~10% smaller than the content-view — pushing markers off. Preference order:
634
+ * native content-view (px→dp) → session metadata → payload → Dimensions.
635
+ */
636
+ _resolveNormalizationBaseDp(p) {
637
+ // Native screenshot-base size in JS-coordinate units (dp on Android, pt on iOS).
638
+ // This is the EXACT region the native screenshot was captured in, so JS-fallback
639
+ // taps (pageX/pageY in dp/pt) divide directly into the same coord space the
640
+ // marker overlay uses on the dashboard. Highest priority — session metadata
641
+ // and Dimensions.get('window') report the app window which excludes system
642
+ // insets differently across devices and pushes markers off vertically.
643
+ if (this._lastNativeViewportJsUnits) {
644
+ return {
645
+ width: this._lastNativeViewportJsUnits.width,
646
+ height: this._lastNativeViewportJsUnits.height,
647
+ space: this._lastNativeViewportJsUnits.space
648
+ };
649
+ }
650
+ const mw = this.session?.metadata?.screenWidth;
651
+ const mh = this.session?.metadata?.screenHeight;
652
+ if (mw && mh) return {
653
+ width: mw,
654
+ height: mh,
655
+ space: 'session-metadata-dp'
656
+ };
657
+ if (typeof p.viewportWidth === 'number' && p.viewportWidth > 0 && typeof p.viewportHeight === 'number' && p.viewportHeight > 0) {
658
+ return {
659
+ width: p.viewportWidth,
660
+ height: p.viewportHeight,
661
+ space: 'payload-viewport-dp'
662
+ };
663
+ }
664
+ try {
665
+ const {
666
+ Dimensions
667
+ } = require('react-native');
668
+ const dims = Dimensions.get('window');
669
+ if (dims.width > 0 && dims.height > 0) {
670
+ return {
671
+ width: dims.width,
672
+ height: dims.height,
673
+ space: 'root-view-dp'
674
+ };
675
+ }
676
+ } catch {/* no-throw */}
677
+ return null;
678
+ }
679
+
680
+ /**
681
+ * Inject/resolve normalized tap coordinates into a USER_ACTION payload, in place.
682
+ *
683
+ * Mutates `p` to carry normalizedX/Y (+ end coords for swipes/scrolls) so the
684
+ * heatmap can overlay them across viewport sizes. Returns true when the source
685
+ * already provided high-confidence / pre-computed normalized coords (native or
686
+ * JS-root-measured), false when this method JS-estimated them.
687
+ *
688
+ * Extracted from emitEvent so BOTH the replay-recording lane AND the always-on
689
+ * analytics lane (Feature #4) normalize identically — keeping the tap payload
690
+ * keys byte-for-byte the same on both routes.
691
+ */
692
+ _normalizeInteractionPayload(p) {
693
+ // If native tracker already provided high-confidence normalized coords,
694
+ // OR the JS path measured the root-view rect and precomputed normalized
695
+ // coords against it, do not overwrite them with JS estimation.
696
+ const hasNormalizedXY = typeof p.normalizedX === 'number' && typeof p.normalizedY === 'number';
697
+ const alreadyNormalized = hasNormalizedXY && (p.confidence === 'high' || p.normalizedPrecomputed === true);
698
+ if (alreadyNormalized) {
699
+ // Cache the native screenshot base in JS-coordinate units (dp/pt)
700
+ // so subsequent JS-fallback taps normalize against the same region
701
+ // the screenshot was captured from. Android sends px (suffix -px),
702
+ // iOS sends pt (suffix -pt). Both are converted to the unit RN
703
+ // pageX/pageY use, so JS taps divide directly with no extra math.
704
+ const cs = typeof p.coordinateSpace === 'string' ? p.coordinateSpace : '';
705
+
706
+ /**
707
+ * TRUST, BUT CHECK. `confidence: 'high'` means the NATIVE layer measured it — not that
708
+ * the number is right. One production device reports a content view of 288x448 px while
709
+ * telling us its layout width is 434.7dp, an implied density of 0.663 that no screen
710
+ * has. Cached unchecked, that wrong base then normalised every tap in the session and
711
+ * became the screenshot's coordinate space too.
712
+ *
713
+ * `windowWidth` and `density` are attached here so the check has both sides of the
714
+ * invariant and so the BACKEND can re-derive the same verdict from the stored payload —
715
+ * see `viewportPlausibility.ts` for the rule and the 56-device measurement behind it.
716
+ */
717
+ let density = 0;
718
+ let windowWidth = 0;
719
+ try {
720
+ const {
721
+ PixelRatio,
722
+ Dimensions
723
+ } = require('react-native');
724
+ density = PixelRatio.get();
725
+ windowWidth = Dimensions.get('window').width;
726
+ } catch {/* no-throw */}
727
+ const check = checkViewport({
728
+ viewportWidth: typeof p.viewportWidth === 'number' ? p.viewportWidth : null,
729
+ viewportHeight: typeof p.viewportHeight === 'number' ? p.viewportHeight : null,
730
+ windowWidth: windowWidth > 0 ? windowWidth : null,
731
+ coordinateSpace: cs,
732
+ density: density > 0 ? density : null
733
+ });
734
+ p.viewportCheck = check.verdict;
735
+ if (check.reason) p.viewportCheckReason = check.reason;
736
+ if (check.impliedDensity != null) p.impliedDensity = check.impliedDensity;
737
+ if (typeof p.viewportWidth === 'number' && p.viewportWidth > 0 && typeof p.viewportHeight === 'number' && p.viewportHeight > 0 && check.verdict !== 'implausible') {
738
+ if (cs.endsWith('-px')) {
739
+ if (density > 0) {
740
+ this._lastNativeViewportJsUnits = {
741
+ width: p.viewportWidth / density,
742
+ height: p.viewportHeight / density,
743
+ space: 'native-content-view-dp'
744
+ };
745
+ }
746
+ } else if (cs.endsWith('-pt')) {
747
+ // iOS already in pt — same unit as RN pageX/pageY
748
+ this._lastNativeViewportJsUnits = {
749
+ width: p.viewportWidth,
750
+ height: p.viewportHeight,
751
+ space: 'native-window-pt'
752
+ };
753
+ }
754
+ } else if (check.verdict === 'implausible') {
755
+ /**
756
+ * The native base is unusable, so fall back to the window and RE-NORMALISE.
757
+ *
758
+ * The coordinates already on the payload were divided by the bad base, so leaving
759
+ * them would keep every tap in the wrong place — the point of rejecting the base is
760
+ * to stop using it, including for the numbers already computed from it. The
761
+ * original is kept under `rejectedViewportW/H` so the device stays diagnosable
762
+ * from stored data instead of needing the handset.
763
+ */
764
+ p.rejectedViewportWidth = p.viewportWidth;
765
+ p.rejectedViewportHeight = p.viewportHeight;
766
+ this._lastNativeViewportJsUnits = null;
767
+
768
+ /**
769
+ * The window, taken DIRECTLY — not via `_resolveNormalizationBaseDp`.
770
+ *
771
+ * That helper would walk its priority list and land straight back on the rejected
772
+ * number: its third branch reads `p.viewportWidth` off this very payload, and its
773
+ * second reads `session.metadata.screenWidth`, which on a device that misreports
774
+ * its content view has no reason to be any more trustworthy. Rejecting a source and
775
+ * then re-selecting it through a helper is how a fix becomes a no-op.
776
+ *
777
+ * `Dimensions.get('window')` is the measurement the invariant just CONFIRMED is
778
+ * sound — on the failing device its 434.7dp is exactly right for a 1440px screen —
779
+ * so it is the one source that has earned being the fallback here.
780
+ */
781
+ let winW = 0;
782
+ let winH = 0;
783
+ try {
784
+ const {
785
+ Dimensions
786
+ } = require('react-native');
787
+ const d = Dimensions.get('window');
788
+ winW = d.width;
789
+ winH = d.height;
790
+ } catch {/* no-throw */}
791
+ const rx = typeof p.x === 'number' ? p.x : undefined;
792
+ const ry = typeof p.y === 'number' ? p.y : undefined;
793
+ if (winW > 0 && winH > 0) {
794
+ // `x`/`y` arrived in the REJECTED space (px), so they have to be converted into
795
+ // the window's unit before dividing, or the normalisation is wrong a second time.
796
+ const rejW = typeof p.rejectedViewportWidth === 'number' ? p.rejectedViewportWidth : 0;
797
+ const rejH = typeof p.rejectedViewportHeight === 'number' ? p.rejectedViewportHeight : 0;
798
+ if (rx !== undefined && ry !== undefined && rejW > 0 && rejH > 0) {
799
+ // Scale-free: the tap's POSITION within the rejected frame is still the best
800
+ // estimate of where the finger was, even though the frame's absolute size was
801
+ // nonsense. Re-express it against the window instead of re-dividing raw px.
802
+ const nx = Math.max(0, Math.min(1, rx / rejW));
803
+ const ny = Math.max(0, Math.min(1, ry / rejH));
804
+ p.normalizedX = nx;
805
+ p.normalizedY = ny;
806
+ p.x = nx * winW;
807
+ p.y = ny * winH;
808
+ }
809
+ p.viewportWidth = winW;
810
+ p.viewportHeight = winH;
811
+ p.coordinateSpace = 'window-fallback-dp';
812
+ p.confidence = 'derived';
813
+ }
814
+ }
815
+ } else {
816
+ // Resolve the normalization base (in dp). Priority:
817
+ // 1. session metadata screen size
818
+ // 2. native content-view size (px → dp via PixelRatio) — matches screenshot
819
+ // 3. payload viewport
820
+ // 4. Dimensions.get('window') — last resort (excludes insets, ~10% off)
821
+ const base = this._resolveNormalizationBaseDp(p);
822
+ const x = typeof p.x === 'number' ? p.x : undefined;
823
+ const y = typeof p.y === 'number' ? p.y : undefined;
824
+ if (x !== undefined && y !== undefined && base) {
825
+ p.normalizedX = Math.max(0, Math.min(1, x / base.width));
826
+ p.normalizedY = Math.max(0, Math.min(1, y / base.height));
827
+ p.viewportWidth = base.width;
828
+ p.viewportHeight = base.height;
829
+ p.coordinateSpace = base.space;
830
+ }
831
+ const endX = typeof p.endX === 'number' ? p.endX : undefined;
832
+ const endY = typeof p.endY === 'number' ? p.endY : undefined;
833
+ if (endX !== undefined && endY !== undefined && base) {
834
+ p.normalizedEndX = Math.max(0, Math.min(1, endX / base.width));
835
+ p.normalizedEndY = Math.max(0, Math.min(1, endY / base.height));
836
+ }
837
+ }
838
+ return alreadyNormalized;
839
+ }
840
+
841
+ /**
842
+ * Feature #4 (heatmaps) — additive analytics emission.
843
+ *
844
+ * Routes a tap/gesture to the always-on ANALYTICS lane (BackendSessionAdapter
845
+ * .trackEvent) so coords are captured even when no replay recording is active.
846
+ *
847
+ * Strictly additive and isolated:
848
+ * - Only runs when `_captureInteractionHeatmap` is ON (opt-in flag) AND a
849
+ * backend analytics transport is attached AND no recording is active
850
+ * (when active, the recording lane already emits the SAME USER_ACTION —
851
+ * emitting here too would duplicate it).
852
+ * - Reuses the EXACT recording payload shape (USER_ACTION + the same keys:
853
+ * normalizedX, normalizedY, gestureType, screen, …) so the backend
854
+ * aggregate reads them identically (no protocol/schema change).
855
+ * - Normalizes via the same _normalizeInteractionPayload used by recording.
856
+ * - Respects redaction: payload is passed through redactBody so any caller-
857
+ * injected sensitive keys (e.g. a label) are stripped before transport.
858
+ * - Never throws.
859
+ */
860
+ _emitInteractionToAnalytics(gestureType, payload, occurredAt, screenName) {
861
+ if (!this._captureInteractionHeatmap) return false;
862
+ if (this.active) return false; // recording lane already carries this tap
863
+ const adapter = this._backendTransport;
864
+ if (!adapter) return false;
865
+ try {
866
+ // Normalize coords in place (same logic as the recording lane).
867
+ this._normalizeInteractionPayload(payload);
868
+
869
+ // Respect redaction before handing to transport. redactBody returns a
870
+ // new object and strips known-sensitive keys; coords/gesture survive.
871
+ const safePayload = redactBody(payload);
872
+
873
+ /**
874
+ * NO `frameId` HERE, and it is not an oversight.
875
+ *
876
+ * This method is guarded by `if (this.active) return;` — it runs ONLY when no replay
877
+ * recording is active, which is precisely when no screenshots are being captured.
878
+ * There is no frame on screen to point at, so an analytics-lane tap can never be
879
+ * attributed to a visual state.
880
+ *
881
+ * That makes it a permanent property of this lane rather than a gap to close later,
882
+ * and the dashboard has to account for it: these taps live in the heatmap grid
883
+ * alongside recorded ones, so a state filter necessarily covers a subset of the
884
+ * traffic. `heat:screen-coverage` reports that subset's size per app for exactly this
885
+ * reason.
886
+ */
887
+ const event = {
888
+ eventId: generateEventId(),
889
+ // sessionId is (re)stamped by the analytics lane at flush time.
890
+ sessionId: adapter.analyticsSessionId ?? '',
891
+ ts: occurredAt,
892
+ type: 'USER_ACTION',
893
+ subtype: `gesture:${gestureType}`,
894
+ screen: screenName ?? this._lastKnownScreen ?? undefined,
895
+ payload: safePayload,
896
+ source: 'user'
897
+ };
898
+ adapter.trackEvent(event);
899
+ return true;
900
+ } catch (err) {
901
+ logger.error('[SessionManager] heatmap analytics emit failed:', err);
902
+ return false;
903
+ }
904
+ }
905
+
906
+ /**
907
+ * Emit a canonical event into the session pipeline.
908
+ * This is the primary entry point for all event sources.
909
+ */
910
+ emitEvent(type, opts) {
911
+ if (!this.active) return;
912
+ try {
913
+ // Pre-process USER_ACTION events to inject normalized coordinates for heatmap readiness
914
+ if (type === 'USER_ACTION' && opts?.payload) {
915
+ const p = opts.payload;
916
+ const alreadyNormalized = this._normalizeInteractionPayload(p);
917
+ __DEV__ && logger.debug(`[TapAccuracy] sink platform=${p.platform ?? '?'} space=${p.coordinateSpace ?? '?'} ` + `source=${alreadyNormalized ? p.confidence === 'high' ? 'native-high' : 'js-precomputed' : 'js-estimated'} ` + `norm=(${p.normalizedX},${p.normalizedY}) base=(${p.viewportWidth}x${p.viewportHeight})`);
918
+
919
+ // ─── Diagnostic: merge calibration expected target (if a calibration
920
+ // screen stamped it within the TTL) and emit ONE unified [TapDiag]
921
+ // JSON object per gesture. Observability only — no math runs here.
922
+ const cal = consumeCalibrationTarget();
923
+ if (cal) {
924
+ p.expectedTargetId = cal.targetId;
925
+ p.expectedNX = cal.expectedNX;
926
+ p.expectedNY = cal.expectedNY;
927
+ }
928
+ try {
929
+ const meta = this.session?.metadata;
930
+ const diag = {
931
+ tag: 'TapDiag',
932
+ side: 'sdk',
933
+ platform: p.platform ?? null,
934
+ coordinateSource: alreadyNormalized ? p.confidence === 'high' ? 'native-high' : 'js-precomputed' : 'js-estimated',
935
+ coordinateSpace: p.coordinateSpace ?? null,
936
+ targetId: p.expectedTargetId ?? p.target ?? null,
937
+ expectedNX: p.expectedNX ?? null,
938
+ expectedNY: p.expectedNY ?? null,
939
+ rawX: p.x ?? null,
940
+ rawY: p.y ?? null,
941
+ pageX: p.pageX ?? null,
942
+ pageY: p.pageY ?? null,
943
+ locationX: p.locationX ?? null,
944
+ locationY: p.locationY ?? null,
945
+ normalizedX: p.normalizedX ?? null,
946
+ normalizedY: p.normalizedY ?? null,
947
+ viewportWidth: p.viewportWidth ?? null,
948
+ viewportHeight: p.viewportHeight ?? null,
949
+ rootViewWidth: p.rootViewWidth ?? null,
950
+ rootViewHeight: p.rootViewHeight ?? null,
951
+ rootViewLeft: p.rootViewLeft ?? null,
952
+ rootViewTop: p.rootViewTop ?? null,
953
+ screenWidth: p.screenWidth ?? meta?.screenWidth ?? null,
954
+ screenHeight: p.screenHeight ?? meta?.screenHeight ?? null,
955
+ windowWidth: p.windowWidth ?? null,
956
+ windowHeight: p.windowHeight ?? null,
957
+ statusBarHeight: p.statusBarHeight ?? null,
958
+ safeAreaTop: p.safeAreaTop ?? null,
959
+ timestamp: Date.now(),
960
+ confidence: p.confidence ?? null,
961
+ source: p.source ?? null
962
+ };
963
+ // Dev-only diagnostic echo. Must NOT emit in release: the console
964
+ // capture integration (captureConsoleLogs) would otherwise forward
965
+ // one [TapDiag] line per tap into the customer-facing Logs lane and
966
+ // bury their own logs. Sibling [TapAccuracy] log above is __DEV__-gated
967
+ // for the same reason; the heatmap/replay data flows through the
968
+ // interaction pipeline, not this echo, so gating it loses nothing.
969
+ // eslint-disable-next-line no-console
970
+ if (__DEV__) console.log('[TapDiag]', JSON.stringify(diag));
971
+ } catch {/* no-throw */}
972
+ }
973
+
974
+ /**
975
+ * Which frame was on screen when this happened.
976
+ *
977
+ * Resolved BEFORE `pipeline.emit`, and deliberately before the capture triggers
978
+ * below: those capture the frame that shows the RESULT of the interaction, and a tap
979
+ * belongs to the state it was made IN, not the one it produced. Reading after them
980
+ * would attribute every tap to its own consequence.
981
+ *
982
+ * USER_ACTION only. A SCREEN_VIEW's frame is the screen being left, which is
983
+ * misleading rather than useful, and no consumer asks for it.
984
+ *
985
+ * `currentKeyframe` returns null unless the frame is from this same screen and still
986
+ * fresh — see its contract. Null is the common, correct answer and stays absent on
987
+ * the event rather than becoming a default.
988
+ */
989
+ /**
990
+ * The keyframe is LINKED only when it can show this tap: a tap made after the list was
991
+ * scrolled is not a tap on the picture taken before it (frameLink.ts). The verdict and the
992
+ * frame's age ride on the payload, so a missing or unverified link is visible, not silent.
993
+ */
994
+ let framedOpts = opts;
995
+ if (type === 'USER_ACTION') {
996
+ const kf = this.captureManager?.currentKeyframe(opts?.screen ?? this._lastKnownScreen ?? undefined);
997
+ const link = frameLinkVerdict(kf, opts?.payload?.['scroll_context']);
998
+ const at = typeof opts?.timestamp === 'number' ? opts.timestamp : Date.now();
999
+ framedOpts = {
1000
+ ...opts,
1001
+ frameId: kf && (link === 'linked' || link === 'unverified') ? kf.frameId : undefined,
1002
+ payload: {
1003
+ ...(opts?.payload ?? {}),
1004
+ frame_link: link,
1005
+ ...(kf ? {
1006
+ frame_age_ms: Math.max(0, at - kf.capturedAt)
1007
+ } : {})
1008
+ }
1009
+ };
1010
+ }
1011
+ const event = this.pipeline.emit(type, framedOpts);
1012
+
1013
+ // Trigger capture on screen view or interaction
1014
+ if (event) {
1015
+ if (type === 'SCREEN_VIEW' && opts?.screen) {
1016
+ this.captureManager.onScreenChange(opts.screen);
1017
+ } else if (type === 'USER_ACTION') {
1018
+ // Extract interaction coordinates from the gesture payload
1019
+ // so the captured frame carries tap location metadata.
1020
+ const p = opts?.payload;
1021
+ const x = typeof p?.x === 'number' ? p.x : undefined;
1022
+ const y = typeof p?.y === 'number' ? p.y : undefined;
1023
+ const gestureType = typeof p?.gestureType === 'string' ? p.gestureType : undefined;
1024
+
1025
+ // Scroll gestures use onScrollSettle (which debounces into a single
1026
+ // capture). Using onInteraction for scroll would produce a DUPLICATE
1027
+ // screenshot alongside the ScrollTracker's onScrollSettle call.
1028
+ if (gestureType === 'scroll') {
1029
+ this.captureManager.onScrollSettle(opts?.screen ?? this._lastKnownScreen ?? undefined);
1030
+ } else {
1031
+ let interactionPoint;
1032
+ if (x !== undefined && y !== undefined && gestureType) {
1033
+ interactionPoint = {
1034
+ x,
1035
+ y,
1036
+ normalizedX: typeof p?.normalizedX === 'number' ? p.normalizedX : undefined,
1037
+ normalizedY: typeof p?.normalizedY === 'number' ? p.normalizedY : undefined,
1038
+ screenWidth: this.session?.metadata?.screenWidth ?? 0,
1039
+ screenHeight: this.session?.metadata?.screenHeight ?? 0,
1040
+ viewportWidth: typeof p?.viewportWidth === 'number' ? p.viewportWidth : undefined,
1041
+ viewportHeight: typeof p?.viewportHeight === 'number' ? p.viewportHeight : undefined,
1042
+ gestureType,
1043
+ endX: typeof p?.endX === 'number' ? p.endX : undefined,
1044
+ endY: typeof p?.endY === 'number' ? p.endY : undefined,
1045
+ normalizedEndX: typeof p?.normalizedEndX === 'number' ? p.normalizedEndX : undefined,
1046
+ normalizedEndY: typeof p?.normalizedEndY === 'number' ? p.normalizedEndY : undefined,
1047
+ durationMs: typeof p?.durationMs === 'number' ? p.durationMs : undefined,
1048
+ direction: typeof p?.direction === 'string' ? p.direction : undefined
1049
+ };
1050
+ }
1051
+ this.captureManager.onInteraction(interactionPoint);
1052
+ }
1053
+ }
1054
+ }
1055
+ } catch (err) {
1056
+ logger.error('[SessionManager] emitEvent failed:', err);
1057
+ }
1058
+ }
1059
+
1060
+ /**
1061
+ * Anchor a crash in the session context.
1062
+ * Protects nearby events and frames from eviction.
1063
+ */
1064
+ anchorCrash(crashEventId) {
1065
+ if (!this.active) return null;
1066
+ try {
1067
+ // Anchor events
1068
+ const anchor = this.pipeline.anchorCrash(crashEventId);
1069
+
1070
+ // Anchor frames (protect frames near the crash timestamp)
1071
+ const crashEvent = this.pipeline.getEvents().find(e => e.eventId === crashEventId);
1072
+ if (crashEvent) {
1073
+ const protectedFrameIds = this.captureManager.protectFramesNearCrash(crashEvent.ts);
1074
+ anchor.nearbyFrameIds = protectedFrameIds;
1075
+ }
1076
+
1077
+ // Capture an error-context frame
1078
+ this.captureManager.captureManual('error-context').catch(() => {});
1079
+ this.crashAnchors.push(anchor);
1080
+ __DEV__ && logger.debug(`[SessionManager] Crash anchored: ${crashEventId}, ` + `protected ${anchor.nearbyEventIds.length} events, ` + `${anchor.nearbyFrameIds.length} frames`);
1081
+ return anchor;
1082
+ } catch (err) {
1083
+ logger.error('[SessionManager] anchorCrash failed:', err);
1084
+ return null;
1085
+ }
1086
+ }
1087
+
1088
+ // ─── Navigation / Screen Integration ────────────────────────────────
1089
+
1090
+ /**
1091
+ * Notify of a screen change. Called by ScaleBunDebugRoot via NavDetector.
1092
+ */
1093
+ /** The screen currently on top, or null before the first navigation is observed. */
1094
+ getLastKnownScreen() {
1095
+ return this._lastKnownScreen;
1096
+ }
1097
+ onScreenChange(screenName) {
1098
+ // Always track the current screen — even when inactive.
1099
+ // This allows startSession to emit the initial SCREEN_VIEW for
1100
+ // the screen that was already mounted before Record was pressed.
1101
+ const previous = this._lastKnownScreen;
1102
+ const enteredAt = this._screenEnteredAt;
1103
+ this._lastKnownScreen = screenName;
1104
+ this._screenEnteredAt = Date.now();
1105
+ if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
1106
+
1107
+ // SCREEN_EXIT for the screen being left, carrying its dwell time.
1108
+ //
1109
+ // The exit was previously detectable ONLY inside the Engage trigger engine and never became an
1110
+ // event, so time-on-screen had to be inferred from the gap to the NEXT SCREEN_VIEW — which is
1111
+ // wrong whenever the app backgrounds in between, and impossible for the last screen of a
1112
+ // session. Emitting it here makes dwell a measured value rather than a derived guess.
1113
+ if (previous && previous !== screenName && enteredAt != null) {
1114
+ this.emitEvent('SCREEN_EXIT', {
1115
+ screen: previous,
1116
+ subtype: previous,
1117
+ source: 'sdk',
1118
+ payload: {
1119
+ dwellMs: Math.max(0, Date.now() - enteredAt),
1120
+ to: screenName
1121
+ }
1122
+ });
1123
+ }
1124
+ this.emitEvent('SCREEN_VIEW', {
1125
+ screen: screenName,
1126
+ subtype: screenName,
1127
+ source: 'sdk',
1128
+ ...(previous && previous !== screenName ? {
1129
+ payload: {
1130
+ from: previous
1131
+ }
1132
+ } : {})
1133
+ });
1134
+ }
1135
+
1136
+ /**
1137
+ * Notify of a user interaction. Called by ScaleBunDebugRoot touch handlers.
1138
+ * Also triggers frame capture for desktop-initiated recordings.
1139
+ */
1140
+ onUserAction(subtype, payload, context) {
1141
+ if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
1142
+ this.emitEvent('USER_ACTION', {
1143
+ subtype,
1144
+ screen: context?.screen ?? this._lastKnownScreen ?? undefined,
1145
+ payload,
1146
+ source: 'user',
1147
+ timestamp: context?.timestamp
1148
+ });
1149
+ // NOTE: Do NOT call captureManager.onInteraction() here.
1150
+ // emitEvent() already triggers onInteraction() for USER_ACTION events (line ~405).
1151
+ // Calling it again here caused DUPLICATE frame captures per gesture.
1152
+ }
1153
+
1154
+ /**
1155
+ * Detailed gesture detection — called by ScaleBunDebugRoot touch handlers.
1156
+ * Emits a USER_ACTION event with gesture-specific subtype and payload.
1157
+ */
1158
+ onGestureDetected(gestureType, details) {
1159
+ // Exact-duplicate suppression — see _lastGestureSig. Signature is the gesture type plus
1160
+ // raw coordinates verbatim; String() keeps undefined coords distinct from 0 (a payload
1161
+ // with no coords never collides with a real origin tap).
1162
+ const suppliedInteractionId = details?.interactionId;
1163
+ const dedupSig = suppliedInteractionId ? `id:${suppliedInteractionId}` : `${gestureType}|${String(details?.x)}|${String(details?.y)}|${String(details?.endX)}|${String(details?.endY)}`;
1164
+ const nowTs = Date.now();
1165
+ if (dedupSig === this._lastGestureSig && nowTs - this._lastGestureTs <= SessionManager.GESTURE_DEDUP_WINDOW_MS) {
1166
+ this._lastGestureTs = nowTs; // a burst of 3 stays suppressed even if gaps chain past the window
1167
+ return;
1168
+ }
1169
+ this._lastGestureSig = dedupSig;
1170
+ this._lastGestureTs = nowTs;
1171
+
1172
+ // Build the canonical gesture payload ONCE so the recording lane and the
1173
+ // (additive) analytics lane carry byte-identical keys (normalizedX/Y,
1174
+ // gestureType, etc.). Same object shape that was previously inlined.
1175
+ const interactionId = suppliedInteractionId ?? generateInteractionId();
1176
+ const occurredAt = details?.occurredAt ?? Date.now();
1177
+ const stateStatus = details?.stateStatus ?? (details?.ui ? 'captured_nonempty' : 'not_captured');
1178
+ const payload = {
1179
+ interaction_id: interactionId,
1180
+ interaction_protocol: details?.interactionProtocol ?? INTERACTION_PROTOCOL_VERSION,
1181
+ state_status: stateStatus,
1182
+ ui: details?.ui,
1183
+ target_id: details?.targetId,
1184
+ /**
1185
+ * RN-6 — shipped with the row so the join is auditable instead of assumed.
1186
+ *
1187
+ * Without it, an interaction with no `target_id` is ambiguous in the worst way:
1188
+ * it could mean the control genuinely had no identity, or that the correlation
1189
+ * refused and the identity exists but could not be attributed. Those are
1190
+ * different defects with different owners, and the accounting lane cannot give
1191
+ * an honest unplaceable REASON without knowing which.
1192
+ *
1193
+ * Undefined on the JS-fallback path (no native event, so nothing was joined),
1194
+ * which is itself the correct answer there rather than a fabricated 'exact'.
1195
+ */
1196
+ correlation: details?.correlation,
1197
+ correlation_delta_ms: details?.correlationDeltaMs,
1198
+ correlation_runner_up_delta_ms: details?.correlationRunnerUpDeltaMs,
1199
+ /**
1200
+ * RN-1/RN-2 — stored alongside `target_id` so a reader can tell an authored
1201
+ * identifier from a structural inference. 'path' means the app authored no testID
1202
+ * and the identity was derived from component names, which is useful but will
1203
+ * change under refactoring; a dashboard that presents the two identically invites
1204
+ * someone to trust a key that is about to move.
1205
+ */
1206
+ target_source: details?.targetSource,
1207
+ /**
1208
+ * RN-8 — stored so "13.8% of interactions have a screen" becomes answerable.
1209
+ * 'none' means the app instrumented nothing the SDK could see; 'manual' means a
1210
+ * <ScaleBunScreen> beacon; 'navigation' means the React Navigation hook. Three
1211
+ * different owners behind one number that today has none.
1212
+ */
1213
+ screen_source: details?.screenSource,
1214
+ /**
1215
+ * RN-13 — what makes "the heat is on this control" checkable instead of assumed.
1216
+ * Absent when the control could not be measured synchronously, which is a fact worth
1217
+ * storing: an unmeasurable control and a mis-placed tap are different findings.
1218
+ */
1219
+ target_rect: details?.targetRect,
1220
+ /**
1221
+ * RN-3 — the backend already reads scrollX/scrollY off the payload into the fact
1222
+ * table's own columns (it has done since the web SDK, which sends `sx`/`sy`), so
1223
+ * these need no migration. Mobile simply never sent them.
1224
+ *
1225
+ * `scroll_source` says whether an offset was available at all: 'none' means the app
1226
+ * uses a plain <ScrollView> rather than the SDK's wrapper, which is a coverage gap in
1227
+ * the integration and not a tap at the top of a list.
1228
+ */
1229
+ scrollX: details?.scrollX,
1230
+ scrollY: details?.scrollY,
1231
+ scroll_source: details?.scrollSource,
1232
+ /**
1233
+ * Every scroll container under the finger at touch-down, innermost first, in the
1234
+ * capture view's pixel space (native probe). The single scrollX/Y above is the
1235
+ * innermost; the chain is what lets a nested list be placed without guessing.
1236
+ */
1237
+ scroll_context: details?.scrollContext,
1238
+ pixel_density: details?.pixelDensity,
1239
+ heatmap_schema_version: details?.heatmapSchemaVersion,
1240
+ /**
1241
+ * RN-4 — what stops a recycled native view merging two different rows into one
1242
+ * hotspot. The key is the app's own keyExtractor output, so it is stable across
1243
+ * scrolling and across sessions; the index is carried so a recycled slot (same index,
1244
+ * different key) can be proven rather than inferred.
1245
+ */
1246
+ item_key: details?.itemKey,
1247
+ item_index: details?.itemIndex,
1248
+ /**
1249
+ * RN-15 — where in the control, not just which control. Turns "they tapped Add to
1250
+ * Cart" into "they tapped its left edge", which is what tells you whether a hit area
1251
+ * is right. Outside 0..1 is a hitSlop tap and is kept as such.
1252
+ */
1253
+ local_u: details?.localU,
1254
+ local_v: details?.localV,
1255
+ gestureType,
1256
+ x: details?.x,
1257
+ y: details?.y,
1258
+ endX: details?.endX,
1259
+ endY: details?.endY,
1260
+ duration: details?.duration ?? details?.durationMs,
1261
+ durationMs: details?.durationMs ?? details?.duration,
1262
+ direction: details?.direction,
1263
+ target: details?.target,
1264
+ viewportWidth: details?.viewportWidth,
1265
+ viewportHeight: details?.viewportHeight,
1266
+ pageX: details?.pageX,
1267
+ pageY: details?.pageY,
1268
+ locationX: details?.locationX,
1269
+ locationY: details?.locationY,
1270
+ // Native / JS-precomputed coords — passed through without overwriting
1271
+ normalizedX: details?.normalizedX,
1272
+ normalizedY: details?.normalizedY,
1273
+ normalizedEndX: details?.normalizedEndX,
1274
+ normalizedEndY: details?.normalizedEndY,
1275
+ confidence: details?.confidence,
1276
+ coordinateSpace: details?.coordinateSpace,
1277
+ source: details?.source,
1278
+ normalizedPrecomputed: details?.normalizedPrecomputed,
1279
+ statusBarHeight: details?.statusBarHeight,
1280
+ safeAreaTop: details?.safeAreaTop,
1281
+ rootViewTop: details?.rootViewTop,
1282
+ rootViewLeft: details?.rootViewLeft,
1283
+ rootViewWidth: details?.rootViewWidth,
1284
+ rootViewHeight: details?.rootViewHeight,
1285
+ windowWidth: details?.windowWidth,
1286
+ windowHeight: details?.windowHeight,
1287
+ screenshotCropTop: details?.screenshotCropTop,
1288
+ screenWidth: details?.screenWidth,
1289
+ screenHeight: details?.screenHeight,
1290
+ platform: details?.platform
1291
+ };
1292
+
1293
+ // ── Feature #4 (heatmaps): additive analytics emission ──
1294
+ // When NOT recording, route the tap to the always-on analytics lane so
1295
+ // heatmaps still get coords (opt-in via captureInteractionHeatmap). No-op
1296
+ // when the flag is OFF, no backend transport is attached, or recording is
1297
+ // active (the recording path below already carries this tap). Uses a fresh
1298
+ // payload clone so analytics normalization never mutates the recording one.
1299
+ const analyticsReplayCarrier = this._emitInteractionToAnalytics(gestureType, {
1300
+ ...payload
1301
+ }, occurredAt, details?.screenName);
1302
+ const replayCarrier = !!this._backendTransport && (this.active || analyticsReplayCarrier);
1303
+ if (details?.emitAutomaticAnalytics) {
1304
+ try {
1305
+ const safePayload = redactBody(payload);
1306
+ emitAutomaticEvent('element_interacted', automaticInteractionProperties(safePayload, details?.screenName ?? this._lastKnownScreen ?? undefined, replayCarrier), occurredAt);
1307
+ } catch {/* automatic projection must never affect interaction capture */}
1308
+ }
1309
+ if (!this.active) return; // Defense-in-depth: no emission when recording is OFF
1310
+ // The subtype becomes `ReplayEvent.label`, which is what the Events explorer GROUPS BY. Naming
1311
+ // the tapped control here is what splits taps per control instead of collapsing every tap in the
1312
+ // app into one `gesture:tap` row. Falls back to the bare gesture when nothing identified the
1313
+ // target, so behaviour is unchanged for taps that cannot be resolved.
1314
+ //
1315
+ // ⚠️ `gestureType` also travels in the payload, and the backend's `resolveGesture` reads THAT
1316
+ // first — so enriching the label cannot change heatmap gesture classification.
1317
+ const target = typeof details?.target === 'string' ? details.target.trim() : '';
1318
+ this.onUserAction(target ? `gesture:${gestureType} · ${target}` : `gesture:${gestureType}`, payload, {
1319
+ screen: details?.screenName,
1320
+ timestamp: occurredAt
1321
+ });
1322
+ }
1323
+
1324
+ /**
1325
+ * Manual frame capture — triggered by Desktop "Capture Step" button.
1326
+ */
1327
+ async captureManualFrame() {
1328
+ if (!this.active || !this.captureManager) return null; // No capture when recording is OFF
1329
+ const frame = await this.captureManager.captureManual('manual');
1330
+ return frame ? {
1331
+ frameId: frame.frameId
1332
+ } : null;
1333
+ }
1334
+
1335
+ /**
1336
+ * Notify of app lifecycle change.
1337
+ */
1338
+ onLifecycleChange(state) {
1339
+ this.emitEvent(state === 'foreground' ? 'APP_FOREGROUND' : 'APP_BACKGROUND', {
1340
+ source: 'system'
1341
+ });
1342
+ }
1343
+
1344
+ // ─── Scroll Integration ─────────────────────────────────────────────
1345
+
1346
+ /**
1347
+ * Notify of a scroll event from a scrollable surface (ScaleBunScrollView).
1348
+ * Delegates to ScrollTracker for accumulation and settle detection.
1349
+ */
1350
+ onScrollEvent(contentOffsetX, contentOffsetY) {
1351
+ if (!this.active) return;
1352
+ this.scrollTracker?.onScrollEvent(contentOffsetX, contentOffsetY);
1353
+ }
1354
+
1355
+ // ─── Loading State Integration ──────────────────────────────────────
1356
+
1357
+ /**
1358
+ * Notify that a screen has started loading.
1359
+ * Explicit instrumentation — NOT auto-called on screen entry.
1360
+ * Call from app code: ScaleBun.markLoadingStarted('ScreenName')
1361
+ */
1362
+ onLoadingStarted(screenName) {
1363
+ if (!this.active) return;
1364
+ this.loadingStartTimes.set(screenName, Date.now());
1365
+ this.emitEvent('LOADING_STARTED', {
1366
+ screen: screenName,
1367
+ subtype: screenName,
1368
+ payload: {
1369
+ screen: screenName
1370
+ },
1371
+ source: 'sdk'
1372
+ });
1373
+ }
1374
+
1375
+ /**
1376
+ * Notify that a screen has finished loading.
1377
+ * Explicit instrumentation — call from app code.
1378
+ * Triggers a 'screen_loaded' frame capture for the settled state.
1379
+ */
1380
+ onLoadingCompleted(screenName) {
1381
+ if (!this.active) return;
1382
+ const startTime = this.loadingStartTimes.get(screenName);
1383
+ const durationMs = startTime ? Date.now() - startTime : undefined;
1384
+ this.loadingStartTimes.delete(screenName);
1385
+ this.emitEvent('LOADING_COMPLETED', {
1386
+ screen: screenName,
1387
+ subtype: screenName,
1388
+ payload: {
1389
+ screen: screenName,
1390
+ durationMs
1391
+ },
1392
+ source: 'sdk'
1393
+ });
1394
+
1395
+ // Capture the settled loaded screen
1396
+ this.captureManager.onLoadingEnd(screenName);
1397
+ }
1398
+
1399
+ /**
1400
+ * App network activity, forwarded to replay capture so a frame can wait for the screen's
1401
+ * data instead of photographing the wait. Called by NetworkFeature, which has already
1402
+ * excluded this SDK's own uploads and third-party beacons.
1403
+ *
1404
+ * Deliberately NOT gated on `this.active`: the counter must stay balanced across a session
1405
+ * boundary. Dropping the `end` of a request whose `start` was counted would leave replay
1406
+ * believing the app is permanently loading, and a session can start or stop mid-request.
1407
+ * The capture manager ignores the signal when it is not capturing anyway.
1408
+ */
1409
+ onNetworkActivity(phase) {
1410
+ try {
1411
+ this.captureManager.onNetworkActivity(phase);
1412
+ } catch {
1413
+ // Advisory signal — it must never take down a network request.
1414
+ }
1415
+ }
1416
+
1417
+ // ─── Sync Policy ────────────────────────────────────────────────────
1418
+
1419
+ /**
1420
+ * Override the sync policy. SDK-owned — native only provides metadata.
1421
+ */
1422
+ setSyncPolicy(policy) {
1423
+ this.syncEngine.setPolicy(policy);
1424
+ }
1425
+
1426
+ /**
1427
+ * Provide native-gathered sync metadata for the current session.
1428
+ * Does NOT make the sync decision — that stays in SDK's SyncDecisionEngine.
1429
+ */
1430
+ setNativeSyncMetadata(metadata) {
1431
+ // Stored for use at session end evaluation
1432
+ if (this.session) {
1433
+ this.session._nativeSyncMetadata = metadata;
1434
+ }
1435
+ }
1436
+ }
1437
+
1438
+ // ─── Helpers ────────────────────────────────────────────────────────────────
1439
+
1440
+ function generateSessionId() {
1441
+ return `ses-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`;
1442
+ }
1443
+ //# sourceMappingURL=SessionManager.js.map