@scalebun/react-native 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1694) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +65 -65
  3. package/android/build.gradle +86 -86
  4. package/android/consumer-rules.pro +28 -28
  5. package/android/src/main/AndroidManifest.xml +14 -14
  6. package/android/src/main/java/com/scalebun/core/crash/CrashStorage.kt +155 -41
  7. package/android/src/main/java/com/scalebun/core/crash/NativeCrashHandler.kt +93 -79
  8. package/android/src/main/java/com/scalebun/core/performance/ANRWatchdog.kt +100 -100
  9. package/android/src/main/java/com/scalebun/core/performance/AppStartCollector.kt +132 -132
  10. package/android/src/main/java/com/scalebun/core/performance/FrameMetricsCollector.kt +230 -230
  11. package/android/src/main/java/com/scalebun/core/performance/PerformanceCore.kt +165 -165
  12. package/android/src/main/java/com/scalebun/profiler/ProfilerModule.kt +398 -398
  13. package/android/src/main/java/com/scalebun/profiler/ProfilerPackage.kt +24 -24
  14. package/android/src/main/java/com/scalebun/profiler/collectors/CpuCollector.kt +161 -161
  15. package/android/src/main/java/com/scalebun/profiler/collectors/IncidentDetector.kt +223 -223
  16. package/android/src/main/java/com/scalebun/profiler/collectors/MemoryCollector.kt +157 -157
  17. package/android/src/main/java/com/scalebun/profiler/collectors/RenderCollector.kt +194 -194
  18. package/android/src/main/java/com/scalebun/profiler/collectors/SamplerScheduler.kt +218 -218
  19. package/android/src/main/java/com/scalebun/profiler/collectors/ThreadCollector.kt +142 -142
  20. package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkModule.kt +982 -966
  21. package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkPackage.kt +24 -24
  22. package/android/src/main/java/com/scalebun/replaysdk/capture/CaptureReason.kt +47 -47
  23. package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureManager.kt +508 -508
  24. package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureScheduler.kt +187 -187
  25. package/android/src/main/java/com/scalebun/replaysdk/capture/UiStabilityDetector.kt +214 -214
  26. package/android/src/main/java/com/scalebun/replaysdk/core/ReplayConfig.kt +144 -144
  27. package/android/src/main/java/com/scalebun/replaysdk/core/ReplayLogger.kt +31 -31
  28. package/android/src/main/java/com/scalebun/replaysdk/core/SessionIdGenerator.kt +15 -15
  29. package/android/src/main/java/com/scalebun/replaysdk/models/ReplayModels.kt +88 -88
  30. package/android/src/main/java/com/scalebun/replaysdk/outbox/NativeOutbox.kt +541 -541
  31. package/android/src/main/java/com/scalebun/replaysdk/outbox/OutboxUploader.kt +407 -407
  32. package/android/src/main/java/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.kt +126 -126
  33. package/android/src/main/java/com/scalebun/replaysdk/session/SessionManager.kt +281 -281
  34. package/android/src/main/java/com/scalebun/replaysdk/storage/ReplayStorage.kt +136 -136
  35. package/android/src/main/java/com/scalebun/replaysdk/timeline/TimelineCollector.kt +28 -28
  36. package/android/src/main/java/com/scalebun/replaysdk/tracking/InteractionTracker.kt +419 -419
  37. package/android/src/main/java/com/scalebun/replaysdk/tracking/ScreenTracker.kt +20 -20
  38. package/android/src/main/java/com/scalebun/replaysdk/transport/ReplayTransport.kt +99 -99
  39. package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceRecorder.kt +121 -121
  40. package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceTranscriber.kt +170 -104
  41. package/android/src/main/java/com/scalebun/rn/ScaleBunPackage.kt +113 -113
  42. package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashModule.kt +164 -100
  43. package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashPackage.kt +22 -22
  44. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngageModule.kt +579 -579
  45. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngagePackage.kt +22 -22
  46. package/android/src/main/java/com/scalebun/rn/engage/ScaleBunNotificationPresenter.kt +110 -110
  47. package/android/src/main/java/com/scalebun/rn/ota/BundleDownloader.kt +170 -0
  48. package/android/src/main/java/com/scalebun/rn/ota/ScaleBunOtaModule.kt +284 -136
  49. package/android/src/main/java/com/scalebun/rn/ota/SlotManager.kt +311 -285
  50. package/android/src/main/java/com/scalebun/rn/performance/PerformanceModule.kt +206 -206
  51. package/android/src/main/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.kt +77 -77
  52. package/android/src/main/java/com/scalebun/rn/storage/ScaleBunStorageModule.kt +68 -68
  53. package/android/src/main/java/com/scalebun/storage/KvFileStore.kt +174 -174
  54. package/android/src/newarch/java/com/scalebun/profiler/ProfilerSpec.kt +12 -12
  55. package/android/src/newarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +12 -12
  56. package/android/src/newarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +15 -15
  57. package/android/src/newarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +16 -16
  58. package/android/src/newarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +12 -12
  59. package/android/src/newarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +14 -14
  60. package/android/src/newarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +16 -16
  61. package/android/src/oldarch/java/com/scalebun/profiler/ProfilerSpec.kt +34 -34
  62. package/android/src/oldarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +76 -76
  63. package/android/src/oldarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +21 -21
  64. package/android/src/oldarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +31 -25
  65. package/android/src/oldarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +27 -27
  66. package/android/src/oldarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +18 -18
  67. package/android/src/oldarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +26 -26
  68. package/bin/lib/iosCodemod.js +266 -266
  69. package/bin/scalebun.js +640 -640
  70. package/ios/Capture/InteractionTracker.swift +191 -191
  71. package/ios/Capture/PrivacyMaskProcessor.swift +158 -158
  72. package/ios/Capture/ScreenshotCaptureManager.swift +315 -315
  73. package/ios/Capture/WindowResolver.swift +63 -63
  74. package/ios/Core/ReplayConfig.swift +100 -100
  75. package/ios/Core/ReplayLogger.swift +22 -22
  76. package/ios/Core/SessionIdGenerator.swift +18 -18
  77. package/ios/Crash/ScaleBunCrashBridge.mm +69 -63
  78. package/ios/Crash/ScaleBunCrashHandler.swift +80 -67
  79. package/ios/Crash/ScaleBunCrashModule.swift +83 -69
  80. package/ios/Crash/ScaleBunCrashSignalBridge.h +49 -18
  81. package/ios/Crash/ScaleBunCrashSignalBridge.m +296 -131
  82. package/ios/Crash/ScaleBunCrashSignalStress.c +137 -0
  83. package/ios/Crash/ScaleBunCrashStorage.swift +121 -46
  84. package/ios/Engage/ScaleBunEngageBridge.m +32 -32
  85. package/ios/Engage/ScaleBunEngageModule.swift +250 -250
  86. package/ios/Engage/ScaleBunPushNotificationCenter.swift +185 -185
  87. package/ios/Ota/BundleDownloader.swift +182 -0
  88. package/ios/Ota/OtaSlotManager.swift +290 -264
  89. package/ios/Ota/ScaleBunOtaBridge.mm +77 -68
  90. package/ios/Ota/ScaleBunOtaEventsModule.swift +61 -0
  91. package/ios/Ota/ScaleBunOtaModule.swift +176 -123
  92. package/ios/Outbox/NativeOutbox.swift +598 -598
  93. package/ios/Outbox/OutboxUploader.swift +431 -431
  94. package/ios/Performance/ScaleBunPerformanceBridge.m +32 -32
  95. package/ios/Performance/ScaleBunPerformanceModule.swift +290 -290
  96. package/ios/PrivacyInfo.xcprivacy +97 -97
  97. package/ios/Profiler/ScaleBunProfilerBridge.m +55 -55
  98. package/ios/Profiler/ScaleBunProfilerModule.swift +972 -972
  99. package/ios/ReplaySdk-Bridging-Header.h +2 -2
  100. package/ios/ReplaySdk.swift +608 -608
  101. package/ios/ReplaySdkBridge.m +94 -94
  102. package/ios/Session/SessionManager.swift +203 -203
  103. package/ios/Skan/ScaleBunSkanBridge.m +14 -14
  104. package/ios/Skan/ScaleBunSkanModule.swift +61 -61
  105. package/ios/Storage/ReplayStorage.swift +61 -61
  106. package/ios/Storage/ScaleBunKvFileStore.swift +125 -125
  107. package/ios/Storage/ScaleBunStorageBridge.mm +72 -72
  108. package/ios/Storage/ScaleBunStorageModule.swift +57 -57
  109. package/ios/Transport/ReplayTransport.swift +70 -70
  110. package/ios/VoiceRecorder.swift +145 -145
  111. package/lib/commonjs/analytics/EventTracker.js +64 -36
  112. package/lib/commonjs/analytics/EventTracker.js.map +1 -1
  113. package/lib/commonjs/analytics/automaticEvents.js +7 -7
  114. package/lib/commonjs/analytics/automaticEvents.js.map +1 -1
  115. package/lib/commonjs/analytics/batching.js +24 -24
  116. package/lib/commonjs/analytics/batching.js.map +1 -1
  117. package/lib/commonjs/analytics/eventLane.js +13 -13
  118. package/lib/commonjs/analytics/eventLane.js.map +1 -1
  119. package/lib/commonjs/bootstrap/FeatureRegistry.js +17 -17
  120. package/lib/commonjs/bootstrap/FeatureRegistry.js.map +1 -1
  121. package/lib/commonjs/bootstrap/SDKBootstrapper.js +83 -56
  122. package/lib/commonjs/bootstrap/SDKBootstrapper.js.map +1 -1
  123. package/lib/commonjs/bucketing/fnv1a32.js +10 -10
  124. package/lib/commonjs/bucketing/fnv1a32.js.map +1 -1
  125. package/lib/commonjs/compat/codepush.js +6 -6
  126. package/lib/commonjs/compat/codepush.js.map +1 -1
  127. package/lib/commonjs/config/ConfigManager.js +20 -20
  128. package/lib/commonjs/config/ConfigManager.js.map +1 -1
  129. package/lib/commonjs/config/configTypes.js.map +1 -1
  130. package/lib/commonjs/core/architecture.js +23 -23
  131. package/lib/commonjs/core/architecture.js.map +1 -1
  132. package/lib/commonjs/core/clock/now.js +2 -2
  133. package/lib/commonjs/core/clock/now.js.map +1 -1
  134. package/lib/commonjs/core/config/defaults.js.map +1 -1
  135. package/lib/commonjs/core/config/schema.js +112 -104
  136. package/lib/commonjs/core/config/schema.js.map +1 -1
  137. package/lib/commonjs/core/constants/endpoints.js +7 -7
  138. package/lib/commonjs/core/constants/endpoints.js.map +1 -1
  139. package/lib/commonjs/core/constants/timings.js +5 -5
  140. package/lib/commonjs/core/constants/timings.js.map +1 -1
  141. package/lib/commonjs/core/constants/version.js +4 -4
  142. package/lib/commonjs/core/constants/version.js.map +1 -1
  143. package/lib/commonjs/core/context/app.js.map +1 -1
  144. package/lib/commonjs/core/context/device.js +130 -0
  145. package/lib/commonjs/core/context/device.js.map +1 -1
  146. package/lib/commonjs/core/context/session.js.map +1 -1
  147. package/lib/commonjs/core/context/user.js.map +1 -1
  148. package/lib/commonjs/core/contracts/IFeature.js.map +1 -1
  149. package/lib/commonjs/core/di/container.js.map +1 -1
  150. package/lib/commonjs/core/encoding/base64.js +9 -9
  151. package/lib/commonjs/core/encoding/base64.js.map +1 -1
  152. package/lib/commonjs/core/id/deviceId.js +4 -4
  153. package/lib/commonjs/core/id/deviceId.js.map +1 -1
  154. package/lib/commonjs/core/id/sessionId.js.map +1 -1
  155. package/lib/commonjs/core/lifecycle/appLifecycle.js.map +1 -1
  156. package/lib/commonjs/core/lifecycle/crashSafe.js +3 -3
  157. package/lib/commonjs/core/lifecycle/crashSafe.js.map +1 -1
  158. package/lib/commonjs/core/logger/errorClassification.js +30 -30
  159. package/lib/commonjs/core/logger/errorClassification.js.map +1 -1
  160. package/lib/commonjs/core/logger/internalLogger.js.map +1 -1
  161. package/lib/commonjs/core/logger/levels.js.map +1 -1
  162. package/lib/commonjs/crypto/hmacSha256.js +6 -6
  163. package/lib/commonjs/crypto/hmacSha256.js.map +1 -1
  164. package/lib/commonjs/debug/bootstrap.js +26 -26
  165. package/lib/commonjs/debug/bootstrap.js.map +1 -1
  166. package/lib/commonjs/debug/commands.js +10 -10
  167. package/lib/commonjs/debug/commands.js.map +1 -1
  168. package/lib/commonjs/debug/configBuilder.js +6 -6
  169. package/lib/commonjs/debug/configBuilder.js.map +1 -1
  170. package/lib/commonjs/debug/exportBridge.js +17 -17
  171. package/lib/commonjs/debug/exportBridge.js.map +1 -1
  172. package/lib/commonjs/debug/hostResolver.js +10 -10
  173. package/lib/commonjs/debug/hostResolver.js.map +1 -1
  174. package/lib/commonjs/debug/index.js.map +1 -1
  175. package/lib/commonjs/debug/metrics.js.map +1 -1
  176. package/lib/commonjs/debug/perf.js +11 -11
  177. package/lib/commonjs/debug/perf.js.map +1 -1
  178. package/lib/commonjs/debug/perfWiring.js +10 -10
  179. package/lib/commonjs/debug/perfWiring.js.map +1 -1
  180. package/lib/commonjs/debug/protocol.js.map +1 -1
  181. package/lib/commonjs/debug/redaction.js +26 -26
  182. package/lib/commonjs/debug/redaction.js.map +1 -1
  183. package/lib/commonjs/debug/replayWiring.js +13 -12
  184. package/lib/commonjs/debug/replayWiring.js.map +1 -1
  185. package/lib/commonjs/debug/screenTracking.js +7 -7
  186. package/lib/commonjs/debug/screenTracking.js.map +1 -1
  187. package/lib/commonjs/debug/sessionWiring.js +8 -8
  188. package/lib/commonjs/debug/sessionWiring.js.map +1 -1
  189. package/lib/commonjs/debug/stream.js +26 -26
  190. package/lib/commonjs/debug/stream.js.map +1 -1
  191. package/lib/commonjs/debug/transport.js +24 -24
  192. package/lib/commonjs/debug/transport.js.map +1 -1
  193. package/lib/commonjs/features/bugreport/BugReportFeature.js +112 -0
  194. package/lib/commonjs/features/bugreport/BugReportFeature.js.map +1 -0
  195. package/lib/commonjs/features/bugreport/buildPayload.js +97 -0
  196. package/lib/commonjs/features/bugreport/buildPayload.js.map +1 -0
  197. package/lib/commonjs/features/bugreport/index.js.map +1 -1
  198. package/lib/commonjs/features/crash/CrashFeature.js +27 -9
  199. package/lib/commonjs/features/crash/CrashFeature.js.map +1 -1
  200. package/lib/commonjs/features/crash/CrashReporter.js +53 -29
  201. package/lib/commonjs/features/crash/CrashReporter.js.map +1 -1
  202. package/lib/commonjs/features/crash/NativeCrashFeature.js +7 -7
  203. package/lib/commonjs/features/crash/NativeCrashFeature.js.map +1 -1
  204. package/lib/commonjs/features/crash/capture.js +27 -9
  205. package/lib/commonjs/features/crash/capture.js.map +1 -1
  206. package/lib/commonjs/features/crash/globalHandler.js +11 -11
  207. package/lib/commonjs/features/crash/globalHandler.js.map +1 -1
  208. package/lib/commonjs/features/crash/index.js.map +1 -1
  209. package/lib/commonjs/features/crash/nativeCrashBridge.js +179 -44
  210. package/lib/commonjs/features/crash/nativeCrashBridge.js.map +1 -1
  211. package/lib/commonjs/features/crash/rejectionHandler.js +123 -0
  212. package/lib/commonjs/features/crash/rejectionHandler.js.map +1 -0
  213. package/lib/commonjs/features/engage/EngageAnchor.js +3 -3
  214. package/lib/commonjs/features/engage/EngageAnchor.js.map +1 -1
  215. package/lib/commonjs/features/engage/EngageArchetypeRenderers.js +19 -19
  216. package/lib/commonjs/features/engage/EngageArchetypeRenderers.js.map +1 -1
  217. package/lib/commonjs/features/engage/EngageInAppView.js +35 -35
  218. package/lib/commonjs/features/engage/EngageInAppView.js.map +1 -1
  219. package/lib/commonjs/features/engage/EngageInlinePlacement.js +7 -7
  220. package/lib/commonjs/features/engage/EngageInlinePlacement.js.map +1 -1
  221. package/lib/commonjs/features/engage/EngagePromptProvider.js +124 -88
  222. package/lib/commonjs/features/engage/EngagePromptProvider.js.map +1 -1
  223. package/lib/commonjs/features/engage/EngagePromptView.js +65 -32
  224. package/lib/commonjs/features/engage/EngagePromptView.js.map +1 -1
  225. package/lib/commonjs/features/engage/EngageTransport.js +79 -79
  226. package/lib/commonjs/features/engage/EngageTransport.js.map +1 -1
  227. package/lib/commonjs/features/engage/EngageVariantContent.js +10 -10
  228. package/lib/commonjs/features/engage/EngageVariantContent.js.map +1 -1
  229. package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js +7 -7
  230. package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js.map +1 -1
  231. package/lib/commonjs/features/engage/attachmentCapture.js +12 -12
  232. package/lib/commonjs/features/engage/attachmentCapture.js.map +1 -1
  233. package/lib/commonjs/features/engage/captureVoiceAttachment.js +20 -20
  234. package/lib/commonjs/features/engage/captureVoiceAttachment.js.map +1 -1
  235. package/lib/commonjs/features/engage/engageCoachmarkTour.js +4 -4
  236. package/lib/commonjs/features/engage/engageCoachmarkTour.js.map +1 -1
  237. package/lib/commonjs/features/engage/engageGameLogic.js.map +1 -1
  238. package/lib/commonjs/features/engage/engageMediaSizing.js +15 -15
  239. package/lib/commonjs/features/engage/engageMediaSizing.js.map +1 -1
  240. package/lib/commonjs/features/engage/engageMultiStepSheet.js +6 -6
  241. package/lib/commonjs/features/engage/engageMultiStepSheet.js.map +1 -1
  242. package/lib/commonjs/features/engage/engageOutcome.js +6 -6
  243. package/lib/commonjs/features/engage/engageOutcome.js.map +1 -1
  244. package/lib/commonjs/features/engage/engagePushTokenBridge.js +20 -20
  245. package/lib/commonjs/features/engage/engagePushTokenBridge.js.map +1 -1
  246. package/lib/commonjs/features/engage/engageShakeBridge.js +16 -16
  247. package/lib/commonjs/features/engage/engageShakeBridge.js.map +1 -1
  248. package/lib/commonjs/features/engage/engageSignals.js.map +1 -1
  249. package/lib/commonjs/features/engage/engageStoreReviewBridge.js +19 -19
  250. package/lib/commonjs/features/engage/engageStoreReviewBridge.js.map +1 -1
  251. package/lib/commonjs/features/engage/engageTestSeenStore.js +29 -29
  252. package/lib/commonjs/features/engage/engageTestSeenStore.js.map +1 -1
  253. package/lib/commonjs/features/engage/engageThrottle.js +117 -86
  254. package/lib/commonjs/features/engage/engageThrottle.js.map +1 -1
  255. package/lib/commonjs/features/engage/engageTriggerEngine.js +17 -7
  256. package/lib/commonjs/features/engage/engageTriggerEngine.js.map +1 -1
  257. package/lib/commonjs/features/engage/engageTypes.js +33 -33
  258. package/lib/commonjs/features/engage/engageTypes.js.map +1 -1
  259. package/lib/commonjs/features/engage/engageVariantResolver.js +13 -13
  260. package/lib/commonjs/features/engage/engageVariantResolver.js.map +1 -1
  261. package/lib/commonjs/features/engage/engageWindowInsets.js +10 -10
  262. package/lib/commonjs/features/engage/engageWindowInsets.js.map +1 -1
  263. package/lib/commonjs/features/engage/gestureTriggerDetector.js.map +1 -1
  264. package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js +16 -16
  265. package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js.map +1 -1
  266. package/lib/commonjs/features/install-referrer/installReferrer.js +26 -26
  267. package/lib/commonjs/features/install-referrer/installReferrer.js.map +1 -1
  268. package/lib/commonjs/features/journey/ScaleBunDebugRoot.js +30 -29
  269. package/lib/commonjs/features/journey/ScaleBunDebugRoot.js.map +1 -1
  270. package/lib/commonjs/features/journey/ScaleBunFlatList.js +15 -15
  271. package/lib/commonjs/features/journey/ScaleBunFlatList.js.map +1 -1
  272. package/lib/commonjs/features/journey/ScaleBunImpression.js +22 -22
  273. package/lib/commonjs/features/journey/ScaleBunImpression.js.map +1 -1
  274. package/lib/commonjs/features/journey/ScaleBunScrollView.js +20 -20
  275. package/lib/commonjs/features/journey/ScaleBunScrollView.js.map +1 -1
  276. package/lib/commonjs/features/journey/ScaleBunSectionList.js +15 -15
  277. package/lib/commonjs/features/journey/ScaleBunSectionList.js.map +1 -1
  278. package/lib/commonjs/features/journey/calibrationContext.js +12 -12
  279. package/lib/commonjs/features/journey/calibrationContext.js.map +1 -1
  280. package/lib/commonjs/features/journey/gestureBuffer.js +9 -9
  281. package/lib/commonjs/features/journey/gestureBuffer.js.map +1 -1
  282. package/lib/commonjs/features/journey/gestureDetector.js +10 -10
  283. package/lib/commonjs/features/journey/gestureDetector.js.map +1 -1
  284. package/lib/commonjs/features/journey/impression.js +18 -18
  285. package/lib/commonjs/features/journey/impression.js.map +1 -1
  286. package/lib/commonjs/features/journey/journeyManager.js +6 -6
  287. package/lib/commonjs/features/journey/journeyManager.js.map +1 -1
  288. package/lib/commonjs/features/journey/journeyTypes.js +5 -5
  289. package/lib/commonjs/features/journey/journeyTypes.js.map +1 -1
  290. package/lib/commonjs/features/journey/navDetector.js +7 -7
  291. package/lib/commonjs/features/journey/navDetector.js.map +1 -1
  292. package/lib/commonjs/features/journey/screenshotHelper.js +7 -7
  293. package/lib/commonjs/features/journey/screenshotHelper.js.map +1 -1
  294. package/lib/commonjs/features/journey/targetRegistry.js +17 -17
  295. package/lib/commonjs/features/journey/targetRegistry.js.map +1 -1
  296. package/lib/commonjs/features/journey/touchTarget.js +29 -29
  297. package/lib/commonjs/features/journey/touchTarget.js.map +1 -1
  298. package/lib/commonjs/features/navigation/AutoScreenDetector.js +114 -71
  299. package/lib/commonjs/features/navigation/AutoScreenDetector.js.map +1 -1
  300. package/lib/commonjs/features/network/NetworkFeature.js +23 -23
  301. package/lib/commonjs/features/network/NetworkFeature.js.map +1 -1
  302. package/lib/commonjs/features/network/index.js +5 -5
  303. package/lib/commonjs/features/network/index.js.map +1 -1
  304. package/lib/commonjs/features/ota/OtaEventEmitter.js +21 -21
  305. package/lib/commonjs/features/ota/OtaEventEmitter.js.map +1 -1
  306. package/lib/commonjs/features/ota/OtaOrchestrator.js +595 -42
  307. package/lib/commonjs/features/ota/OtaOrchestrator.js.map +1 -1
  308. package/lib/commonjs/features/ota/OtaTypes.js.map +1 -1
  309. package/lib/commonjs/features/ota/deviceAttributes.js +48 -0
  310. package/lib/commonjs/features/ota/deviceAttributes.js.map +1 -0
  311. package/lib/commonjs/features/ota/environment.js +172 -0
  312. package/lib/commonjs/features/ota/environment.js.map +1 -0
  313. package/lib/commonjs/features/ota/geoCountry.js +93 -0
  314. package/lib/commonjs/features/ota/geoCountry.js.map +1 -0
  315. package/lib/commonjs/features/ota/retry.js +96 -0
  316. package/lib/commonjs/features/ota/retry.js.map +1 -0
  317. package/lib/commonjs/features/ota/signature.js +115 -0
  318. package/lib/commonjs/features/ota/signature.js.map +1 -0
  319. package/lib/commonjs/features/ota/useOtaUpdate.js +18 -15
  320. package/lib/commonjs/features/ota/useOtaUpdate.js.map +1 -1
  321. package/lib/commonjs/features/performance/PerformanceFeature.js +49 -35
  322. package/lib/commonjs/features/performance/PerformanceFeature.js.map +1 -1
  323. package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js +13 -13
  324. package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js.map +1 -1
  325. package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js +32 -32
  326. package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js.map +1 -1
  327. package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js +13 -13
  328. package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js.map +1 -1
  329. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js +80 -20
  330. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
  331. package/lib/commonjs/features/performance/collectors/JsStallCollector.js +12 -12
  332. package/lib/commonjs/features/performance/collectors/JsStallCollector.js.map +1 -1
  333. package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js +10 -10
  334. package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js.map +1 -1
  335. package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js +11 -11
  336. package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js.map +1 -1
  337. package/lib/commonjs/features/performance/collectors/UiHangCollector.js +5 -5
  338. package/lib/commonjs/features/performance/collectors/UiHangCollector.js.map +1 -1
  339. package/lib/commonjs/features/performance/config.js +11 -11
  340. package/lib/commonjs/features/performance/config.js.map +1 -1
  341. package/lib/commonjs/features/performance/getNativePerformanceModule.js +11 -11
  342. package/lib/commonjs/features/performance/getNativePerformanceModule.js.map +1 -1
  343. package/lib/commonjs/features/performance/index.js.map +1 -1
  344. package/lib/commonjs/features/performance/metrics/MetricsEngine.js +13 -13
  345. package/lib/commonjs/features/performance/metrics/MetricsEngine.js.map +1 -1
  346. package/lib/commonjs/features/performance/models.js +8 -8
  347. package/lib/commonjs/features/performance/models.js.map +1 -1
  348. package/lib/commonjs/features/performance/transport/PerformanceTransport.js +31 -6
  349. package/lib/commonjs/features/performance/transport/PerformanceTransport.js.map +1 -1
  350. package/lib/commonjs/features/profiler/ProfilerFeature.js +53 -53
  351. package/lib/commonjs/features/profiler/ProfilerFeature.js.map +1 -1
  352. package/lib/commonjs/features/profiler/config.js +15 -15
  353. package/lib/commonjs/features/profiler/config.js.map +1 -1
  354. package/lib/commonjs/features/profiler/contracts.js +22 -22
  355. package/lib/commonjs/features/profiler/contracts.js.map +1 -1
  356. package/lib/commonjs/features/profiler/index.js.map +1 -1
  357. package/lib/commonjs/features/profiler/models.js +44 -44
  358. package/lib/commonjs/features/profiler/models.js.map +1 -1
  359. package/lib/commonjs/features/profiler/transport/ProfilerTransport.js +9 -9
  360. package/lib/commonjs/features/profiler/transport/ProfilerTransport.js.map +1 -1
  361. package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js +17 -17
  362. package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js.map +1 -1
  363. package/lib/commonjs/features/replay/bridge/eventEmitter.js +8 -8
  364. package/lib/commonjs/features/replay/bridge/eventEmitter.js.map +1 -1
  365. package/lib/commonjs/features/replay/bridge/nativeModule.js +20 -20
  366. package/lib/commonjs/features/replay/bridge/nativeModule.js.map +1 -1
  367. package/lib/commonjs/features/replay/core/clock/clock.js +6 -6
  368. package/lib/commonjs/features/replay/core/clock/clock.js.map +1 -1
  369. package/lib/commonjs/features/replay/core/config/defaults.js +2 -2
  370. package/lib/commonjs/features/replay/core/config/defaults.js.map +1 -1
  371. package/lib/commonjs/features/replay/core/config/validator.js +5 -5
  372. package/lib/commonjs/features/replay/core/config/validator.js.map +1 -1
  373. package/lib/commonjs/features/replay/core/env/environmentDetector.js +10 -10
  374. package/lib/commonjs/features/replay/core/env/environmentDetector.js.map +1 -1
  375. package/lib/commonjs/features/replay/core/errors/safeCall.js +4 -4
  376. package/lib/commonjs/features/replay/core/errors/safeCall.js.map +1 -1
  377. package/lib/commonjs/features/replay/core/ids/sessionId.js +5 -5
  378. package/lib/commonjs/features/replay/core/ids/sessionId.js.map +1 -1
  379. package/lib/commonjs/features/replay/core/logger/logger.js +5 -5
  380. package/lib/commonjs/features/replay/core/logger/logger.js.map +1 -1
  381. package/lib/commonjs/features/replay/core/privacy/privacyTypes.js +4 -4
  382. package/lib/commonjs/features/replay/core/privacy/privacyTypes.js.map +1 -1
  383. package/lib/commonjs/features/replay/core/queue/boundedQueue.js +5 -5
  384. package/lib/commonjs/features/replay/core/queue/boundedQueue.js.map +1 -1
  385. package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js +59 -59
  386. package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js.map +1 -1
  387. package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js +19 -19
  388. package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js.map +1 -1
  389. package/lib/commonjs/features/replay/integrations/network/networkAdapter.js +30 -30
  390. package/lib/commonjs/features/replay/integrations/network/networkAdapter.js.map +1 -1
  391. package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js +19 -19
  392. package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
  393. package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js +16 -16
  394. package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
  395. package/lib/commonjs/features/replay/pipeline/batching/batchManager.js +5 -5
  396. package/lib/commonjs/features/replay/pipeline/batching/batchManager.js.map +1 -1
  397. package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js +5 -5
  398. package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js.map +1 -1
  399. package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js +4 -4
  400. package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
  401. package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js +7 -7
  402. package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js.map +1 -1
  403. package/lib/commonjs/features/replay/public/api.js +21 -21
  404. package/lib/commonjs/features/replay/public/api.js.map +1 -1
  405. package/lib/commonjs/features/replay/public/enums.js +5 -5
  406. package/lib/commonjs/features/replay/public/enums.js.map +1 -1
  407. package/lib/commonjs/features/replay/public/types.js.map +1 -1
  408. package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js +5 -5
  409. package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js.map +1 -1
  410. package/lib/commonjs/features/replay/replay/frames/frameModels.js +4 -4
  411. package/lib/commonjs/features/replay/replay/frames/frameModels.js.map +1 -1
  412. package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js +10 -10
  413. package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
  414. package/lib/commonjs/features/replay/replay/timeline/timelineModels.js +4 -4
  415. package/lib/commonjs/features/replay/replay/timeline/timelineModels.js.map +1 -1
  416. package/lib/commonjs/features/replay/transport/BackendReplayTransport.js +13 -13
  417. package/lib/commonjs/features/replay/transport/BackendReplayTransport.js.map +1 -1
  418. package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js +8 -8
  419. package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js.map +1 -1
  420. package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js +14 -14
  421. package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js.map +1 -1
  422. package/lib/commonjs/features/replay/transport/ReplayTransport.js.map +1 -1
  423. package/lib/commonjs/features/session/BackendSessionAdapter.js +486 -164
  424. package/lib/commonjs/features/session/BackendSessionAdapter.js.map +1 -1
  425. package/lib/commonjs/features/session/DesktopSessionTransport.js +14 -14
  426. package/lib/commonjs/features/session/DesktopSessionTransport.js.map +1 -1
  427. package/lib/commonjs/features/session/JourneyEventPipeline.js +20 -19
  428. package/lib/commonjs/features/session/JourneyEventPipeline.js.map +1 -1
  429. package/lib/commonjs/features/session/ReplayCaptureManager.js +169 -123
  430. package/lib/commonjs/features/session/ReplayCaptureManager.js.map +1 -1
  431. package/lib/commonjs/features/session/ScrollTracker.js +17 -17
  432. package/lib/commonjs/features/session/ScrollTracker.js.map +1 -1
  433. package/lib/commonjs/features/session/SessionManager.js +185 -155
  434. package/lib/commonjs/features/session/SessionManager.js.map +1 -1
  435. package/lib/commonjs/features/session/SyncDecisionEngine.js +23 -23
  436. package/lib/commonjs/features/session/SyncDecisionEngine.js.map +1 -1
  437. package/lib/commonjs/features/session/index.js.map +1 -1
  438. package/lib/commonjs/features/session/nativeCapture.js +9 -9
  439. package/lib/commonjs/features/session/nativeCapture.js.map +1 -1
  440. package/lib/commonjs/features/session/outboxFrameCapture.js +18 -17
  441. package/lib/commonjs/features/session/outboxFrameCapture.js.map +1 -1
  442. package/lib/commonjs/features/session/sessionTypes.js +44 -44
  443. package/lib/commonjs/features/session/sessionTypes.js.map +1 -1
  444. package/lib/commonjs/features/skan/skanBridge.js +11 -11
  445. package/lib/commonjs/features/skan/skanBridge.js.map +1 -1
  446. package/lib/commonjs/features/skan/skanConversionManager.js +23 -23
  447. package/lib/commonjs/features/skan/skanConversionManager.js.map +1 -1
  448. package/lib/commonjs/index.js +20 -0
  449. package/lib/commonjs/index.js.map +1 -1
  450. package/lib/commonjs/integrations/fetch/fetchInterceptor.js +21 -21
  451. package/lib/commonjs/integrations/fetch/fetchInterceptor.js.map +1 -1
  452. package/lib/commonjs/integrations/navigation/screenTracker.js.map +1 -1
  453. package/lib/commonjs/integrations/network/bodyCapture.js +69 -69
  454. package/lib/commonjs/integrations/network/bodyCapture.js.map +1 -1
  455. package/lib/commonjs/integrations/xhr/xhrInterceptor.js +24 -24
  456. package/lib/commonjs/integrations/xhr/xhrInterceptor.js.map +1 -1
  457. package/lib/commonjs/metro/index.js +37 -37
  458. package/lib/commonjs/metro/index.js.map +1 -1
  459. package/lib/commonjs/metro/optionalDependencyStub.js.map +1 -1
  460. package/lib/commonjs/metro/optionalModules.js +16 -16
  461. package/lib/commonjs/metro/optionalModules.js.map +1 -1
  462. package/lib/commonjs/pipeline/dispatcher/dispatcher.js.map +1 -1
  463. package/lib/commonjs/pipeline/envelope/envelope.js.map +1 -1
  464. package/lib/commonjs/pipeline/envelope/serializer.js.map +1 -1
  465. package/lib/commonjs/pipeline/processors/dedupe.js.map +1 -1
  466. package/lib/commonjs/pipeline/processors/enrich.js.map +1 -1
  467. package/lib/commonjs/pipeline/processors/sampling.js.map +1 -1
  468. package/lib/commonjs/pipeline/processors/sanitize.js.map +1 -1
  469. package/lib/commonjs/pipeline/queue/flushQueue.js +4 -4
  470. package/lib/commonjs/pipeline/queue/flushQueue.js.map +1 -1
  471. package/lib/commonjs/pipeline/queue/memoryQueue.js.map +1 -1
  472. package/lib/commonjs/pipeline/queue/persistentQueue.js +80 -80
  473. package/lib/commonjs/pipeline/queue/persistentQueue.js.map +1 -1
  474. package/lib/commonjs/pipeline/queue/queuePolicy.js.map +1 -1
  475. package/lib/commonjs/pipeline/scheduler/flushScheduler.js.map +1 -1
  476. package/lib/commonjs/pipeline/scheduler/retryPolicy.js +2 -2
  477. package/lib/commonjs/pipeline/scheduler/retryPolicy.js.map +1 -1
  478. package/lib/commonjs/public/ScaleBunErrorBoundary.js +79 -0
  479. package/lib/commonjs/public/ScaleBunErrorBoundary.js.map +1 -0
  480. package/lib/commonjs/public/ScaleBunFacade.js +424 -276
  481. package/lib/commonjs/public/ScaleBunFacade.js.map +1 -1
  482. package/lib/commonjs/public/ScaleBunProvider.js +3 -3
  483. package/lib/commonjs/public/ScaleBunProvider.js.map +1 -1
  484. package/lib/commonjs/public/typedTracker.js +36 -36
  485. package/lib/commonjs/public/typedTracker.js.map +1 -1
  486. package/lib/commonjs/public/types.js.map +1 -1
  487. package/lib/commonjs/push/PushManager.js +21 -21
  488. package/lib/commonjs/push/PushManager.js.map +1 -1
  489. package/lib/commonjs/push/adapters/ManualAdapter.js +14 -14
  490. package/lib/commonjs/push/adapters/ManualAdapter.js.map +1 -1
  491. package/lib/commonjs/push/adapters/NativeBridgeAdapter.js +17 -17
  492. package/lib/commonjs/push/adapters/NativeBridgeAdapter.js.map +1 -1
  493. package/lib/commonjs/push/adapters/NoopAdapter.js +5 -5
  494. package/lib/commonjs/push/adapters/NoopAdapter.js.map +1 -1
  495. package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js +17 -17
  496. package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js.map +1 -1
  497. package/lib/commonjs/push/adapters/loadMessaging.js +12 -12
  498. package/lib/commonjs/push/adapters/loadMessaging.js.map +1 -1
  499. package/lib/commonjs/push/adapters/loadNotifee.js +12 -12
  500. package/lib/commonjs/push/adapters/loadNotifee.js.map +1 -1
  501. package/lib/commonjs/push/adapters/selectAdapter.js +14 -14
  502. package/lib/commonjs/push/adapters/selectAdapter.js.map +1 -1
  503. package/lib/commonjs/push/detect/capabilities.js +19 -19
  504. package/lib/commonjs/push/detect/capabilities.js.map +1 -1
  505. package/lib/commonjs/push/index.js.map +1 -1
  506. package/lib/commonjs/push/native/nativeNotifications.js +32 -32
  507. package/lib/commonjs/push/native/nativeNotifications.js.map +1 -1
  508. package/lib/commonjs/push/types.js.map +1 -1
  509. package/lib/commonjs/specs/NativeReplaySdk.js +18 -18
  510. package/lib/commonjs/specs/NativeReplaySdk.js.map +1 -1
  511. package/lib/commonjs/specs/NativeScaleBunCrash.js +19 -19
  512. package/lib/commonjs/specs/NativeScaleBunCrash.js.map +1 -1
  513. package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js +14 -14
  514. package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js.map +1 -1
  515. package/lib/commonjs/specs/NativeScaleBunOta.js +21 -21
  516. package/lib/commonjs/specs/NativeScaleBunOta.js.map +1 -1
  517. package/lib/commonjs/specs/NativeScaleBunPerformance.js +15 -15
  518. package/lib/commonjs/specs/NativeScaleBunPerformance.js.map +1 -1
  519. package/lib/commonjs/specs/NativeScaleBunProfiler.js +16 -16
  520. package/lib/commonjs/specs/NativeScaleBunProfiler.js.map +1 -1
  521. package/lib/commonjs/specs/NativeScaleBunStorage.js +29 -29
  522. package/lib/commonjs/specs/NativeScaleBunStorage.js.map +1 -1
  523. package/lib/commonjs/storage/StorageBackend.js +83 -83
  524. package/lib/commonjs/storage/StorageBackend.js.map +1 -1
  525. package/lib/commonjs/storage/db/sqlite.js.map +1 -1
  526. package/lib/commonjs/storage/files/fileStore.js.map +1 -1
  527. package/lib/commonjs/transport/auth/sdkSession.js.map +1 -1
  528. package/lib/commonjs/transport/backoff/exponentialJitter.js +2 -2
  529. package/lib/commonjs/transport/backoff/exponentialJitter.js.map +1 -1
  530. package/lib/commonjs/transport/http/endpoints.js.map +1 -1
  531. package/lib/commonjs/transport/http/httpClient.js +3 -3
  532. package/lib/commonjs/transport/http/httpClient.js.map +1 -1
  533. package/lib/commonjs/transport/rateLimit/retryAfter.js.map +1 -1
  534. package/lib/commonjs/transport/signing/requestSigner.js.map +1 -1
  535. package/lib/commonjs/vendor/protocol/index.js +74 -74
  536. package/lib/commonjs/vendor/protocol/index.js.map +1 -1
  537. package/lib/commonjs/vendor/protocol/internal/validation.js +23 -23
  538. package/lib/commonjs/vendor/protocol/internal/validation.js.map +1 -1
  539. package/lib/commonjs/vendor/sdk-contracts/bridge.js.map +1 -1
  540. package/lib/commonjs/vendor/sdk-contracts/config.js.map +1 -1
  541. package/lib/commonjs/vendor/sdk-contracts/events.js.map +1 -1
  542. package/lib/commonjs/vendor/sdk-contracts/features.js.map +1 -1
  543. package/lib/commonjs/vendor/sdk-contracts/index.js.map +1 -1
  544. package/lib/commonjs/vendor/sdk-contracts/platform.js.map +1 -1
  545. package/lib/commonjs/vendor/sdk-contracts/session-boundary.js.map +1 -1
  546. package/lib/commonjs/vendor/sdk-contracts/session.js.map +1 -1
  547. package/lib/commonjs/vendor/vendor.manifest +10 -10
  548. package/lib/module/analytics/EventTracker.js +63 -35
  549. package/lib/module/analytics/EventTracker.js.map +1 -1
  550. package/lib/module/analytics/automaticEvents.js +7 -7
  551. package/lib/module/analytics/automaticEvents.js.map +1 -1
  552. package/lib/module/analytics/batching.js +24 -24
  553. package/lib/module/analytics/batching.js.map +1 -1
  554. package/lib/module/analytics/eventLane.js +13 -13
  555. package/lib/module/analytics/eventLane.js.map +1 -1
  556. package/lib/module/bootstrap/FeatureRegistry.js +17 -17
  557. package/lib/module/bootstrap/FeatureRegistry.js.map +1 -1
  558. package/lib/module/bootstrap/SDKBootstrapper.js +81 -54
  559. package/lib/module/bootstrap/SDKBootstrapper.js.map +1 -1
  560. package/lib/module/bucketing/fnv1a32.js +10 -10
  561. package/lib/module/bucketing/fnv1a32.js.map +1 -1
  562. package/lib/module/compat/codepush.js +6 -6
  563. package/lib/module/compat/codepush.js.map +1 -1
  564. package/lib/module/config/ConfigManager.js +20 -20
  565. package/lib/module/config/ConfigManager.js.map +1 -1
  566. package/lib/module/config/configTypes.js.map +1 -1
  567. package/lib/module/core/architecture.js +23 -23
  568. package/lib/module/core/architecture.js.map +1 -1
  569. package/lib/module/core/clock/now.js +2 -2
  570. package/lib/module/core/clock/now.js.map +1 -1
  571. package/lib/module/core/config/defaults.js.map +1 -1
  572. package/lib/module/core/config/schema.js +112 -104
  573. package/lib/module/core/config/schema.js.map +1 -1
  574. package/lib/module/core/constants/endpoints.js +7 -7
  575. package/lib/module/core/constants/endpoints.js.map +1 -1
  576. package/lib/module/core/constants/timings.js +5 -5
  577. package/lib/module/core/constants/timings.js.map +1 -1
  578. package/lib/module/core/constants/version.js +4 -4
  579. package/lib/module/core/constants/version.js.map +1 -1
  580. package/lib/module/core/context/app.js.map +1 -1
  581. package/lib/module/core/context/device.js +119 -0
  582. package/lib/module/core/context/device.js.map +1 -1
  583. package/lib/module/core/context/session.js.map +1 -1
  584. package/lib/module/core/context/user.js.map +1 -1
  585. package/lib/module/core/contracts/IFeature.js.map +1 -1
  586. package/lib/module/core/di/container.js.map +1 -1
  587. package/lib/module/core/encoding/base64.js +9 -9
  588. package/lib/module/core/encoding/base64.js.map +1 -1
  589. package/lib/module/core/id/deviceId.js +4 -4
  590. package/lib/module/core/id/deviceId.js.map +1 -1
  591. package/lib/module/core/id/sessionId.js.map +1 -1
  592. package/lib/module/core/lifecycle/appLifecycle.js.map +1 -1
  593. package/lib/module/core/lifecycle/crashSafe.js +3 -3
  594. package/lib/module/core/lifecycle/crashSafe.js.map +1 -1
  595. package/lib/module/core/logger/errorClassification.js +30 -30
  596. package/lib/module/core/logger/errorClassification.js.map +1 -1
  597. package/lib/module/core/logger/internalLogger.js.map +1 -1
  598. package/lib/module/core/logger/levels.js.map +1 -1
  599. package/lib/module/crypto/hmacSha256.js +6 -6
  600. package/lib/module/crypto/hmacSha256.js.map +1 -1
  601. package/lib/module/debug/bootstrap.js +26 -26
  602. package/lib/module/debug/bootstrap.js.map +1 -1
  603. package/lib/module/debug/commands.js +10 -10
  604. package/lib/module/debug/commands.js.map +1 -1
  605. package/lib/module/debug/configBuilder.js +6 -6
  606. package/lib/module/debug/configBuilder.js.map +1 -1
  607. package/lib/module/debug/exportBridge.js +17 -17
  608. package/lib/module/debug/exportBridge.js.map +1 -1
  609. package/lib/module/debug/hostResolver.js +10 -10
  610. package/lib/module/debug/hostResolver.js.map +1 -1
  611. package/lib/module/debug/index.js +5 -5
  612. package/lib/module/debug/index.js.map +1 -1
  613. package/lib/module/debug/metrics.js.map +1 -1
  614. package/lib/module/debug/perf.js +11 -11
  615. package/lib/module/debug/perf.js.map +1 -1
  616. package/lib/module/debug/perfWiring.js +10 -10
  617. package/lib/module/debug/perfWiring.js.map +1 -1
  618. package/lib/module/debug/protocol.js +11 -11
  619. package/lib/module/debug/protocol.js.map +1 -1
  620. package/lib/module/debug/redaction.js +26 -26
  621. package/lib/module/debug/redaction.js.map +1 -1
  622. package/lib/module/debug/replayWiring.js +13 -12
  623. package/lib/module/debug/replayWiring.js.map +1 -1
  624. package/lib/module/debug/screenTracking.js +7 -7
  625. package/lib/module/debug/screenTracking.js.map +1 -1
  626. package/lib/module/debug/sessionWiring.js +8 -8
  627. package/lib/module/debug/sessionWiring.js.map +1 -1
  628. package/lib/module/debug/stream.js +26 -26
  629. package/lib/module/debug/stream.js.map +1 -1
  630. package/lib/module/debug/transport.js +24 -24
  631. package/lib/module/debug/transport.js.map +1 -1
  632. package/lib/module/features/bugreport/BugReportFeature.js +105 -0
  633. package/lib/module/features/bugreport/BugReportFeature.js.map +1 -0
  634. package/lib/module/features/bugreport/buildPayload.js +91 -0
  635. package/lib/module/features/bugreport/buildPayload.js.map +1 -0
  636. package/lib/module/features/bugreport/index.js.map +1 -1
  637. package/lib/module/features/crash/CrashFeature.js +27 -9
  638. package/lib/module/features/crash/CrashFeature.js.map +1 -1
  639. package/lib/module/features/crash/CrashReporter.js +53 -29
  640. package/lib/module/features/crash/CrashReporter.js.map +1 -1
  641. package/lib/module/features/crash/NativeCrashFeature.js +7 -7
  642. package/lib/module/features/crash/NativeCrashFeature.js.map +1 -1
  643. package/lib/module/features/crash/capture.js +28 -9
  644. package/lib/module/features/crash/capture.js.map +1 -1
  645. package/lib/module/features/crash/globalHandler.js +11 -11
  646. package/lib/module/features/crash/globalHandler.js.map +1 -1
  647. package/lib/module/features/crash/index.js.map +1 -1
  648. package/lib/module/features/crash/nativeCrashBridge.js +177 -44
  649. package/lib/module/features/crash/nativeCrashBridge.js.map +1 -1
  650. package/lib/module/features/crash/rejectionHandler.js +116 -0
  651. package/lib/module/features/crash/rejectionHandler.js.map +1 -0
  652. package/lib/module/features/engage/EngageAnchor.js +3 -3
  653. package/lib/module/features/engage/EngageAnchor.js.map +1 -1
  654. package/lib/module/features/engage/EngageArchetypeRenderers.js +19 -19
  655. package/lib/module/features/engage/EngageArchetypeRenderers.js.map +1 -1
  656. package/lib/module/features/engage/EngageInAppView.js +35 -35
  657. package/lib/module/features/engage/EngageInAppView.js.map +1 -1
  658. package/lib/module/features/engage/EngageInlinePlacement.js +7 -7
  659. package/lib/module/features/engage/EngageInlinePlacement.js.map +1 -1
  660. package/lib/module/features/engage/EngagePromptProvider.js +124 -88
  661. package/lib/module/features/engage/EngagePromptProvider.js.map +1 -1
  662. package/lib/module/features/engage/EngagePromptView.js +65 -32
  663. package/lib/module/features/engage/EngagePromptView.js.map +1 -1
  664. package/lib/module/features/engage/EngageTransport.js +79 -79
  665. package/lib/module/features/engage/EngageTransport.js.map +1 -1
  666. package/lib/module/features/engage/EngageVariantContent.js +10 -10
  667. package/lib/module/features/engage/EngageVariantContent.js.map +1 -1
  668. package/lib/module/features/engage/__test-support__/reactNativeStub.js +7 -7
  669. package/lib/module/features/engage/__test-support__/reactNativeStub.js.map +1 -1
  670. package/lib/module/features/engage/attachmentCapture.js +12 -12
  671. package/lib/module/features/engage/attachmentCapture.js.map +1 -1
  672. package/lib/module/features/engage/captureVoiceAttachment.js +20 -20
  673. package/lib/module/features/engage/captureVoiceAttachment.js.map +1 -1
  674. package/lib/module/features/engage/engageCoachmarkTour.js +4 -4
  675. package/lib/module/features/engage/engageCoachmarkTour.js.map +1 -1
  676. package/lib/module/features/engage/engageGameLogic.js.map +1 -1
  677. package/lib/module/features/engage/engageMediaSizing.js +15 -15
  678. package/lib/module/features/engage/engageMediaSizing.js.map +1 -1
  679. package/lib/module/features/engage/engageMultiStepSheet.js +6 -6
  680. package/lib/module/features/engage/engageMultiStepSheet.js.map +1 -1
  681. package/lib/module/features/engage/engageOutcome.js +6 -6
  682. package/lib/module/features/engage/engageOutcome.js.map +1 -1
  683. package/lib/module/features/engage/engagePushTokenBridge.js +20 -20
  684. package/lib/module/features/engage/engagePushTokenBridge.js.map +1 -1
  685. package/lib/module/features/engage/engageShakeBridge.js +16 -16
  686. package/lib/module/features/engage/engageShakeBridge.js.map +1 -1
  687. package/lib/module/features/engage/engageSignals.js.map +1 -1
  688. package/lib/module/features/engage/engageStoreReviewBridge.js +19 -19
  689. package/lib/module/features/engage/engageStoreReviewBridge.js.map +1 -1
  690. package/lib/module/features/engage/engageTestSeenStore.js +29 -29
  691. package/lib/module/features/engage/engageTestSeenStore.js.map +1 -1
  692. package/lib/module/features/engage/engageThrottle.js +117 -86
  693. package/lib/module/features/engage/engageThrottle.js.map +1 -1
  694. package/lib/module/features/engage/engageTriggerEngine.js +17 -7
  695. package/lib/module/features/engage/engageTriggerEngine.js.map +1 -1
  696. package/lib/module/features/engage/engageTypes.js +33 -33
  697. package/lib/module/features/engage/engageTypes.js.map +1 -1
  698. package/lib/module/features/engage/engageVariantResolver.js +13 -13
  699. package/lib/module/features/engage/engageVariantResolver.js.map +1 -1
  700. package/lib/module/features/engage/engageWindowInsets.js +10 -10
  701. package/lib/module/features/engage/engageWindowInsets.js.map +1 -1
  702. package/lib/module/features/engage/gestureTriggerDetector.js.map +1 -1
  703. package/lib/module/features/engage/transcription/TranscriptionProvider.js +16 -16
  704. package/lib/module/features/engage/transcription/TranscriptionProvider.js.map +1 -1
  705. package/lib/module/features/install-referrer/installReferrer.js +26 -26
  706. package/lib/module/features/install-referrer/installReferrer.js.map +1 -1
  707. package/lib/module/features/journey/ScaleBunDebugRoot.js +30 -29
  708. package/lib/module/features/journey/ScaleBunDebugRoot.js.map +1 -1
  709. package/lib/module/features/journey/ScaleBunFlatList.js +15 -15
  710. package/lib/module/features/journey/ScaleBunFlatList.js.map +1 -1
  711. package/lib/module/features/journey/ScaleBunImpression.js +22 -22
  712. package/lib/module/features/journey/ScaleBunImpression.js.map +1 -1
  713. package/lib/module/features/journey/ScaleBunScrollView.js +20 -20
  714. package/lib/module/features/journey/ScaleBunScrollView.js.map +1 -1
  715. package/lib/module/features/journey/ScaleBunSectionList.js +15 -15
  716. package/lib/module/features/journey/ScaleBunSectionList.js.map +1 -1
  717. package/lib/module/features/journey/calibrationContext.js +12 -12
  718. package/lib/module/features/journey/calibrationContext.js.map +1 -1
  719. package/lib/module/features/journey/gestureBuffer.js +9 -9
  720. package/lib/module/features/journey/gestureBuffer.js.map +1 -1
  721. package/lib/module/features/journey/gestureDetector.js +10 -10
  722. package/lib/module/features/journey/gestureDetector.js.map +1 -1
  723. package/lib/module/features/journey/impression.js +18 -18
  724. package/lib/module/features/journey/impression.js.map +1 -1
  725. package/lib/module/features/journey/journeyManager.js +6 -6
  726. package/lib/module/features/journey/journeyManager.js.map +1 -1
  727. package/lib/module/features/journey/journeyTypes.js +5 -5
  728. package/lib/module/features/journey/journeyTypes.js.map +1 -1
  729. package/lib/module/features/journey/navDetector.js +7 -7
  730. package/lib/module/features/journey/navDetector.js.map +1 -1
  731. package/lib/module/features/journey/screenshotHelper.js +7 -7
  732. package/lib/module/features/journey/screenshotHelper.js.map +1 -1
  733. package/lib/module/features/journey/targetRegistry.js +17 -17
  734. package/lib/module/features/journey/targetRegistry.js.map +1 -1
  735. package/lib/module/features/journey/touchTarget.js +29 -29
  736. package/lib/module/features/journey/touchTarget.js.map +1 -1
  737. package/lib/module/features/navigation/AutoScreenDetector.js +114 -71
  738. package/lib/module/features/navigation/AutoScreenDetector.js.map +1 -1
  739. package/lib/module/features/network/NetworkFeature.js +23 -23
  740. package/lib/module/features/network/NetworkFeature.js.map +1 -1
  741. package/lib/module/features/network/index.js +5 -5
  742. package/lib/module/features/network/index.js.map +1 -1
  743. package/lib/module/features/ota/OtaEventEmitter.js +21 -21
  744. package/lib/module/features/ota/OtaEventEmitter.js.map +1 -1
  745. package/lib/module/features/ota/OtaOrchestrator.js +596 -43
  746. package/lib/module/features/ota/OtaOrchestrator.js.map +1 -1
  747. package/lib/module/features/ota/OtaTypes.js.map +1 -1
  748. package/lib/module/features/ota/deviceAttributes.js +43 -0
  749. package/lib/module/features/ota/deviceAttributes.js.map +1 -0
  750. package/lib/module/features/ota/environment.js +165 -0
  751. package/lib/module/features/ota/environment.js.map +1 -0
  752. package/lib/module/features/ota/geoCountry.js +86 -0
  753. package/lib/module/features/ota/geoCountry.js.map +1 -0
  754. package/lib/module/features/ota/retry.js +87 -0
  755. package/lib/module/features/ota/retry.js.map +1 -0
  756. package/lib/module/features/ota/signature.js +109 -0
  757. package/lib/module/features/ota/signature.js.map +1 -0
  758. package/lib/module/features/ota/useOtaUpdate.js +18 -15
  759. package/lib/module/features/ota/useOtaUpdate.js.map +1 -1
  760. package/lib/module/features/performance/PerformanceFeature.js +49 -35
  761. package/lib/module/features/performance/PerformanceFeature.js.map +1 -1
  762. package/lib/module/features/performance/collectors/AppLaunchCollector.js +13 -13
  763. package/lib/module/features/performance/collectors/AppLaunchCollector.js.map +1 -1
  764. package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js +32 -32
  765. package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js.map +1 -1
  766. package/lib/module/features/performance/collectors/CustomTraceCollector.js +13 -13
  767. package/lib/module/features/performance/collectors/CustomTraceCollector.js.map +1 -1
  768. package/lib/module/features/performance/collectors/FrameMetricsCollector.js +81 -21
  769. package/lib/module/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
  770. package/lib/module/features/performance/collectors/JsStallCollector.js +12 -12
  771. package/lib/module/features/performance/collectors/JsStallCollector.js.map +1 -1
  772. package/lib/module/features/performance/collectors/NetworkPerfCollector.js +10 -10
  773. package/lib/module/features/performance/collectors/NetworkPerfCollector.js.map +1 -1
  774. package/lib/module/features/performance/collectors/ScreenLoadCollector.js +11 -11
  775. package/lib/module/features/performance/collectors/ScreenLoadCollector.js.map +1 -1
  776. package/lib/module/features/performance/collectors/UiHangCollector.js +5 -5
  777. package/lib/module/features/performance/collectors/UiHangCollector.js.map +1 -1
  778. package/lib/module/features/performance/config.js +11 -11
  779. package/lib/module/features/performance/config.js.map +1 -1
  780. package/lib/module/features/performance/getNativePerformanceModule.js +11 -11
  781. package/lib/module/features/performance/getNativePerformanceModule.js.map +1 -1
  782. package/lib/module/features/performance/index.js +2 -2
  783. package/lib/module/features/performance/index.js.map +1 -1
  784. package/lib/module/features/performance/metrics/MetricsEngine.js +13 -13
  785. package/lib/module/features/performance/metrics/MetricsEngine.js.map +1 -1
  786. package/lib/module/features/performance/models.js +8 -8
  787. package/lib/module/features/performance/models.js.map +1 -1
  788. package/lib/module/features/performance/transport/PerformanceTransport.js +31 -6
  789. package/lib/module/features/performance/transport/PerformanceTransport.js.map +1 -1
  790. package/lib/module/features/profiler/ProfilerFeature.js +53 -53
  791. package/lib/module/features/profiler/ProfilerFeature.js.map +1 -1
  792. package/lib/module/features/profiler/config.js +15 -15
  793. package/lib/module/features/profiler/config.js.map +1 -1
  794. package/lib/module/features/profiler/contracts.js +22 -22
  795. package/lib/module/features/profiler/contracts.js.map +1 -1
  796. package/lib/module/features/profiler/index.js +4 -4
  797. package/lib/module/features/profiler/index.js.map +1 -1
  798. package/lib/module/features/profiler/models.js +44 -44
  799. package/lib/module/features/profiler/models.js.map +1 -1
  800. package/lib/module/features/profiler/transport/ProfilerTransport.js +9 -9
  801. package/lib/module/features/profiler/transport/ProfilerTransport.js.map +1 -1
  802. package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js +17 -17
  803. package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js.map +1 -1
  804. package/lib/module/features/replay/bridge/eventEmitter.js +8 -8
  805. package/lib/module/features/replay/bridge/eventEmitter.js.map +1 -1
  806. package/lib/module/features/replay/bridge/nativeModule.js +20 -20
  807. package/lib/module/features/replay/bridge/nativeModule.js.map +1 -1
  808. package/lib/module/features/replay/core/clock/clock.js +6 -6
  809. package/lib/module/features/replay/core/clock/clock.js.map +1 -1
  810. package/lib/module/features/replay/core/config/defaults.js +2 -2
  811. package/lib/module/features/replay/core/config/defaults.js.map +1 -1
  812. package/lib/module/features/replay/core/config/validator.js +5 -5
  813. package/lib/module/features/replay/core/config/validator.js.map +1 -1
  814. package/lib/module/features/replay/core/env/environmentDetector.js +10 -10
  815. package/lib/module/features/replay/core/env/environmentDetector.js.map +1 -1
  816. package/lib/module/features/replay/core/errors/safeCall.js +4 -4
  817. package/lib/module/features/replay/core/errors/safeCall.js.map +1 -1
  818. package/lib/module/features/replay/core/ids/sessionId.js +5 -5
  819. package/lib/module/features/replay/core/ids/sessionId.js.map +1 -1
  820. package/lib/module/features/replay/core/logger/logger.js +5 -5
  821. package/lib/module/features/replay/core/logger/logger.js.map +1 -1
  822. package/lib/module/features/replay/core/privacy/privacyTypes.js +4 -4
  823. package/lib/module/features/replay/core/privacy/privacyTypes.js.map +1 -1
  824. package/lib/module/features/replay/core/queue/boundedQueue.js +5 -5
  825. package/lib/module/features/replay/core/queue/boundedQueue.js.map +1 -1
  826. package/lib/module/features/replay/integrations/alert/alertInstrumentation.js +59 -59
  827. package/lib/module/features/replay/integrations/alert/alertInstrumentation.js.map +1 -1
  828. package/lib/module/features/replay/integrations/logs/consoleIntegration.js +19 -19
  829. package/lib/module/features/replay/integrations/logs/consoleIntegration.js.map +1 -1
  830. package/lib/module/features/replay/integrations/network/networkAdapter.js +30 -30
  831. package/lib/module/features/replay/integrations/network/networkAdapter.js.map +1 -1
  832. package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js +19 -19
  833. package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
  834. package/lib/module/features/replay/integrations/touch/ReplayRoot.js +16 -16
  835. package/lib/module/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
  836. package/lib/module/features/replay/pipeline/batching/batchManager.js +5 -5
  837. package/lib/module/features/replay/pipeline/batching/batchManager.js.map +1 -1
  838. package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js +5 -5
  839. package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js.map +1 -1
  840. package/lib/module/features/replay/pipeline/retry/retryPolicy.js +4 -4
  841. package/lib/module/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
  842. package/lib/module/features/replay/pipeline/transport/transportTypes.js +7 -7
  843. package/lib/module/features/replay/pipeline/transport/transportTypes.js.map +1 -1
  844. package/lib/module/features/replay/public/api.js +21 -21
  845. package/lib/module/features/replay/public/api.js.map +1 -1
  846. package/lib/module/features/replay/public/enums.js +5 -5
  847. package/lib/module/features/replay/public/enums.js.map +1 -1
  848. package/lib/module/features/replay/public/types.js.map +1 -1
  849. package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js +5 -5
  850. package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js.map +1 -1
  851. package/lib/module/features/replay/replay/frames/frameModels.js +4 -4
  852. package/lib/module/features/replay/replay/frames/frameModels.js.map +1 -1
  853. package/lib/module/features/replay/replay/session/sessionOrchestrator.js +10 -10
  854. package/lib/module/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
  855. package/lib/module/features/replay/replay/timeline/timelineModels.js +4 -4
  856. package/lib/module/features/replay/replay/timeline/timelineModels.js.map +1 -1
  857. package/lib/module/features/replay/transport/BackendReplayTransport.js +13 -13
  858. package/lib/module/features/replay/transport/BackendReplayTransport.js.map +1 -1
  859. package/lib/module/features/replay/transport/CompositeReplayTransport.js +8 -8
  860. package/lib/module/features/replay/transport/CompositeReplayTransport.js.map +1 -1
  861. package/lib/module/features/replay/transport/DesktopReplayTransport.js +14 -14
  862. package/lib/module/features/replay/transport/DesktopReplayTransport.js.map +1 -1
  863. package/lib/module/features/replay/transport/ReplayTransport.js.map +1 -1
  864. package/lib/module/features/session/BackendSessionAdapter.js +485 -164
  865. package/lib/module/features/session/BackendSessionAdapter.js.map +1 -1
  866. package/lib/module/features/session/DesktopSessionTransport.js +14 -14
  867. package/lib/module/features/session/DesktopSessionTransport.js.map +1 -1
  868. package/lib/module/features/session/JourneyEventPipeline.js +20 -19
  869. package/lib/module/features/session/JourneyEventPipeline.js.map +1 -1
  870. package/lib/module/features/session/ReplayCaptureManager.js +169 -123
  871. package/lib/module/features/session/ReplayCaptureManager.js.map +1 -1
  872. package/lib/module/features/session/ScrollTracker.js +17 -17
  873. package/lib/module/features/session/ScrollTracker.js.map +1 -1
  874. package/lib/module/features/session/SessionManager.js +185 -155
  875. package/lib/module/features/session/SessionManager.js.map +1 -1
  876. package/lib/module/features/session/SyncDecisionEngine.js +23 -23
  877. package/lib/module/features/session/SyncDecisionEngine.js.map +1 -1
  878. package/lib/module/features/session/index.js +5 -5
  879. package/lib/module/features/session/index.js.map +1 -1
  880. package/lib/module/features/session/nativeCapture.js +9 -10
  881. package/lib/module/features/session/nativeCapture.js.map +1 -1
  882. package/lib/module/features/session/outboxFrameCapture.js +18 -17
  883. package/lib/module/features/session/outboxFrameCapture.js.map +1 -1
  884. package/lib/module/features/session/sessionTypes.js +44 -44
  885. package/lib/module/features/session/sessionTypes.js.map +1 -1
  886. package/lib/module/features/skan/skanBridge.js +11 -11
  887. package/lib/module/features/skan/skanBridge.js.map +1 -1
  888. package/lib/module/features/skan/skanConversionManager.js +23 -23
  889. package/lib/module/features/skan/skanConversionManager.js.map +1 -1
  890. package/lib/module/index.js +19 -10
  891. package/lib/module/index.js.map +1 -1
  892. package/lib/module/integrations/fetch/fetchInterceptor.js +21 -21
  893. package/lib/module/integrations/fetch/fetchInterceptor.js.map +1 -1
  894. package/lib/module/integrations/navigation/screenTracker.js.map +1 -1
  895. package/lib/module/integrations/network/bodyCapture.js +69 -69
  896. package/lib/module/integrations/network/bodyCapture.js.map +1 -1
  897. package/lib/module/integrations/xhr/xhrInterceptor.js +24 -24
  898. package/lib/module/integrations/xhr/xhrInterceptor.js.map +1 -1
  899. package/lib/module/metro/index.js +37 -37
  900. package/lib/module/metro/index.js.map +1 -1
  901. package/lib/module/metro/optionalDependencyStub.js +11 -11
  902. package/lib/module/metro/optionalDependencyStub.js.map +1 -1
  903. package/lib/module/metro/optionalModules.js +16 -16
  904. package/lib/module/metro/optionalModules.js.map +1 -1
  905. package/lib/module/pipeline/dispatcher/dispatcher.js.map +1 -1
  906. package/lib/module/pipeline/envelope/envelope.js.map +1 -1
  907. package/lib/module/pipeline/envelope/serializer.js.map +1 -1
  908. package/lib/module/pipeline/processors/dedupe.js.map +1 -1
  909. package/lib/module/pipeline/processors/enrich.js.map +1 -1
  910. package/lib/module/pipeline/processors/sampling.js.map +1 -1
  911. package/lib/module/pipeline/processors/sanitize.js.map +1 -1
  912. package/lib/module/pipeline/queue/flushQueue.js +4 -4
  913. package/lib/module/pipeline/queue/flushQueue.js.map +1 -1
  914. package/lib/module/pipeline/queue/memoryQueue.js.map +1 -1
  915. package/lib/module/pipeline/queue/persistentQueue.js +80 -80
  916. package/lib/module/pipeline/queue/persistentQueue.js.map +1 -1
  917. package/lib/module/pipeline/queue/queuePolicy.js.map +1 -1
  918. package/lib/module/pipeline/scheduler/flushScheduler.js.map +1 -1
  919. package/lib/module/pipeline/scheduler/retryPolicy.js +2 -2
  920. package/lib/module/pipeline/scheduler/retryPolicy.js.map +1 -1
  921. package/lib/module/public/ScaleBunErrorBoundary.js +70 -0
  922. package/lib/module/public/ScaleBunErrorBoundary.js.map +1 -0
  923. package/lib/module/public/ScaleBunFacade.js +424 -276
  924. package/lib/module/public/ScaleBunFacade.js.map +1 -1
  925. package/lib/module/public/ScaleBunProvider.js +3 -3
  926. package/lib/module/public/ScaleBunProvider.js.map +1 -1
  927. package/lib/module/public/typedTracker.js +36 -36
  928. package/lib/module/public/typedTracker.js.map +1 -1
  929. package/lib/module/public/types.js.map +1 -1
  930. package/lib/module/push/PushManager.js +21 -21
  931. package/lib/module/push/PushManager.js.map +1 -1
  932. package/lib/module/push/adapters/ManualAdapter.js +14 -14
  933. package/lib/module/push/adapters/ManualAdapter.js.map +1 -1
  934. package/lib/module/push/adapters/NativeBridgeAdapter.js +17 -17
  935. package/lib/module/push/adapters/NativeBridgeAdapter.js.map +1 -1
  936. package/lib/module/push/adapters/NoopAdapter.js +5 -5
  937. package/lib/module/push/adapters/NoopAdapter.js.map +1 -1
  938. package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js +17 -17
  939. package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js.map +1 -1
  940. package/lib/module/push/adapters/loadMessaging.js +12 -12
  941. package/lib/module/push/adapters/loadMessaging.js.map +1 -1
  942. package/lib/module/push/adapters/loadNotifee.js +12 -12
  943. package/lib/module/push/adapters/loadNotifee.js.map +1 -1
  944. package/lib/module/push/adapters/selectAdapter.js +14 -14
  945. package/lib/module/push/adapters/selectAdapter.js.map +1 -1
  946. package/lib/module/push/detect/capabilities.js +19 -19
  947. package/lib/module/push/detect/capabilities.js.map +1 -1
  948. package/lib/module/push/index.js +3 -3
  949. package/lib/module/push/index.js.map +1 -1
  950. package/lib/module/push/native/nativeNotifications.js +32 -32
  951. package/lib/module/push/native/nativeNotifications.js.map +1 -1
  952. package/lib/module/push/types.js.map +1 -1
  953. package/lib/module/specs/NativeReplaySdk.js +18 -18
  954. package/lib/module/specs/NativeReplaySdk.js.map +1 -1
  955. package/lib/module/specs/NativeScaleBunCrash.js +19 -19
  956. package/lib/module/specs/NativeScaleBunCrash.js.map +1 -1
  957. package/lib/module/specs/NativeScaleBunInstallReferrer.js +14 -14
  958. package/lib/module/specs/NativeScaleBunInstallReferrer.js.map +1 -1
  959. package/lib/module/specs/NativeScaleBunOta.js +21 -21
  960. package/lib/module/specs/NativeScaleBunOta.js.map +1 -1
  961. package/lib/module/specs/NativeScaleBunPerformance.js +15 -15
  962. package/lib/module/specs/NativeScaleBunPerformance.js.map +1 -1
  963. package/lib/module/specs/NativeScaleBunProfiler.js +16 -16
  964. package/lib/module/specs/NativeScaleBunProfiler.js.map +1 -1
  965. package/lib/module/specs/NativeScaleBunStorage.js +29 -29
  966. package/lib/module/specs/NativeScaleBunStorage.js.map +1 -1
  967. package/lib/module/storage/StorageBackend.js +83 -83
  968. package/lib/module/storage/StorageBackend.js.map +1 -1
  969. package/lib/module/storage/db/sqlite.js.map +1 -1
  970. package/lib/module/storage/files/fileStore.js.map +1 -1
  971. package/lib/module/transport/auth/sdkSession.js.map +1 -1
  972. package/lib/module/transport/backoff/exponentialJitter.js +2 -2
  973. package/lib/module/transport/backoff/exponentialJitter.js.map +1 -1
  974. package/lib/module/transport/http/endpoints.js.map +1 -1
  975. package/lib/module/transport/http/httpClient.js +3 -3
  976. package/lib/module/transport/http/httpClient.js.map +1 -1
  977. package/lib/module/transport/rateLimit/retryAfter.js.map +1 -1
  978. package/lib/module/transport/signing/requestSigner.js.map +1 -1
  979. package/lib/module/vendor/protocol/index.js +74 -74
  980. package/lib/module/vendor/protocol/index.js.map +1 -1
  981. package/lib/module/vendor/protocol/internal/validation.js +23 -23
  982. package/lib/module/vendor/protocol/internal/validation.js.map +1 -1
  983. package/lib/module/vendor/sdk-contracts/bridge.js.map +1 -1
  984. package/lib/module/vendor/sdk-contracts/config.js.map +1 -1
  985. package/lib/module/vendor/sdk-contracts/events.js.map +1 -1
  986. package/lib/module/vendor/sdk-contracts/features.js.map +1 -1
  987. package/lib/module/vendor/sdk-contracts/index.js.map +1 -1
  988. package/lib/module/vendor/sdk-contracts/platform.js.map +1 -1
  989. package/lib/module/vendor/sdk-contracts/session-boundary.js.map +1 -1
  990. package/lib/module/vendor/sdk-contracts/session.js.map +1 -1
  991. package/lib/module/vendor/vendor.manifest +10 -10
  992. package/lib/typescript/analytics/EventTracker.d.ts +20 -0
  993. package/lib/typescript/analytics/EventTracker.d.ts.map +1 -1
  994. package/lib/typescript/bootstrap/SDKBootstrapper.d.ts.map +1 -1
  995. package/lib/typescript/core/config/schema.d.ts +1 -1
  996. package/lib/typescript/core/config/schema.d.ts.map +1 -1
  997. package/lib/typescript/core/context/device.d.ts +46 -0
  998. package/lib/typescript/core/context/device.d.ts.map +1 -1
  999. package/lib/typescript/debug/replayWiring.d.ts.map +1 -1
  1000. package/lib/typescript/features/bugreport/BugReportFeature.d.ts +59 -0
  1001. package/lib/typescript/features/bugreport/BugReportFeature.d.ts.map +1 -0
  1002. package/lib/typescript/features/bugreport/buildPayload.d.ts +51 -0
  1003. package/lib/typescript/features/bugreport/buildPayload.d.ts.map +1 -0
  1004. package/lib/typescript/features/crash/CrashFeature.d.ts.map +1 -1
  1005. package/lib/typescript/features/crash/CrashReporter.d.ts +20 -1
  1006. package/lib/typescript/features/crash/CrashReporter.d.ts.map +1 -1
  1007. package/lib/typescript/features/crash/capture.d.ts +21 -2
  1008. package/lib/typescript/features/crash/capture.d.ts.map +1 -1
  1009. package/lib/typescript/features/crash/nativeCrashBridge.d.ts +16 -3
  1010. package/lib/typescript/features/crash/nativeCrashBridge.d.ts.map +1 -1
  1011. package/lib/typescript/features/crash/rejectionHandler.d.ts +46 -0
  1012. package/lib/typescript/features/crash/rejectionHandler.d.ts.map +1 -0
  1013. package/lib/typescript/features/engage/EngagePromptProvider.d.ts.map +1 -1
  1014. package/lib/typescript/features/engage/EngagePromptView.d.ts.map +1 -1
  1015. package/lib/typescript/features/engage/engageThrottle.d.ts +24 -4
  1016. package/lib/typescript/features/engage/engageThrottle.d.ts.map +1 -1
  1017. package/lib/typescript/features/engage/engageTriggerEngine.d.ts.map +1 -1
  1018. package/lib/typescript/features/engage/engageTypes.d.ts +21 -0
  1019. package/lib/typescript/features/engage/engageTypes.d.ts.map +1 -1
  1020. package/lib/typescript/features/journey/ScaleBunDebugRoot.d.ts.map +1 -1
  1021. package/lib/typescript/features/navigation/AutoScreenDetector.d.ts +9 -0
  1022. package/lib/typescript/features/navigation/AutoScreenDetector.d.ts.map +1 -1
  1023. package/lib/typescript/features/ota/OtaOrchestrator.d.ts +75 -3
  1024. package/lib/typescript/features/ota/OtaOrchestrator.d.ts.map +1 -1
  1025. package/lib/typescript/features/ota/OtaTypes.d.ts +42 -0
  1026. package/lib/typescript/features/ota/OtaTypes.d.ts.map +1 -1
  1027. package/lib/typescript/features/ota/deviceAttributes.d.ts +18 -0
  1028. package/lib/typescript/features/ota/deviceAttributes.d.ts.map +1 -0
  1029. package/lib/typescript/features/ota/environment.d.ts +99 -0
  1030. package/lib/typescript/features/ota/environment.d.ts.map +1 -0
  1031. package/lib/typescript/features/ota/geoCountry.d.ts +14 -0
  1032. package/lib/typescript/features/ota/geoCountry.d.ts.map +1 -0
  1033. package/lib/typescript/features/ota/retry.d.ts +53 -0
  1034. package/lib/typescript/features/ota/retry.d.ts.map +1 -0
  1035. package/lib/typescript/features/ota/signature.d.ts +66 -0
  1036. package/lib/typescript/features/ota/signature.d.ts.map +1 -0
  1037. package/lib/typescript/features/ota/useOtaUpdate.d.ts +20 -2
  1038. package/lib/typescript/features/ota/useOtaUpdate.d.ts.map +1 -1
  1039. package/lib/typescript/features/performance/PerformanceFeature.d.ts +0 -1
  1040. package/lib/typescript/features/performance/PerformanceFeature.d.ts.map +1 -1
  1041. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts +33 -0
  1042. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts.map +1 -1
  1043. package/lib/typescript/features/performance/transport/PerformanceTransport.d.ts.map +1 -1
  1044. package/lib/typescript/features/session/BackendSessionAdapter.d.ts +135 -4
  1045. package/lib/typescript/features/session/BackendSessionAdapter.d.ts.map +1 -1
  1046. package/lib/typescript/features/session/JourneyEventPipeline.d.ts +2 -0
  1047. package/lib/typescript/features/session/JourneyEventPipeline.d.ts.map +1 -1
  1048. package/lib/typescript/features/session/ReplayCaptureManager.d.ts +38 -1
  1049. package/lib/typescript/features/session/ReplayCaptureManager.d.ts.map +1 -1
  1050. package/lib/typescript/features/session/SessionManager.d.ts.map +1 -1
  1051. package/lib/typescript/features/session/nativeCapture.d.ts +2 -1
  1052. package/lib/typescript/features/session/nativeCapture.d.ts.map +1 -1
  1053. package/lib/typescript/features/session/outboxFrameCapture.d.ts.map +1 -1
  1054. package/lib/typescript/features/session/sessionTypes.d.ts +20 -3
  1055. package/lib/typescript/features/session/sessionTypes.d.ts.map +1 -1
  1056. package/lib/typescript/index.d.ts +7 -0
  1057. package/lib/typescript/index.d.ts.map +1 -1
  1058. package/lib/typescript/public/ScaleBunErrorBoundary.d.ts +44 -0
  1059. package/lib/typescript/public/ScaleBunErrorBoundary.d.ts.map +1 -0
  1060. package/lib/typescript/public/ScaleBunFacade.d.ts +58 -0
  1061. package/lib/typescript/public/ScaleBunFacade.d.ts.map +1 -1
  1062. package/lib/typescript/specs/NativeScaleBunCrash.d.ts +14 -0
  1063. package/lib/typescript/specs/NativeScaleBunCrash.d.ts.map +1 -1
  1064. package/lib/typescript/specs/NativeScaleBunOta.d.ts +11 -0
  1065. package/lib/typescript/specs/NativeScaleBunOta.d.ts.map +1 -1
  1066. package/lib/typescript/vendor/protocol/index.d.ts +17 -17
  1067. package/package.json +12 -14
  1068. package/react-native.config.js +24 -24
  1069. package/scalebun-react-native.podspec +37 -37
  1070. package/src/analytics/EventTracker.ts +489 -462
  1071. package/src/analytics/automaticEvents.ts +105 -105
  1072. package/src/analytics/batching.ts +54 -54
  1073. package/src/analytics/eventLane.ts +26 -26
  1074. package/src/bootstrap/FeatureRegistry.ts +81 -81
  1075. package/src/bootstrap/SDKBootstrapper.ts +610 -585
  1076. package/src/bucketing/fnv1a32.ts +40 -40
  1077. package/src/compat/codepush.ts +118 -118
  1078. package/src/config/ConfigManager.ts +167 -167
  1079. package/src/config/configTypes.ts +32 -32
  1080. package/src/core/architecture.ts +39 -39
  1081. package/src/core/clock/now.ts +6 -6
  1082. package/src/core/config/schema.ts +239 -231
  1083. package/src/core/constants/endpoints.ts +9 -9
  1084. package/src/core/constants/timings.ts +23 -23
  1085. package/src/core/constants/version.ts +6 -6
  1086. package/src/core/context/device.ts +146 -0
  1087. package/src/core/context/user.ts +26 -26
  1088. package/src/core/contracts/IFeature.ts +53 -53
  1089. package/src/core/di/container.ts +26 -26
  1090. package/src/core/encoding/base64.ts +46 -46
  1091. package/src/core/id/deviceId.ts +51 -51
  1092. package/src/core/lifecycle/appLifecycle.ts +33 -33
  1093. package/src/core/lifecycle/crashSafe.ts +29 -29
  1094. package/src/core/logger/errorClassification.ts +108 -108
  1095. package/src/core/logger/internalLogger.ts +65 -65
  1096. package/src/crypto/hmacSha256.ts +106 -106
  1097. package/src/debug/bootstrap.ts +366 -366
  1098. package/src/debug/commands.ts +597 -597
  1099. package/src/debug/configBuilder.ts +56 -56
  1100. package/src/debug/exportBridge.ts +153 -153
  1101. package/src/debug/hostResolver.ts +34 -34
  1102. package/src/debug/index.ts +25 -25
  1103. package/src/debug/metrics.ts +29 -29
  1104. package/src/debug/perf.ts +212 -212
  1105. package/src/debug/perfWiring.ts +119 -119
  1106. package/src/debug/protocol.ts +58 -58
  1107. package/src/debug/redaction.ts +290 -290
  1108. package/src/debug/replayWiring.ts +148 -147
  1109. package/src/debug/screenTracking.ts +55 -55
  1110. package/src/debug/sessionWiring.ts +59 -59
  1111. package/src/debug/stream.ts +561 -561
  1112. package/src/debug/transport.ts +439 -439
  1113. package/src/features/bugreport/BugReportFeature.ts +128 -0
  1114. package/src/features/bugreport/buildPayload.ts +116 -0
  1115. package/src/features/crash/CrashFeature.ts +71 -52
  1116. package/src/features/crash/CrashReporter.ts +179 -140
  1117. package/src/features/crash/NativeCrashFeature.ts +42 -42
  1118. package/src/features/crash/capture.ts +48 -21
  1119. package/src/features/crash/globalHandler.ts +39 -39
  1120. package/src/features/crash/index.ts +8 -8
  1121. package/src/features/crash/nativeCrashBridge.ts +266 -132
  1122. package/src/features/crash/rejectionHandler.ts +134 -0
  1123. package/src/features/engage/EngageAnchor.tsx +159 -159
  1124. package/src/features/engage/EngageArchetypeRenderers.tsx +3716 -3716
  1125. package/src/features/engage/EngageInAppView.tsx +2678 -2678
  1126. package/src/features/engage/EngageInlinePlacement.tsx +169 -169
  1127. package/src/features/engage/EngagePromptProvider.tsx +1318 -1270
  1128. package/src/features/engage/EngagePromptView.tsx +1400 -1364
  1129. package/src/features/engage/EngageTransport.ts +668 -668
  1130. package/src/features/engage/EngageVariantContent.tsx +1483 -1483
  1131. package/src/features/engage/__test-support__/reactNativeStub.js +40 -40
  1132. package/src/features/engage/attachmentCapture.ts +45 -45
  1133. package/src/features/engage/captureVoiceAttachment.ts +81 -81
  1134. package/src/features/engage/engageCoachmarkTour.ts +120 -120
  1135. package/src/features/engage/engageGameLogic.ts +347 -347
  1136. package/src/features/engage/engageMediaSizing.ts +76 -76
  1137. package/src/features/engage/engageMultiStepSheet.ts +53 -53
  1138. package/src/features/engage/engageOutcome.ts +157 -157
  1139. package/src/features/engage/engagePushTokenBridge.ts +84 -84
  1140. package/src/features/engage/engageShakeBridge.ts +67 -67
  1141. package/src/features/engage/engageSignals.ts +40 -40
  1142. package/src/features/engage/engageStoreReviewBridge.ts +48 -48
  1143. package/src/features/engage/engageTestSeenStore.ts +95 -95
  1144. package/src/features/engage/engageThrottle.ts +478 -440
  1145. package/src/features/engage/engageTriggerEngine.ts +350 -335
  1146. package/src/features/engage/engageTypes.ts +712 -691
  1147. package/src/features/engage/engageVariantResolver.ts +364 -364
  1148. package/src/features/engage/engageWindowInsets.ts +108 -108
  1149. package/src/features/engage/gestureTriggerDetector.ts +83 -83
  1150. package/src/features/engage/transcription/TranscriptionProvider.ts +68 -68
  1151. package/src/features/install-referrer/installReferrer.ts +112 -112
  1152. package/src/features/journey/ScaleBunDebugRoot.tsx +727 -726
  1153. package/src/features/journey/ScaleBunFlatList.tsx +39 -39
  1154. package/src/features/journey/ScaleBunImpression.tsx +109 -109
  1155. package/src/features/journey/ScaleBunScrollView.tsx +72 -72
  1156. package/src/features/journey/ScaleBunSectionList.tsx +39 -39
  1157. package/src/features/journey/calibrationContext.ts +53 -53
  1158. package/src/features/journey/gestureBuffer.ts +59 -59
  1159. package/src/features/journey/gestureDetector.ts +162 -162
  1160. package/src/features/journey/impression.ts +92 -92
  1161. package/src/features/journey/journeyManager.ts +466 -466
  1162. package/src/features/journey/journeyTypes.ts +215 -215
  1163. package/src/features/journey/navDetector.ts +149 -149
  1164. package/src/features/journey/screenshotHelper.ts +137 -137
  1165. package/src/features/journey/targetRegistry.ts +43 -43
  1166. package/src/features/journey/touchTarget.ts +128 -128
  1167. package/src/features/navigation/AutoScreenDetector.ts +503 -448
  1168. package/src/features/network/NetworkFeature.ts +144 -144
  1169. package/src/features/network/index.ts +31 -31
  1170. package/src/features/ota/OtaEventEmitter.ts +128 -128
  1171. package/src/features/ota/OtaOrchestrator.ts +963 -323
  1172. package/src/features/ota/OtaTypes.ts +118 -62
  1173. package/src/features/ota/deviceAttributes.ts +46 -0
  1174. package/src/features/ota/environment.ts +199 -0
  1175. package/src/features/ota/geoCountry.ts +85 -0
  1176. package/src/features/ota/retry.ts +123 -0
  1177. package/src/features/ota/signature.ts +123 -0
  1178. package/src/features/ota/useOtaUpdate.ts +152 -134
  1179. package/src/features/performance/PerformanceFeature.ts +597 -584
  1180. package/src/features/performance/collectors/AppLaunchCollector.ts +117 -117
  1181. package/src/features/performance/collectors/AutoScreenLoadCollector.ts +258 -258
  1182. package/src/features/performance/collectors/CustomTraceCollector.ts +116 -116
  1183. package/src/features/performance/collectors/FrameMetricsCollector.ts +181 -119
  1184. package/src/features/performance/collectors/JsStallCollector.ts +165 -165
  1185. package/src/features/performance/collectors/NetworkPerfCollector.ts +69 -69
  1186. package/src/features/performance/collectors/ScreenLoadCollector.ts +95 -95
  1187. package/src/features/performance/collectors/UiHangCollector.ts +98 -98
  1188. package/src/features/performance/config.ts +136 -136
  1189. package/src/features/performance/getNativePerformanceModule.ts +38 -38
  1190. package/src/features/performance/index.ts +28 -28
  1191. package/src/features/performance/metrics/MetricsEngine.ts +152 -152
  1192. package/src/features/performance/models.ts +235 -235
  1193. package/src/features/performance/transport/PerformanceTransport.ts +161 -143
  1194. package/src/features/profiler/ProfilerFeature.ts +661 -661
  1195. package/src/features/profiler/config.ts +230 -230
  1196. package/src/features/profiler/contracts.ts +176 -176
  1197. package/src/features/profiler/index.ts +45 -45
  1198. package/src/features/profiler/models.ts +430 -430
  1199. package/src/features/profiler/transport/ProfilerTransport.ts +93 -93
  1200. package/src/features/replay/bridge/adapters/bridgeAdapter.ts +230 -230
  1201. package/src/features/replay/bridge/eventEmitter.ts +176 -176
  1202. package/src/features/replay/bridge/nativeModule.ts +241 -241
  1203. package/src/features/replay/core/clock/clock.ts +38 -38
  1204. package/src/features/replay/core/config/defaults.ts +66 -66
  1205. package/src/features/replay/core/config/validator.ts +113 -113
  1206. package/src/features/replay/core/env/environmentDetector.ts +21 -21
  1207. package/src/features/replay/core/errors/safeCall.ts +34 -34
  1208. package/src/features/replay/core/ids/sessionId.ts +44 -44
  1209. package/src/features/replay/core/logger/logger.ts +40 -40
  1210. package/src/features/replay/core/privacy/privacyTypes.ts +41 -41
  1211. package/src/features/replay/core/queue/boundedQueue.ts +71 -71
  1212. package/src/features/replay/integrations/alert/alertInstrumentation.ts +277 -277
  1213. package/src/features/replay/integrations/logs/consoleIntegration.ts +116 -116
  1214. package/src/features/replay/integrations/network/networkAdapter.ts +128 -128
  1215. package/src/features/replay/integrations/react-navigation/navigationIntegration.ts +89 -89
  1216. package/src/features/replay/integrations/touch/ReplayRoot.tsx +114 -114
  1217. package/src/features/replay/pipeline/batching/batchManager.ts +133 -133
  1218. package/src/features/replay/pipeline/envelope/envelopeBuilder.ts +66 -66
  1219. package/src/features/replay/pipeline/retry/retryPolicy.ts +62 -62
  1220. package/src/features/replay/pipeline/transport/transportTypes.ts +85 -85
  1221. package/src/features/replay/public/api.ts +364 -364
  1222. package/src/features/replay/public/enums.ts +78 -78
  1223. package/src/features/replay/public/types.ts +297 -297
  1224. package/src/features/replay/replay/breadcrumbs/breadcrumbCollector.ts +115 -115
  1225. package/src/features/replay/replay/frames/frameModels.ts +45 -45
  1226. package/src/features/replay/replay/session/sessionOrchestrator.ts +286 -286
  1227. package/src/features/replay/replay/timeline/timelineModels.ts +129 -129
  1228. package/src/features/replay/transport/BackendReplayTransport.ts +215 -215
  1229. package/src/features/replay/transport/CompositeReplayTransport.ts +82 -82
  1230. package/src/features/replay/transport/DesktopReplayTransport.ts +140 -140
  1231. package/src/features/replay/transport/ReplayTransport.ts +84 -84
  1232. package/src/features/session/BackendSessionAdapter.ts +1568 -1233
  1233. package/src/features/session/DesktopSessionTransport.ts +128 -128
  1234. package/src/features/session/JourneyEventPipeline.ts +276 -273
  1235. package/src/features/session/ReplayCaptureManager.ts +998 -946
  1236. package/src/features/session/ScrollTracker.ts +166 -166
  1237. package/src/features/session/SessionManager.ts +1248 -1209
  1238. package/src/features/session/SyncDecisionEngine.ts +117 -117
  1239. package/src/features/session/index.ts +88 -88
  1240. package/src/features/session/nativeCapture.ts +39 -38
  1241. package/src/features/session/outboxFrameCapture.ts +75 -74
  1242. package/src/features/session/sessionTypes.ts +514 -491
  1243. package/src/features/skan/skanBridge.ts +61 -61
  1244. package/src/features/skan/skanConversionManager.ts +173 -173
  1245. package/src/index.ts +200 -191
  1246. package/src/integrations/fetch/fetchInterceptor.ts +182 -182
  1247. package/src/integrations/network/bodyCapture.ts +328 -328
  1248. package/src/integrations/xhr/xhrInterceptor.ts +231 -231
  1249. package/src/metro/index.ts +164 -164
  1250. package/src/metro/optionalDependencyStub.ts +13 -13
  1251. package/src/metro/optionalModules.ts +27 -27
  1252. package/src/pipeline/dispatcher/dispatcher.ts +22 -22
  1253. package/src/pipeline/envelope/envelope.ts +31 -31
  1254. package/src/pipeline/envelope/serializer.ts +14 -14
  1255. package/src/pipeline/processors/enrich.ts +11 -11
  1256. package/src/pipeline/processors/sanitize.ts +23 -23
  1257. package/src/pipeline/queue/flushQueue.ts +144 -144
  1258. package/src/pipeline/queue/memoryQueue.ts +31 -31
  1259. package/src/pipeline/queue/persistentQueue.ts +414 -414
  1260. package/src/pipeline/scheduler/flushScheduler.ts +47 -47
  1261. package/src/pipeline/scheduler/retryPolicy.ts +8 -8
  1262. package/src/public/ScaleBunErrorBoundary.tsx +79 -0
  1263. package/src/public/ScaleBunFacade.ts +1630 -1479
  1264. package/src/public/ScaleBunProvider.tsx +91 -91
  1265. package/src/public/typedTracker.ts +123 -123
  1266. package/src/public/types.ts +312 -312
  1267. package/src/push/PushManager.ts +318 -318
  1268. package/src/push/adapters/ManualAdapter.ts +100 -100
  1269. package/src/push/adapters/NativeBridgeAdapter.ts +142 -142
  1270. package/src/push/adapters/NoopAdapter.ts +46 -46
  1271. package/src/push/adapters/RNFirebaseMessagingAdapter.ts +271 -271
  1272. package/src/push/adapters/loadMessaging.ts +24 -24
  1273. package/src/push/adapters/loadNotifee.ts +29 -29
  1274. package/src/push/adapters/selectAdapter.ts +176 -176
  1275. package/src/push/detect/capabilities.ts +124 -124
  1276. package/src/push/index.ts +22 -22
  1277. package/src/push/native/nativeNotifications.ts +216 -216
  1278. package/src/push/types.ts +159 -159
  1279. package/src/specs/NativeReplaySdk.ts +99 -99
  1280. package/src/specs/NativeScaleBunCrash.ts +52 -36
  1281. package/src/specs/NativeScaleBunInstallReferrer.ts +29 -29
  1282. package/src/specs/NativeScaleBunOta.ts +97 -85
  1283. package/src/specs/NativeScaleBunPerformance.ts +34 -34
  1284. package/src/specs/NativeScaleBunProfiler.ts +41 -41
  1285. package/src/specs/NativeScaleBunStorage.ts +59 -59
  1286. package/src/storage/StorageBackend.ts +272 -272
  1287. package/src/transport/auth/sdkSession.ts +27 -27
  1288. package/src/transport/backoff/exponentialJitter.ts +9 -9
  1289. package/src/transport/http/endpoints.ts +33 -33
  1290. package/src/transport/http/httpClient.ts +73 -73
  1291. package/src/vendor/protocol/index.ts +391 -391
  1292. package/src/vendor/protocol/internal/validation.ts +497 -497
  1293. package/src/vendor/sdk-contracts/bridge.ts +162 -162
  1294. package/src/vendor/sdk-contracts/config.ts +192 -192
  1295. package/src/vendor/sdk-contracts/events.ts +50 -50
  1296. package/src/vendor/sdk-contracts/features.ts +42 -42
  1297. package/src/vendor/sdk-contracts/index.ts +98 -98
  1298. package/src/vendor/sdk-contracts/platform.ts +42 -42
  1299. package/src/vendor/sdk-contracts/session-boundary.ts +55 -55
  1300. package/src/vendor/sdk-contracts/session.ts +225 -225
  1301. package/src/vendor/vendor.manifest +10 -10
  1302. package/android/build/generated/source/buildConfig/debug/com/scalebun/sdk/BuildConfig.java +0 -12
  1303. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeReplaySdkSpec.java +0 -208
  1304. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunCrashSpec.java +0 -46
  1305. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.java +0 -38
  1306. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunOtaSpec.java +0 -63
  1307. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunPerformanceSpec.java +0 -70
  1308. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunProfilerSpec.java +0 -96
  1309. package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunStorageSpec.java +0 -50
  1310. package/android/build/generated/source/codegen/jni/CMakeLists.txt +0 -28
  1311. package/android/build/generated/source/codegen/jni/ScaleBunSpec-generated.cpp +0 -554
  1312. package/android/build/generated/source/codegen/jni/ScaleBunSpec.h +0 -79
  1313. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ComponentDescriptors.cpp +0 -22
  1314. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ComponentDescriptors.h +0 -24
  1315. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/EventEmitters.cpp +0 -16
  1316. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/EventEmitters.h +0 -17
  1317. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/Props.cpp +0 -19
  1318. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/Props.h +0 -18
  1319. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ScaleBunSpecJSI-generated.cpp +0 -595
  1320. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ScaleBunSpecJSI.h +0 -1070
  1321. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ShadowNodes.cpp +0 -17
  1322. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ShadowNodes.h +0 -23
  1323. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/States.cpp +0 -16
  1324. package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/States.h +0 -20
  1325. package/android/build/generated/source/codegen/schema.json +0 -1
  1326. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -20
  1327. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  1328. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  1329. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  1330. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  1331. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  1332. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  1333. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
  1334. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  1335. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  1336. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  1337. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  1338. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
  1339. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/sdk/BuildConfig.class +0 -0
  1340. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeReplaySdkSpec.class +0 -0
  1341. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunCrashSpec.class +0 -0
  1342. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.class +0 -0
  1343. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunOtaSpec.class +0 -0
  1344. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunPerformanceSpec.class +0 -0
  1345. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunProfilerSpec.class +0 -0
  1346. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunStorageSpec.class +0 -0
  1347. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
  1348. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -24
  1349. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -20
  1350. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  1351. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  1352. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
  1353. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/CrashStorage.class +0 -0
  1354. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/NativeCrashHandler$Companion.class +0 -0
  1355. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/NativeCrashHandler.class +0 -0
  1356. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/ANRWatchdog$HangInfo.class +0 -0
  1357. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/ANRWatchdog.class +0 -0
  1358. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$AppStartInfo.class +0 -0
  1359. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$Breakdown.class +0 -0
  1360. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$start$1.class +0 -0
  1361. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector.class +0 -0
  1362. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$Companion.class +0 -0
  1363. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$FrameMetricsSnapshot.class +0 -0
  1364. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$start$1.class +0 -0
  1365. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$startChoreographerFallback$1.class +0 -0
  1366. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector.class +0 -0
  1367. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/PerformanceCore$Listener.class +0 -0
  1368. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/PerformanceCore.class +0 -0
  1369. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerModule$Companion.class +0 -0
  1370. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerModule.class +0 -0
  1371. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerPackage.class +0 -0
  1372. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerSpec.class +0 -0
  1373. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/CpuCollector.class +0 -0
  1374. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/IncidentDetector.class +0 -0
  1375. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/MemoryCollector.class +0 -0
  1376. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/RenderCollector$frameCallback$1.class +0 -0
  1377. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/RenderCollector.class +0 -0
  1378. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/SamplerScheduler.class +0 -0
  1379. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/SamplerSchedulerKt.class +0 -0
  1380. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/ThreadCollector$WhenMappings.class +0 -0
  1381. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/ThreadCollector.class +0 -0
  1382. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule$Companion.class +0 -0
  1383. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule$registerConnectivity$cb$1.class +0 -0
  1384. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule.class +0 -0
  1385. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkPackage.class +0 -0
  1386. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkSpec.class +0 -0
  1387. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/CaptureReason$Companion.class +0 -0
  1388. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/CaptureReason.class +0 -0
  1389. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureManager$startFrequencyTimer$1.class +0 -0
  1390. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureManager.class +0 -0
  1391. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$Companion.class +0 -0
  1392. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$FrameRequest.class +0 -0
  1393. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler.class +0 -0
  1394. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$Companion.class +0 -0
  1395. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$SettleWatch.class +0 -0
  1396. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$StabilityWatch.class +0 -0
  1397. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector.class +0 -0
  1398. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/CaptureMode$Companion.class +0 -0
  1399. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/CaptureMode.class +0 -0
  1400. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayConfig$Companion.class +0 -0
  1401. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayConfig.class +0 -0
  1402. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayLogger.class +0 -0
  1403. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ScreenshotQuality$Companion.class +0 -0
  1404. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ScreenshotQuality.class +0 -0
  1405. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/SessionIdGenerator.class +0 -0
  1406. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/SessionState.class +0 -0
  1407. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/ReplayFrame.class +0 -0
  1408. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/ReplaySession.class +0 -0
  1409. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/TimelineEvent.class +0 -0
  1410. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox$Companion.class +0 -0
  1411. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox$enforceLimits$lambda$37$$inlined$sortedBy$1.class +0 -0
  1412. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox.class +0 -0
  1413. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$NetworkError.class +0 -0
  1414. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$Response.class +0 -0
  1415. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult.class +0 -0
  1416. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$Outcome.class +0 -0
  1417. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$WhenMappings.class +0 -0
  1418. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader.class +0 -0
  1419. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.class +0 -0
  1420. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/session/SessionManager.class +0 -0
  1421. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/storage/ReplayStorage$enforceStorageLimit$$inlined$sortedBy$1.class +0 -0
  1422. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/storage/ReplayStorage.class +0 -0
  1423. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/timeline/TimelineCollector.class +0 -0
  1424. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/DialogTouchObserver$start$runnable$1.class +0 -0
  1425. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/DialogTouchObserver.class +0 -0
  1426. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/InteractionTracker.class +0 -0
  1427. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/NativeTouchInterceptor.class +0 -0
  1428. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/ScreenTracker.class +0 -0
  1429. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport$UploadResult.class +0 -0
  1430. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport$upload$2.class +0 -0
  1431. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport.class +0 -0
  1432. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder$Companion.class +0 -0
  1433. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder$Result.class +0 -0
  1434. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder.class +0 -0
  1435. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber$TranscriptResult.class +0 -0
  1436. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber$listener$1.class +0 -0
  1437. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber.class +0 -0
  1438. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ScaleBunPackage$Companion.class +0 -0
  1439. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ScaleBunPackage.class +0 -0
  1440. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashModule$Companion.class +0 -0
  1441. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashModule.class +0 -0
  1442. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashPackage.class +0 -0
  1443. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashSpec.class +0 -0
  1444. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$Companion.class +0 -0
  1445. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$WindowInsetEdges.class +0 -0
  1446. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$shakeListener$1.class +0 -0
  1447. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule.class +0 -0
  1448. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngagePackage.class +0 -0
  1449. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunNotificationPresenter.class +0 -0
  1450. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaModule$Companion.class +0 -0
  1451. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaModule.class +0 -0
  1452. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaSpec.class +0 -0
  1453. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/SlotManager$Companion.class +0 -0
  1454. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/SlotManager.class +0 -0
  1455. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule$Companion.class +0 -0
  1456. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule$coreListener$1.class +0 -0
  1457. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule.class +0 -0
  1458. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceSpec.class +0 -0
  1459. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$Companion.class +0 -0
  1460. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$getInstallReferrer$1.class +0 -0
  1461. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.class +0 -0
  1462. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.class +0 -0
  1463. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageModule$Companion.class +0 -0
  1464. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageModule.class +0 -0
  1465. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageSpec.class +0 -0
  1466. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/sdk/BuildConfig.class +0 -0
  1467. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeReplaySdkSpec.class +0 -0
  1468. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunCrashSpec.class +0 -0
  1469. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.class +0 -0
  1470. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunOtaSpec.class +0 -0
  1471. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunPerformanceSpec.class +0 -0
  1472. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunProfilerSpec.class +0 -0
  1473. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunStorageSpec.class +0 -0
  1474. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/storage/KvFileStore$Companion.class +0 -0
  1475. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/storage/KvFileStore.class +0 -0
  1476. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  1477. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
  1478. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  1479. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  1480. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  1481. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  1482. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  1483. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  1484. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  1485. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  1486. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  1487. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  1488. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  1489. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  1490. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  1491. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  1492. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  1493. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  1494. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  1495. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  1496. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  1497. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  1498. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  1499. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  1500. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  1501. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  1502. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  1503. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  1504. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  1505. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  1506. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  1507. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  1508. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  1509. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  1510. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  1511. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  1512. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  1513. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
  1514. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream +0 -0
  1515. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len +0 -0
  1516. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len +0 -0
  1517. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
  1518. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i +0 -0
  1519. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len +0 -0
  1520. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  1521. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  1522. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  1523. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  1524. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
  1525. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  1526. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +0 -1
  1527. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  1528. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  1529. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  1530. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  1531. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  1532. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  1533. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  1534. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  1535. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  1536. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  1537. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  1538. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  1539. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  1540. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  1541. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  1542. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  1543. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  1544. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  1545. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  1546. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  1547. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  1548. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  1549. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  1550. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +0 -2
  1551. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  1552. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  1553. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  1554. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  1555. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  1556. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  1557. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  1558. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  1559. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  1560. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  1561. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  1562. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  1563. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  1564. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  1565. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  1566. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  1567. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  1568. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  1569. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values +0 -0
  1570. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  1571. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s +0 -1
  1572. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  1573. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  1574. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  1575. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  1576. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  1577. package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -25
  1578. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  1579. package/android/build/tmp/kotlin-classes/debug/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
  1580. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/CrashStorage.class +0 -0
  1581. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/NativeCrashHandler$Companion.class +0 -0
  1582. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/NativeCrashHandler.class +0 -0
  1583. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/ANRWatchdog$HangInfo.class +0 -0
  1584. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/ANRWatchdog.class +0 -0
  1585. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$AppStartInfo.class +0 -0
  1586. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$Breakdown.class +0 -0
  1587. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$start$1.class +0 -0
  1588. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector.class +0 -0
  1589. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$Companion.class +0 -0
  1590. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$FrameMetricsSnapshot.class +0 -0
  1591. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$start$1.class +0 -0
  1592. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$startChoreographerFallback$1.class +0 -0
  1593. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector.class +0 -0
  1594. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/PerformanceCore$Listener.class +0 -0
  1595. package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/PerformanceCore.class +0 -0
  1596. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerModule$Companion.class +0 -0
  1597. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerModule.class +0 -0
  1598. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerPackage.class +0 -0
  1599. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerSpec.class +0 -0
  1600. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/CpuCollector.class +0 -0
  1601. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/IncidentDetector.class +0 -0
  1602. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/MemoryCollector.class +0 -0
  1603. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/RenderCollector$frameCallback$1.class +0 -0
  1604. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/RenderCollector.class +0 -0
  1605. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/SamplerScheduler.class +0 -0
  1606. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/SamplerSchedulerKt.class +0 -0
  1607. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/ThreadCollector$WhenMappings.class +0 -0
  1608. package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/ThreadCollector.class +0 -0
  1609. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule$Companion.class +0 -0
  1610. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule$registerConnectivity$cb$1.class +0 -0
  1611. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule.class +0 -0
  1612. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkPackage.class +0 -0
  1613. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkSpec.class +0 -0
  1614. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/CaptureReason$Companion.class +0 -0
  1615. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/CaptureReason.class +0 -0
  1616. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureManager$startFrequencyTimer$1.class +0 -0
  1617. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureManager.class +0 -0
  1618. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$Companion.class +0 -0
  1619. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$FrameRequest.class +0 -0
  1620. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler.class +0 -0
  1621. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$Companion.class +0 -0
  1622. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$SettleWatch.class +0 -0
  1623. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$StabilityWatch.class +0 -0
  1624. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector.class +0 -0
  1625. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/CaptureMode$Companion.class +0 -0
  1626. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/CaptureMode.class +0 -0
  1627. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayConfig$Companion.class +0 -0
  1628. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayConfig.class +0 -0
  1629. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayLogger.class +0 -0
  1630. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ScreenshotQuality$Companion.class +0 -0
  1631. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ScreenshotQuality.class +0 -0
  1632. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/SessionIdGenerator.class +0 -0
  1633. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/SessionState.class +0 -0
  1634. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/ReplayFrame.class +0 -0
  1635. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/ReplaySession.class +0 -0
  1636. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/TimelineEvent.class +0 -0
  1637. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox$Companion.class +0 -0
  1638. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox$enforceLimits$lambda$37$$inlined$sortedBy$1.class +0 -0
  1639. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox.class +0 -0
  1640. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$NetworkError.class +0 -0
  1641. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$Response.class +0 -0
  1642. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult.class +0 -0
  1643. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$Outcome.class +0 -0
  1644. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$WhenMappings.class +0 -0
  1645. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader.class +0 -0
  1646. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.class +0 -0
  1647. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/session/SessionManager.class +0 -0
  1648. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/storage/ReplayStorage$enforceStorageLimit$$inlined$sortedBy$1.class +0 -0
  1649. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/storage/ReplayStorage.class +0 -0
  1650. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/timeline/TimelineCollector.class +0 -0
  1651. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/DialogTouchObserver$start$runnable$1.class +0 -0
  1652. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/DialogTouchObserver.class +0 -0
  1653. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/InteractionTracker.class +0 -0
  1654. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/NativeTouchInterceptor.class +0 -0
  1655. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/ScreenTracker.class +0 -0
  1656. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport$UploadResult.class +0 -0
  1657. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport$upload$2.class +0 -0
  1658. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport.class +0 -0
  1659. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder$Companion.class +0 -0
  1660. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder$Result.class +0 -0
  1661. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder.class +0 -0
  1662. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber$TranscriptResult.class +0 -0
  1663. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber$listener$1.class +0 -0
  1664. package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber.class +0 -0
  1665. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ScaleBunPackage$Companion.class +0 -0
  1666. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ScaleBunPackage.class +0 -0
  1667. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashModule$Companion.class +0 -0
  1668. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashModule.class +0 -0
  1669. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashPackage.class +0 -0
  1670. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashSpec.class +0 -0
  1671. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$Companion.class +0 -0
  1672. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$WindowInsetEdges.class +0 -0
  1673. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$shakeListener$1.class +0 -0
  1674. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule.class +0 -0
  1675. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngagePackage.class +0 -0
  1676. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunNotificationPresenter.class +0 -0
  1677. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaModule$Companion.class +0 -0
  1678. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaModule.class +0 -0
  1679. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaSpec.class +0 -0
  1680. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/SlotManager$Companion.class +0 -0
  1681. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/SlotManager.class +0 -0
  1682. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule$Companion.class +0 -0
  1683. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule$coreListener$1.class +0 -0
  1684. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule.class +0 -0
  1685. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceSpec.class +0 -0
  1686. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$Companion.class +0 -0
  1687. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$getInstallReferrer$1.class +0 -0
  1688. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.class +0 -0
  1689. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.class +0 -0
  1690. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageModule$Companion.class +0 -0
  1691. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageModule.class +0 -0
  1692. package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageSpec.class +0 -0
  1693. package/android/build/tmp/kotlin-classes/debug/com/scalebun/storage/KvFileStore$Companion.class +0 -0
  1694. package/android/build/tmp/kotlin-classes/debug/com/scalebun/storage/KvFileStore.class +0 -0
@@ -1,1479 +1,1630 @@
1
- /**
2
- * ScaleBun SDK — Public Facade
3
- *
4
- * Single clean entry point for the ScaleBun SDK.
5
- * Delegates initialization to SDKBootstrapper, which handles config validation,
6
- * core service setup, handshake, and feature registration via FeatureRegistry.
7
- *
8
- * Config model preserved exactly: projectId, publishableKey, apiBaseUrl.
9
- * Features are default-on with explicit opt-out via `features: { replay: false }`.
10
- */
11
-
12
- import { noThrow, safeAsync } from '../core/lifecycle/crashSafe';
13
- import { logger } from '../core/logger/internalLogger';
14
- import { createEnvelope } from '../pipeline/envelope/envelope';
15
- import { generateEventId } from '../features/replay/core/ids/sessionId';
16
- import { PersistentQueue } from '../pipeline/queue/persistentQueue';
17
- import { MemoryBackend, createStorageBackend } from '../storage/StorageBackend';
18
- import { HttpClient } from '../transport/http/httpClient';
19
- import { getDeviceId } from '../core/id/deviceId';
20
- import { coreContainer } from '../core/di/container';
21
- import { flushQueue } from '../pipeline/queue/flushQueue';
22
- import {
23
- enableDebug as _enableDebug,
24
- disableDebug as _disableDebug,
25
- isDebugEnabled,
26
- addBreadcrumb as _addBreadcrumb,
27
- ping as _ping,
28
- _getStream,
29
- _setFlushFn,
30
- _getSessionManager,
31
- _getAutoScreenDetector,
32
- getPerformanceFeature as _getPerformanceFeature,
33
- requestExport as _requestExport,
34
- buildDebugConfigFromInitConfig,
35
- applyFeatureGatesToDebugConfig,
36
- sendDebugMetric,
37
- } from '../debug';
38
- import type { DebugConfig } from '../debug';
39
- import { ReplaySdk } from '../features/replay/public/api';
40
- import type {
41
- ReplayUser,
42
- ReplayBreadcrumb,
43
- ReplayPrivacyOptions,
44
- } from '../features/replay/public/types';
45
- import { SDKBootstrapper } from '../bootstrap/SDKBootstrapper';
46
- import { EventTracker } from '../analytics/EventTracker';
47
- import {
48
- emitAutomaticEvent,
49
- type AutomaticEventName,
50
- } from '../analytics/automaticEvents';
51
- import { resolveEventLane } from '../analytics/eventLane';
52
- import { ConfigManager } from '../config/ConfigManager';
53
- import { SDK_VERSION } from '../core/constants/version';
54
- import { EngageTransport, type SubmitStage } from '../features/engage/EngageTransport';
55
- import {
56
- getNativePushToken,
57
- subscribeNativePushTokenRefresh,
58
- } from '../features/engage/engagePushTokenBridge';
59
- import { requestNativeStoreReview } from '../features/engage/engageStoreReviewBridge';
60
- import { PushManager } from '../push/PushManager';
61
- import type { EnablePushOptions, EnablePushResult, PushNotification } from '../push/types';
62
- import { ENGAGE_SCHEMA_VERSION } from '../features/engage/engageTypes';
63
- import { EngageThrottleStore } from '../features/engage/engageThrottle';
64
- import { EngageTestSeenStore } from '../features/engage/engageTestSeenStore';
65
- import { engageSignals } from '../features/engage/engageSignals';
66
- import type {
67
- EngageAttachmentDraft,
68
- EngageConfigContext,
69
- EngageConfigResponse,
70
- EngageEventInput,
71
- EngageResponseInput,
72
- RatingFunnelEventInput,
73
- SurveyImpressionInput,
74
- } from '../features/engage/engageTypes';
75
- import { PerformanceFeature } from '../features/performance/PerformanceFeature';
76
- import { SessionManager } from '../features/session/SessionManager';
77
- import type { JourneyEventType } from '../features/session/sessionTypes';
78
- import { getCrashReporter } from '../features/crash/CrashReporter';
79
- import { triggerNativeCrash } from '../features/crash/nativeCrashBridge';
80
- import { updateSkanConversionValue, isSkanAvailable, type SkanCoarseValue } from '../features/skan/skanBridge';
81
- import { SkanConversionManager } from '../features/skan/skanConversionManager';
82
- import {
83
- isInstallReferrerAvailable,
84
- getInstallReferrer,
85
- captureInstallReferrerOnce,
86
- type InstallReferrerSink,
87
- } from '../features/install-referrer/installReferrer';
88
- import type {
89
- ScaleBunInitConfig,
90
- ScaleBunUser,
91
- ScaleBunFeatures,
92
- SimplifiedInitConfig,
93
- DebugConnectionConfig,
94
- PrivacyConfig,
95
- BrandingConfig,
96
- ExportPresetName,
97
- SimplifiedExportOptions,
98
- ExportResult,
99
- } from './types';
100
-
101
- class ScaleBunFacade {
102
- private initialized = false;
103
- /** In-flight init promise — guards against a second init() racing before the first resolves. */
104
- private _initInFlight: Promise<void> | null = null;
105
- private bootstrapper = new SDKBootstrapper();
106
- private _features: ScaleBunFeatures = {};
107
- private _performanceFeature: PerformanceFeature | null = null;
108
- private _privacyConfig: PrivacyConfig = {};
109
- private _brandingConfig: BrandingConfig = {};
110
- private _clientKey: string | undefined = undefined;
111
- private _apiBaseUrl: string | undefined = undefined;
112
- private _engageTransport: EngageTransport | null = null;
113
- private _engageTokenUnsubscribe: (() => void) | null = null;
114
- private _pushManager: PushManager | null = null;
115
- /** Phase 1 envelope event-tracking lane (POST /v1/batch). Null until init with appId. */
116
- private _eventTracker: EventTracker | null = null;
117
- /** External identity last supplied through identify(); used by config targeting. */
118
- private _identifiedUserId: string | null = null;
119
- /** Identity supplied while async initialization is still in flight. */
120
- private _pendingIdentity: {
121
- userId: string;
122
- traits?: Record<string, any>;
123
- } | null = null;
124
- private _configManager: ConfigManager | null = null;
125
- /** Signature of the last identity POSTed to the ingestion identify endpoint, to skip redundant re-sends. */
126
- private _lastIngestionIdentityKey: string | null = null;
127
- /** Phase 3: auto-applies SKAN conversion values from the server schema (iOS only). */
128
- private _skanManager: SkanConversionManager | null = null;
129
-
130
- /**
131
- * Pre-init memory buffer.
132
- * Events tracked before init() completes are buffered here,
133
- * then drained into the real persistent queue post-init.
134
- */
135
- private _preInitBuffer: PersistentQueue = new PersistentQueue(new MemoryBackend(), {
136
- enabled: false,
137
- maxEntries: 500,
138
- maxBytes: 1_048_576, // 1 MB
139
- redactBeforeWrite: false, // No redaction for memory-only buffer
140
- });
141
-
142
- /** Resolve the active queue (DI container or pre-init buffer) */
143
- private _getQueue(): PersistentQueue {
144
- if (this.initialized) {
145
- try {
146
- return coreContainer.get<PersistentQueue>('PersistentQueue');
147
- } catch {
148
- // Container not ready yet — shouldn't happen post-init
149
- }
150
- }
151
- return this._preInitBuffer;
152
- }
153
-
154
- // ─── Initialization ─────────────────────────────────────────────────
155
-
156
- /**
157
- * Initialize the ScaleBun SDK.
158
- *
159
- * **Simplified usage** (recommended):
160
- * ```ts
161
- * await ScaleBun.init({
162
- * projectId: 'proj_xxx',
163
- * publishableKey: 'pk_xxx',
164
- * apiBaseUrl: 'https://api.scalebun.com',
165
- * debug: true,
166
- * });
167
- * ```
168
- *
169
- * Accepts both `SimplifiedInitConfig` (new) and `ScaleBunInitConfig` (legacy).
170
- * If `debug` key is present, auto-connects to the desktop debugger.
171
- */
172
- public async init(rawConfig: SimplifiedInitConfig | ScaleBunInitConfig | any) {
173
- if (this.initialized) return;
174
- // Coalesce concurrent init() calls: a second call before the first resolves
175
- // must not run a second bootstrap (which would double-register lifecycle
176
- // listeners and repeat the backend handshake).
177
- if (this._initInFlight) return this._initInFlight;
178
- this._initInFlight = safeAsync(async () => {
179
- if (this.initialized) return;
180
-
181
- // Store feature flags (all default true)
182
- this._features = rawConfig?.features ?? {};
183
- if (rawConfig?.sessionReplay !== undefined) {
184
- this._features.replay = rawConfig.sessionReplay;
185
- }
186
-
187
- // Store privacy config if provided
188
- if (rawConfig?.privacy) {
189
- this._privacyConfig = rawConfig.privacy;
190
- }
191
-
192
- // Phase 3 (entitlements) — COST suppression: don't even register a
193
- // collector the org isn't entitled to (no traffic → no server cost).
194
- // Read from the cached /config (sync); first run has no cache → fail-open
195
- // (all entitled), and the server still rejects a closed feature anyway.
196
- const ent = ConfigManager.readCachedEntitlements();
197
- const effectiveFeatures: ScaleBunFeatures = {
198
- ...this._features,
199
- replay: this._features.replay !== false && ent.replay !== false,
200
- network: this._features.network !== false && ent.networkMonitoring !== false,
201
- crashes: this._features.crashes !== false && ent.crashReporting !== false,
202
- performance: this._features.performance !== false && ent.performanceMonitoring !== false,
203
- };
204
-
205
- // Backend bootstrap (non-blocking for debug connection)
206
- // If the backend is unreachable, the debug WebSocket should still connect.
207
- try {
208
- const result = await this.bootstrapper.bootstrap(
209
- rawConfig,
210
- (name, payload) => this.track(name, payload),
211
- () => this.flush() as Promise<void>,
212
- effectiveFeatures,
213
- );
214
-
215
- if (result) {
216
- this.initialized = true;
217
- this._clientKey = result.config.clientKey;
218
- this._apiBaseUrl = result.config.apiBaseUrl;
219
-
220
- // Phase 1 envelope tracking lane. Enabled when an appId is supplied
221
- // (and not explicitly disabled). Runs alongside the replay lane.
222
- this._maybeStartEventTracker(rawConfig);
223
- if (this._pendingIdentity) {
224
- const pending = this._pendingIdentity;
225
- this._pendingIdentity = null;
226
- this.identify(pending.userId, pending.traits);
227
- }
228
-
229
- // Drain pre-init buffer into the real persistent queue
230
- const realQueue = coreContainer.get<PersistentQueue>('PersistentQueue');
231
- const buffered = this._preInitBuffer.popBatch(this._preInitBuffer.length());
232
- if (buffered.length > 0) {
233
- logger.debug(`[ScaleBun] Draining ${buffered.length} pre-init events into persistent queue`);
234
- for (const envelope of buffered) {
235
- realQueue.add(envelope);
236
- }
237
- }
238
-
239
- // Grab a reference to the PerformanceFeature for the public API
240
- const perfFeature = result.featureRegistry.get('performance');
241
- if (perfFeature && perfFeature instanceof PerformanceFeature) {
242
- this._performanceFeature = perfFeature;
243
- }
244
- }
245
- } catch (bootstrapErr: any) {
246
- logger.warn('[ScaleBun] Backend bootstrap failed (non-blocking):', bootstrapErr?.message);
247
- // Continue — debug connection is independent of backend API
248
- }
249
-
250
- // Auto debug connection from init config — runs regardless of backend status
251
- const debugConfig = (rawConfig?.desktopDebug ?? rawConfig?.debug) as DebugConnectionConfig | undefined;
252
- if (debugConfig) {
253
- this._autoEnableDebug(debugConfig);
254
- }
255
- });
256
- try {
257
- return await this._initInFlight;
258
- } finally {
259
- this._initInFlight = null;
260
- }
261
- }
262
-
263
- private _autoEnableDebug(debugConfig: DebugConnectionConfig): void {
264
- try {
265
- const dbgConfig = buildDebugConfigFromInitConfig(debugConfig);
266
- if (!dbgConfig) return;
267
- (dbgConfig as any).__skipDeprecationWarning = true;
268
- this.enableDebug(dbgConfig);
269
- logger.info('[ScaleBun] Debug auto-connected via init({ debug }).');
270
- } catch (err: any) {
271
- logger.warn('[ScaleBun] Auto debug connection failed:', err?.message);
272
- }
273
- }
274
-
275
- /** Boot the Phase 1 envelope tracking lane if an appId is configured. */
276
- private _maybeStartEventTracker(rawConfig: any): void {
277
- try {
278
- const appId = rawConfig?.appId;
279
- const enabled = rawConfig?.eventTracking !== false;
280
- const clientKey = this._clientKey ?? rawConfig?.clientKey;
281
- const apiBaseUrl = this._apiBaseUrl ?? rawConfig?.apiBaseUrl;
282
- if (!enabled || !appId || !clientKey || !apiBaseUrl) {
283
- if (enabled && !appId) {
284
- logger.info('[ScaleBun] Envelope event tracking disabled — no appId in init config.');
285
- }
286
- return;
287
- }
288
- // Phase 3: auto-apply SKAdNetwork conversion values from the server-side
289
- // CV schema (iOS only; no-op elsewhere). Created BEFORE the tracker so the
290
- // onEvent hook is live for the very first event (first_open).
291
- if (isSkanAvailable()) {
292
- this._skanManager = new SkanConversionManager({ apiBaseUrl, clientKey });
293
- this._skanManager.refreshSchema().catch(() => {});
294
- }
295
- this._eventTracker = new EventTracker({
296
- appId,
297
- clientKey,
298
- apiBaseUrl,
299
- platform: rawConfig?.platform ?? 'react_native',
300
- appVersion: rawConfig?.appVersion,
301
- osVersion: rawConfig?.osVersion,
302
- autoLifecycleEvents: rawConfig?.autoLifecycleEvents !== false,
303
- // Backward-compatible opt-in: existing init-only integrations do
304
- // not begin uploading the new automatic collector stream merely
305
- // because they upgraded the package. ScaleBunProvider sets this
306
- // to true unless the integrator explicitly disables it.
307
- automaticEventTracking:
308
- rawConfig?.automaticEventTracking === true,
309
- flushIntervalMs: rawConfig?.flushIntervalMs,
310
- context: rawConfig?.context,
311
- // Use the same foreground id as replay/journey capture. The
312
- // callback is resolved per event because the session subsystem
313
- // may start after this tracker is constructed.
314
- sessionIdProvider: () => {
315
- const manager = SessionManager.getExistingInstance();
316
- return manager?.currentSessionId
317
- ?? manager?.getBackendTransport()?.analyticsSessionId
318
- ?? null;
319
- },
320
- // Feed every tracked event to the SKAN CV manager (iOS; no-op otherwise).
321
- onEvent: (eventName, revenue) => this._skanManager?.onEvent(eventName, revenue),
322
- });
323
- this._eventTracker.start();
324
- logger.info('[ScaleBun] Envelope event tracking started → /v1/batch.');
325
-
326
- // Android: capture the Play Install Referrer once per install → feeds the
327
- // deterministic click_id path + a one-off install_referrer event (UTM/gclid).
328
- // Fire-and-forget; no-op off Android.
329
- this._captureInstallReferrer(this._eventTracker);
330
-
331
- // Phase 4: runtime config (flags / remote config / experiments / rollouts).
332
- // Resolves locally; exposure + stamps flow through the event lane above.
333
- const tracker = this._eventTracker;
334
- this._configManager = new ConfigManager({
335
- apiBaseUrl,
336
- clientKey,
337
- installationId: tracker.ids.installationId,
338
- emitExposure: (experiment, variant) => tracker.track('experiment_exposure', { experiment, variant }),
339
- stamp: (key, value) => tracker.stamp(key, value),
340
- });
341
- this._configManager.refresh().catch(() => {});
342
- } catch (err: any) {
343
- logger.warn('[ScaleBun] Failed to start envelope event tracking:', err?.message);
344
- }
345
- }
346
-
347
- /**
348
- * Android-only: read the Play Install Referrer once per install and route it into
349
- * attribution. `scalebun_click_id` the deterministic click path; the full
350
- * referrer (utm_source/gclid/…) rides on a one-off `install_referrer` event. A
351
- * `null` fetch (Play unavailable/transient) is not marked captured, so a later
352
- * launch retries while Play still has the referrer. Never throws.
353
- */
354
- private _captureInstallReferrer(tracker: EventTracker): void {
355
- try {
356
- if (!isInstallReferrerAvailable()) return;
357
- const storage = createStorageBackend();
358
- const KEY = 'scalebun_install_referrer_done';
359
- const sink: InstallReferrerSink = {
360
- alreadyCaptured: () => { try { return storage.get(KEY) === '1'; } catch { return false; } },
361
- markCaptured: () => { try { storage.set(KEY, '1'); } catch { /* no-throw */ } },
362
- setClickId: (id) => tracker.setAttributionClickId(id),
363
- emit: (name, props) => tracker.track(name, props as Record<string, any>),
364
- fetch: () => getInstallReferrer(),
365
- };
366
- void captureInstallReferrerOnce(sink);
367
- } catch (err: any) {
368
- logger.warn('[ScaleBun] Install Referrer capture failed:', err?.message);
369
- }
370
- }
371
-
372
- /**
373
- * Phase 1 envelope event tracking API (POST /v1/batch).
374
- * Methods are no-ops (never throw) until init() is called with an `appId`.
375
- */
376
- public get events() {
377
- const tracker = this._eventTracker;
378
- return {
379
- track: (eventName: string, properties?: Record<string, any>) => tracker?.track(eventName, properties),
380
- identify: (userId: string, traits?: Record<string, any>) => tracker?.identify(userId, traits),
381
- trackPurchase: (input: { revenue: number; currency: string; transactionId: string; [k: string]: any }) =>
382
- tracker?.trackPurchase(input),
383
- setIdentifiers: (ids: { idfa?: string; gaid?: string; idfv?: string }) => tracker?.setIdentifiers(ids),
384
- // Phase 2: record a deferred deep-link click token for deterministic install attribution.
385
- setAttributionClickId: (clickId: string) => tracker?.setAttributionClickId(clickId),
386
- flush: () => tracker?.flush() ?? Promise.resolve(),
387
- newSession: () => tracker?.newSession(),
388
- ids: () => tracker?.ids ?? null,
389
- // Phase 3: update the SKAdNetwork conversion value (iOS only; no-op elsewhere).
390
- updateSkanConversionValue: (value: number, coarseValue?: SkanCoarseValue, lockWindow?: boolean) =>
391
- updateSkanConversionValue(value, coarseValue, lockWindow),
392
- };
393
- }
394
-
395
- /**
396
- * Phase 4: runtime config delivered via GET /v1/config. All resolution is local
397
- * and non-throwing; values default sensibly until init() runs / config is fetched.
398
- *
399
- * ScaleBun.config.get('max_items', 10)
400
- * ScaleBun.flags.isEnabled('new_checkout')
401
- * ScaleBun.rollouts.isOn('beta_paywall')
402
- * ScaleBun.experiments.variant('checkout_cta') // 'control' | 'treatment' | null
403
- */
404
- public get config() {
405
- const cm = this._configManager;
406
- return {
407
- get: <T = any>(key: string, fallback: T): T => (cm ? cm.get(key, fallback) : fallback),
408
- refresh: () => cm?.refresh() ?? Promise.resolve(),
409
- };
410
- }
411
-
412
- public get flags() {
413
- const cm = this._configManager;
414
- return { isEnabled: (key: string) => cm?.isEnabled(key) ?? false };
415
- }
416
-
417
- public get rollouts() {
418
- const cm = this._configManager;
419
- return { isOn: (key: string) => cm?.rolloutIsOn(key) ?? false };
420
- }
421
-
422
- public get experiments() {
423
- const cm = this._configManager;
424
- return { variant: (key: string): string | null => cm?.variant(key) ?? null };
425
- }
426
-
427
- /** Convenience: emit a Phase 1 purchase event (revenue + currency + transaction_id). */
428
- public trackPurchase(input: { revenue: number; currency: string; transactionId: string; [k: string]: any }): void {
429
- noThrow(() => this._eventTracker?.trackPurchase(input));
430
- }
431
-
432
- /**
433
- * Phase 3: set the SKAdNetwork fine conversion value (0–63), optionally with a
434
- * SKAN 4.0 coarse value and window-lock. iOS only — a no-op on Android / Expo Go.
435
- */
436
- public updateSkanConversionValue(value: number, coarseValue?: SkanCoarseValue, lockWindow?: boolean): void {
437
- noThrow(() => { void updateSkanConversionValue(value, coarseValue, lockWindow); });
438
- }
439
-
440
- // ─── Feature Flags ──────────────────────────────────────────────────
441
-
442
- /** Get the current feature flags (consumed by enableDebug) */
443
- public getFeatureFlags(): ScaleBunFeatures {
444
- return this._features;
445
- }
446
-
447
- // ─── Identity ───────────────────────────────────────────────────────
448
-
449
- /** Identify a user by ID and optional traits */
450
- public identify(userId: string, traits?: Record<string, any>) {
451
- return noThrow(() => {
452
- this._identifiedUserId = userId;
453
- if (!this.initialized) {
454
- this._pendingIdentity = { userId, traits };
455
- return;
456
- }
457
- this._pendingIdentity = null;
458
- // Forward to the Phase 1 envelope lane (sets user_id for subsequent events).
459
- this._eventTracker?.identify(userId, traits);
460
- this.track('$identify', { id: userId, ...traits });
461
- const sessionId = SessionManager.getExistingInstance()?.currentSessionId;
462
- if (this._clientKey && sessionId) {
463
- // Skip the network POST when the same identity was already sent for this
464
- // session (repeat identify() with identical traits is a no-op upsert).
465
- const identityKey = `${sessionId}|${userId}|${JSON.stringify(traits ?? {})}`;
466
- if (identityKey !== this._lastIngestionIdentityKey) {
467
- this._lastIngestionIdentityKey = identityKey;
468
- const user: ScaleBunUser = {
469
- id: userId,
470
- name: traits?.name,
471
- email: traits?.email,
472
- properties: traits,
473
- };
474
- this._callIngestionIdentify(sessionId, user).catch(() => {
475
- // Re-arm on failure so a later retry is not suppressed.
476
- this._lastIngestionIdentityKey = null;
477
- });
478
- }
479
- }
480
- });
481
- }
482
-
483
- /**
484
- * Stable public alias for {@link identify}. Part of the minimal public push
485
- * API surface (ScaleBun.init / identifyUser / enablePush) that stays
486
- * identical across RN versions and future platforms.
487
- */
488
- public identifyUser(userId: string, traits?: Record<string, any>) {
489
- return this.identify(userId, traits);
490
- }
491
-
492
- /** POST user identity to the SaaS ingestion identify endpoint */
493
- private async _callIngestionIdentify(sessionId: string, user: ScaleBunUser): Promise<void> {
494
- if (!this._clientKey || !this._apiBaseUrl) return;
495
- const url = `${this._apiBaseUrl}/ingestion/sessions/${sessionId}/identify`;
496
- try {
497
- await fetch(url, {
498
- method: 'POST',
499
- headers: {
500
- 'Content-Type': 'application/json',
501
- 'x-scalebun-client-key': this._clientKey,
502
- },
503
- body: JSON.stringify({
504
- userId: user.id,
505
- username: user.name,
506
- email: user.email,
507
- properties: user.properties,
508
- }),
509
- });
510
- } catch (err: any) {
511
- logger.warn('[ScaleBun] ingestion identify failed:', err?.message);
512
- }
513
- }
514
-
515
- /** Set user identity (for session context) */
516
- public setUser(user: ScaleBunUser) {
517
- return noThrow(() => {
518
- this.identify(user.id, {
519
- name: user.name,
520
- email: user.email,
521
- ...user.attributes,
522
- });
523
- });
524
- }
525
-
526
- /** Clear user identity */
527
- public clearUser() {
528
- return noThrow(() => {
529
- this._identifiedUserId = null;
530
- this._pendingIdentity = null;
531
- if (!this.initialized) return;
532
- this._eventTracker?.clearIdentity();
533
- this.track('$clear_user', {});
534
- });
535
- }
536
-
537
- /**
538
- * Submit in-app rating (1-5 stars).
539
- * Attaches to current session when available; otherwise sends standalone.
540
- * Never throws.
541
- */
542
- public submitRating(input: {
543
- rating: number;
544
- comment?: string;
545
- source?: 'in_app' | 'prompt' | 'manual';
546
- /** [ADDITIVE] client-generated UUID for app-rating idempotency (contract §1.4, D8). */
547
- clientRatingId?: string;
548
- }) {
549
- return safeAsync(async () => {
550
- if (!this._clientKey || !this._apiBaseUrl) return { ok: false, reason: 'sdk_not_configured' as const };
551
- const rating = Math.round(Number(input?.rating));
552
- if (!Number.isFinite(rating) || rating < 1 || rating > 5) {
553
- return { ok: false, reason: 'invalid_rating' as const };
554
- }
555
-
556
- const sessionId = this.getActiveSessionId();
557
- const meta = SessionManager.getExistingInstance()?.currentSessionMetadata;
558
- const path = sessionId
559
- ? `/ingestion/sessions/${sessionId}/rating`
560
- : `/ingestion/ratings`;
561
- const url = `${this._apiBaseUrl}${path}`;
562
-
563
- try {
564
- const res = await fetch(url, {
565
- method: 'POST',
566
- headers: {
567
- 'Content-Type': 'application/json',
568
- 'x-scalebun-client-key': this._clientKey,
569
- },
570
- body: JSON.stringify({
571
- rating,
572
- comment: input.comment,
573
- source: input.source ?? 'in_app',
574
- appVersion: meta?.appVersion,
575
- platform: meta?.platform,
576
- // [ADDITIVE] idempotency + versioning (contract §1.4); omitted when unset.
577
- ...(input.clientRatingId ? { clientRatingId: input.clientRatingId } : {}),
578
- schemaVersion: ENGAGE_SCHEMA_VERSION,
579
- }),
580
- });
581
- if (!res.ok) {
582
- logger.warn('[ScaleBun] submitRating non-ok', res.status);
583
- return { ok: false, reason: 'http_error' as const, status: res.status };
584
- }
585
- return { ok: true as const };
586
- } catch (err: any) {
587
- logger.warn('[ScaleBun] submitRating failed:', err?.message);
588
- return { ok: false, reason: 'network_error' as const };
589
- }
590
- });
591
- }
592
-
593
- private getActiveSessionId(): string | null {
594
- try {
595
- return SessionManager.getExistingInstance()?.currentSessionId ?? null;
596
- } catch {}
597
- return null;
598
- }
599
-
600
- // ─── Engage ─────────────────────────────────────────────────────────
601
-
602
- /**
603
- * Lazily resolve the Engage transport. Requires a configured SaaS clientKey +
604
- * apiBaseUrl (same gate as the rating/ingestion lanes); returns null otherwise.
605
- * The transport mirrors the existing BackendSessionAdapter outbox: upload lanes
606
- * batch-flush and re-queue on failure, the config GET is a direct fetch.
607
- */
608
- private _getEngageTransport(): EngageTransport | null {
609
- if (!this._clientKey || !this._apiBaseUrl) return null;
610
- if (!this._engageTransport) {
611
- this._engageTransport = new EngageTransport({
612
- endpoint: this._apiBaseUrl,
613
- clientKey: this._clientKey,
614
- });
615
- }
616
- return this._engageTransport;
617
- }
618
-
619
- /**
620
- * Engage surface namespace (foundation: transport + native push-token plumbing).
621
- *
622
- * Rendering of campaigns/in-app messages is a SHARED cross-platform JS overlay
623
- * (D4) built in a later stage. This namespace exposes only the foundation:
624
- * versioned config fetch, idempotent response/event upload (via the existing
625
- * outbox), and native push-token registration on both platforms.
626
- */
627
- public engage = {
628
- /** Current external identity, forwarded by the provider for segment targeting. */
629
- getIdentifiedUserId: (): string | undefined =>
630
- this._identifiedUserId ?? undefined,
631
-
632
- /**
633
- * Fetch the versioned Engage config (campaigns + in-app messages).
634
- *
635
- * slice-agent: the shared cross-platform JS overlay renderer consumes this
636
- * payload (EngageConfigResponse.campaigns / .inAppMessages) in a later stage.
637
- */
638
- fetchConfig: async (
639
- context?: EngageConfigContext,
640
- ): Promise<EngageConfigResponse | null> => {
641
- const transport = this._getEngageTransport();
642
- if (!transport) return null;
643
- const [engageConfig, coachConfig] = await Promise.all([
644
- transport.fetchEngageConfig(context),
645
- transport.fetchCoachConfig(),
646
- ]);
647
- if (!engageConfig && !coachConfig) return null;
648
- const coachMessages = (coachConfig?.tours ?? [])
649
- .filter((tour) => Array.isArray(tour.steps) && tour.steps.length > 0)
650
- .map((tour) => ({
651
- id: tour.id,
652
- layout: 'tooltip' as const,
653
- trigger: 'app_open',
654
- variantKey: 'coachmark_spotlight',
655
- revision: String(tour.version),
656
- preview: tour.preview === true,
657
- spec: {
658
- title: tour.name,
659
- body: tour.steps[0]?.body ?? tour.name,
660
- anchorKey: tour.steps[0]?.anchorKey,
661
- ext: {
662
- coachTourId: tour.id,
663
- coachTourVersion: tour.version,
664
- steps: tour.steps,
665
- },
666
- },
667
- }));
668
- return {
669
- configVersion: engageConfig?.configVersion ?? 1,
670
- serverTime: engageConfig?.serverTime ?? new Date().toISOString(),
671
- campaigns: engageConfig?.campaigns ?? [],
672
- inAppMessages: [...(engageConfig?.inAppMessages ?? []), ...coachMessages],
673
- };
674
- },
675
-
676
- /** Internal bridge used by the shared renderer to feed standalone tour analytics. */
677
- trackCoachmarkEvent: (name: string, properties: Record<string, unknown>): void => {
678
- this.track(name, properties as Record<string, any>);
679
- },
680
-
681
- /**
682
- * DEBUG/DEV ONLY — clear the persisted in-app/campaign frequency-cap state
683
- * (every `scalebun_engage_throttle:*` key: impressions, showOnce/completed, cooldown).
684
- * Lets a tester see throttled/dismissed messages again WITHOUT uninstalling the
685
- * app. Does NOT change the device id (identity is preserved). Returns the number
686
- * of cleared entries. NOT a substitute for the real fix (revision-scoped state +
687
- * test-preview bypass already make normal Send Test work without this).
688
- */
689
- clearInAppMessageCache: (): number => {
690
- return noThrow(() => new EngageThrottleStore().clearAll() + new EngageTestSeenStore().clear()) ?? 0;
691
- },
692
-
693
- /**
694
- * DEBUG/DEV ONLY alias of {@link clearInAppMessageCache} with the broader name
695
- * used in docs. Resets all on-device in-app frequency/dismiss/impression state so
696
- * the next config poll can show messages again. Identity (device id) is untouched.
697
- */
698
- resetInAppState: (): number => {
699
- // Clears BOTH lanes: production frequency/dismiss/impression state (throttle
700
- // store) AND the one-shot test-seen store — so a dismissed test reappears after
701
- // a debug reset (the "block forever UNLESS debug reset" contract). Identity
702
- // (device id) is a separate key and stays untouched.
703
- return noThrow(() => new EngageThrottleStore().clearAll() + new EngageTestSeenStore().clear()) ?? 0;
704
- },
705
-
706
- /**
707
- * Force an immediate flush of queued in-app events. The provider calls this right
708
- * after a TEST preview's impression/dismiss ACK so the backend consumes the
709
- * one-shot preview row promptly a fast close→kill→reopen can't re-serve a
710
- * still-`delivered` test. Best-effort, never throws.
711
- */
712
- flushEvents: (): void => {
713
- noThrow(() => this._getEngageTransport()?.flushEventsNow());
714
- },
715
-
716
- /**
717
- * DEBUG/DEV ONLY force a fresh config fetch (deviceId in context) and return the
718
- * in-app messages the backend is serving THIS device right now, including any
719
- * queued test previews (`preview:true`). Use it to verify Send Test targeting/
720
- * delivery without rendering. Logs a one-line summary for the dev console.
721
- */
722
- debugFetchInAppMessages: async (
723
- context?: EngageConfigContext,
724
- ): Promise<EngageConfigResponse['inAppMessages']> => {
725
- const cfg = await (this._getEngageTransport()?.fetchEngageConfig(context) ?? Promise.resolve(null));
726
- const messages = cfg?.inAppMessages ?? [];
727
- const previews = messages.filter((m) => m.preview === true || m.isTest === true);
728
- logger.info(
729
- `[Engage] debugFetchInAppMessages → ${messages.length} message(s), ${previews.length} test preview(s)`,
730
- );
731
- return messages;
732
- },
733
-
734
- /** Upload a survey/NPS/feedback response (idempotent, rides the outbox). */
735
- submitResponse: (input: EngageResponseInput): void => {
736
- noThrow(() => this._getEngageTransport()?.uploadEngageResponse(input));
737
- },
738
-
739
- /**
740
- * [P3-e] Submit a response carrying native attachments (screenshot/voice).
741
- * Presigns + PUTs bytes direct to storage, then enqueues the response with
742
- * key-only metadata linked by responseId. Falls back to a plain response
743
- * (no media) when storage is disabled. Best-effort, never throws.
744
- */
745
- submitResponseWithAttachments: (
746
- input: EngageResponseInput,
747
- attachments: EngageAttachmentDraft[],
748
- ): void => {
749
- noThrow(() => {
750
- void this._getEngageTransport()?.submitResponseWithAttachments(input, attachments);
751
- });
752
- },
753
-
754
- /**
755
- * [Slice D5] CONFIRMED response submit for the in-prompt submitting→success→error
756
- * UI. UNLIKE submitResponse*, this AWAITS real server persistence (presign+PUT any
757
- * audio/screenshot bytes, then a direct response POST) and REJECTS on failure so the
758
- * caller can show a retryable error. Idempotent: pass the SAME `responseId` on retry
759
- * both response and attachments de-dupe server-side. Used by EVERY question type.
760
- */
761
- submitResponseConfirmed: (
762
- input: EngageResponseInput,
763
- attachments: EngageAttachmentDraft[],
764
- opts: { responseId: string; onStage?: (stage: SubmitStage) => void },
765
- ): Promise<void> => {
766
- const transport = this._getEngageTransport();
767
- if (!transport) return Promise.reject(new Error('sdk_not_configured'));
768
- return transport.submitResponseConfirmed(input, attachments, opts);
769
- },
770
-
771
- /** Upload an in-app impression/click/dismiss event (idempotent, rides the outbox). */
772
- trackEvent: (input: EngageEventInput): void => {
773
- noThrow(() => {
774
- const automaticName: Partial<Record<EngageEventInput['type'], AutomaticEventName>> = {
775
- impression: 'in_app_displayed',
776
- rendered: 'in_app_displayed',
777
- completion: 'in_app_completed',
778
- click: 'in_app_clicked',
779
- dismiss: 'in_app_dismissed',
780
- interaction: 'in_app_interaction',
781
- render_failed: 'in_app_render_failed',
782
- cta_open_failed: 'in_app_cta_open_failed',
783
- };
784
- const eventName = automaticName[input.type];
785
- if (eventName) {
786
- emitAutomaticEvent(eventName, {
787
- campaign_id: input.campaignId,
788
- variant_id: input.variantId,
789
- preview_id: input.previewId,
790
- is_test: input.isTest,
791
- source: input.source,
792
- interaction_type:
793
- typeof input.meta?.type === 'string'
794
- ? input.meta.type
795
- : undefined,
796
- });
797
- }
798
- this._getEngageTransport()?.uploadEngageEvent(input);
799
- });
800
- },
801
-
802
- /** Upload an idempotent survey shown/started funnel beacon. */
803
- trackSurveyImpression: (input: SurveyImpressionInput): void => {
804
- noThrow(() => this._getEngageTransport()?.uploadSurveyImpression(input));
805
- },
806
-
807
- /**
808
- * Emit a rating-funnel tracking event (ratings-rebuild CONTRACT §1.2). These
809
- * are dimensioned FACTS feeding the Overview funnel — NOT campaign responses
810
- * (D1) so they ride their own `/ingestion/rating-events` lane. Idempotent
811
- * (client `eventId`, D8). Best-effort, never throws.
812
- */
813
- emitRatingEvent: (input: RatingFunnelEventInput): void => {
814
- noThrow(() => {
815
- emitAutomaticEvent(input.type, {
816
- prompt_id: input.promptId,
817
- trigger_id: input.triggerId,
818
- variant_id: input.variantId,
819
- stars: input.stars,
820
- });
821
- this._getEngageTransport()?.uploadRatingEvent(input);
822
- });
823
- },
824
-
825
- /**
826
- * Trigger the native in-app review sheet (Play In-App Review on Android,
827
- * SKStoreReviewController on iOS) — the genuinely-native leg of the rating
828
- * funnel (D5). Resolves `true` ONLY when the OS flow ran/resolved after a
829
- * positive route, so the caller emits `store_redirect_clicked` solely on a
830
- * `true` result. Fail-soft: resolves `false` when native review is unavailable.
831
- */
832
- requestStoreReview: async (): Promise<boolean> => {
833
- return (await safeAsync(async () => requestNativeStoreReview())) ?? false;
834
- },
835
-
836
- /**
837
- * Submit a 1–5 app-store rating via the EXISTING app-rating lane (D1 keeps
838
- * ratings a distinct funnel — NOT submitResponse). Delegates to the
839
- * facade's `submitRating`, threading the renderer's `clientRatingId` for
840
- * idempotency (D8). Used by the RATING_PROMPT render branch.
841
- */
842
- submitRating: (input: {
843
- rating: number;
844
- comment?: string;
845
- source?: 'in_app' | 'prompt' | 'manual';
846
- clientRatingId?: string;
847
- }): void => {
848
- noThrow(() => {
849
- void this.submitRating(input);
850
- });
851
- },
852
-
853
- /**
854
- * Acquire the native push token (FCM/APNs) and register it for delivery.
855
- * Subscribes to native token-refresh (rotation) so the backend always holds
856
- * the live token. Fail-soft: no-op when native push is unavailable.
857
- */
858
- registerForPush: async (): Promise<void> => {
859
- return safeAsync(async () => {
860
- const transport = this._getEngageTransport();
861
- if (!transport) return;
862
-
863
- const initial = await getNativePushToken();
864
- if (initial) {
865
- transport.registerDeviceToken({
866
- pushToken: initial.token,
867
- platform: initial.platform,
868
- pushProvider: initial.platform === 'ios' ? 'apns' : 'fcm',
869
- });
870
- }
871
-
872
- // Avoid stacking listeners on repeated calls.
873
- this._engageTokenUnsubscribe?.();
874
- this._engageTokenUnsubscribe = subscribeNativePushTokenRefresh((refreshed) => {
875
- this._getEngageTransport()?.registerDeviceToken({
876
- pushToken: refreshed.token,
877
- platform: refreshed.platform,
878
- pushProvider: refreshed.platform === 'ios' ? 'apns' : 'fcm',
879
- });
880
- });
881
- }) as Promise<void>;
882
- },
883
- };
884
-
885
- // ─── Push Notifications ─────────────────────────────────────────────
886
-
887
- /**
888
- * Lazily build the PushManager. Backend token registration is injected and
889
- * routes through the existing Engage outbox (EngageTransport.registerDeviceToken),
890
- * so push reuses the SDK's single device-token lane rather than a parallel
891
- * fetch. Returns {ok:false} when the SDK isn't configured (clientKey absent).
892
- */
893
- private _getPushManager(): PushManager {
894
- if (!this._pushManager) {
895
- this._pushManager = new PushManager({
896
- registerToken: async (input) => {
897
- const transport = this._getEngageTransport();
898
- if (!transport) return { ok: false, reason: 'sdk_not_configured' as const };
899
- transport.registerDeviceToken({
900
- pushToken: input.pushToken,
901
- platform: input.platform,
902
- pushProvider: input.pushProvider,
903
- sdkVersion: SDK_VERSION,
904
- ...(this._eventTracker
905
- ? { installationId: this._eventTracker.getInstallationId() }
906
- : {}),
907
- });
908
- return { ok: true as const };
909
- },
910
- });
911
- }
912
- return this._pushManager;
913
- }
914
-
915
- /**
916
- * Enable push notifications with smart, version-aware adapter selection.
917
- *
918
- * Detects the RN version, architecture (legacy bridge vs New
919
- * Architecture/bridgeless), whether @react-native-firebase/messaging is
920
- * installed & compatible, and whether the ScaleBunEngage native token bridge is
921
- * linked, then picks the safest supported path automatically: RNFirebase
922
- * (full callbacks) → native ScaleBunEngage bridge (token-only fallback that works
923
- * under bridgeless regardless of RNFirebase version) → manual → noop.
924
- *
925
- * Requests OS permission, creates the Android channel, acquires the push
926
- * token, keeps it in sync on refresh, registers it with the ScaleBun backend
927
- * (via the Engage outbox), and wires foreground/opened callbacks.
928
- *
929
- * Fails clearly (ok:false + actionable reason) when no usable provider
930
- * exists — never silently breaks. Never throws.
931
- *
932
- * ```ts
933
- * await ScaleBun.enablePush({
934
- * onForegroundNotification: (n) => {},
935
- * onNotificationOpened: (n) => {},
936
- * });
937
- * ```
938
- */
939
- public enablePush(options?: EnablePushOptions): Promise<EnablePushResult> {
940
- return this._getPushManager().enable(options ?? {});
941
- }
942
-
943
- /**
944
- * Subscribe to notifications received while the app is foregrounded. Thin,
945
- * platform-agnostic alias for `enablePush({ onForegroundNotification })`; use it
946
- * to attach a handler after enablePush. Returns an unsubscribe function. Inert
947
- * until push is enabled. (iOS direct APNs delivers these via the native
948
- * UNUserNotificationCenter surface.)
949
- */
950
- public onForegroundNotification(cb: (notification: PushNotification) => void): () => void {
951
- return noThrow(() => this._getPushManager().onForegroundNotification(cb)) ?? (() => {});
952
- }
953
-
954
- /**
955
- * Subscribe to the user tapping a notification (open / deep-link), including the
956
- * cold-start notification that launched the app. Thin alias for
957
- * `enablePush({ onNotificationOpened })`. Returns an unsubscribe function. The
958
- * event shape ({ data, title?, body? }) matches across Android and iOS.
959
- */
960
- public onNotificationOpened(cb: (notification: PushNotification) => void): () => void {
961
- return noThrow(() => this._getPushManager().onNotificationOpened(cb)) ?? (() => {});
962
- }
963
-
964
- /**
965
- * Push control namespace. Most apps only need {@link enablePush}; these are
966
- * for the manual/custom provider path and diagnostics.
967
- */
968
- public push = {
969
- /** Inject/rotate a token (manual provider) — syncs to the backend. */
970
- setToken: (token: string): void => {
971
- noThrow(() => this._getPushManager().setToken(token));
972
- },
973
- /** Current push token, if acquired. */
974
- getToken: (): string | null => {
975
- return noThrow(() => this._getPushManager().getToken()) ?? null;
976
- },
977
- /** Deliver a foreground notification to registered callbacks (manual provider). */
978
- emitForeground: (message: PushNotification): void => {
979
- noThrow(() => this._getPushManager().emitForeground(message));
980
- },
981
- /** Deliver a notification-open event to registered callbacks (manual provider). */
982
- emitNotificationOpened: (message: PushNotification): void => {
983
- noThrow(() => this._getPushManager().emitNotificationOpened(message));
984
- },
985
- /** Current push status: selected adapter, usability, reason, token. */
986
- status: () => this._getPushManager().status(),
987
- /** Tear down all push listeners. */
988
- teardown: (): void => {
989
- noThrow(() => this._pushManager?.teardown());
990
- },
991
- };
992
-
993
- // ─── Event Tracking ─────────────────────────────────────────────────
994
-
995
- /**
996
- * Report the outcome of an OS permission prompt.
997
- *
998
- * Permission results were state the SDK held privately and never an event, so the core mobile
999
- * growth loop — "reached the paywall → was prompted → granted" — could not be expressed as a funnel.
1000
- *
1001
- * Notification permission is captured AUTOMATICALLY (the SDK runs that prompt itself, see
1002
- * PushManager). Every other permission belongs to the host app: the SDK never sees a camera or
1003
- * location request, so guessing at one would be inventing data. Call this right after the prompt
1004
- * resolves:
1005
- *
1006
- * ```ts
1007
- * const { status } = await Location.requestForegroundPermissionsAsync();
1008
- * ScaleBun.trackPermission('location', status === 'granted' ? 'granted' : 'denied');
1009
- * ```
1010
- *
1011
- * `permission` is free-form on purpose — platforms disagree on names and a fixed enum would go
1012
- * stale but stick to one spelling per permission or the funnel splits in two.
1013
- */
1014
- public trackPermission(
1015
- permission: string,
1016
- status: 'granted' | 'denied' | 'blocked' | 'undetermined' | 'limited',
1017
- details?: Record<string, any>,
1018
- ) {
1019
- return noThrow(() => {
1020
- const name = String(permission || '').trim();
1021
- if (!name) return; // Nothing to attribute the result to — drop rather than emit a blank.
1022
- emitAutomaticEvent('permission_result', {
1023
- ...details,
1024
- permission: name,
1025
- status,
1026
- // Distinguishes a host-reported result from the SDK's own push prompt.
1027
- source: 'host',
1028
- });
1029
- });
1030
- }
1031
-
1032
- /** Track a named event with optional payload */
1033
- public track(name: string, payload?: Record<string, any>) {
1034
- return noThrow(() => {
1035
- if (!this.initialized && !name.startsWith('$')) {
1036
- logger.warn('SDK not initialized. Event dropped:', name);
1037
- return;
1038
- }
1039
- logger.debug('Tracking event:', name);
1040
-
1041
- // Fan this event out to the Engage trigger engine. Same single funnel,
1042
- // extra observer lets behavioral triggers (custom_event, failed_action,
1043
- // after_crash, network_error, before_logout, …) fire off events the SDK
1044
- // already produces, without a parallel capture pipeline.
1045
- engageSignals.emit(name, payload);
1046
-
1047
- const adapter = SessionManager.getExistingInstance()?.getBackendTransport();
1048
- if (this._clientKey && adapter) {
1049
- // SaaS mode → always-on analytics ingestion lane (NOT /sdk/events).
1050
- // sessionId is stamped by the lane at flush time, so the call-time
1051
- // value is a placeholder; endpoint id == body sessionId by construction.
1052
- adapter.trackEvent({
1053
- eventId: generateEventId(),
1054
- sessionId: adapter.analyticsSessionId ?? '',
1055
- ts: Date.now(),
1056
- type: name === '$log' ? 'LOG_EMITTED' : 'USER_ACTION',
1057
- subtype: name,
1058
- payload,
1059
- });
1060
- } else {
1061
- // Legacy mode (projectId/publishableKey): persistent queue /sdk/events.
1062
- const envelope = createEnvelope('event', { name, ...payload });
1063
- this._getQueue().add(envelope);
1064
- }
1065
-
1066
- // Phase 1 analytics envelope lane (/batch → raw_events → events).
1067
- // Runs alongside the session/replay lane above; only active when an
1068
- // appId was configured at init. SDK-internal ($-prefixed) signals stay
1069
- // on the session/debug lane and must not pollute the events table — the
1070
- // split is owned by resolveEventLane (see analytics/eventLane).
1071
- if (this._eventTracker && resolveEventLane(name) === 'analytics') {
1072
- this._eventTracker.track(name, payload);
1073
- }
1074
-
1075
- // Tap into debug stream if enabled (non-blocking)
1076
- const stream = _getStream();
1077
- if (stream) {
1078
- stream.tapEnvelope(createEnvelope('event', { name, ...payload }));
1079
- }
1080
-
1081
- // Tap network events into performance feature
1082
- if (name === '$network_request' && this._performanceFeature?.isActive && payload) {
1083
- this._performanceFeature.processNetworkEvent(payload);
1084
- }
1085
- });
1086
- }
1087
-
1088
- /** Log a message (convenience wrapper over track) */
1089
- public log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: Record<string, unknown>) {
1090
- return this.track('$log', { level, message, ...data });
1091
- }
1092
-
1093
- /**
1094
- * Capture a handled error/exception and deliver it to the backend
1095
- * errors endpoint (shows up in the dashboard Crashes view).
1096
- *
1097
- * No-throw. Routes to: desktop debug stream ($crash event) + SaaS
1098
- * backend errors ingestion (when a clientKey session is active).
1099
- */
1100
- public captureError(
1101
- error: Error | string,
1102
- context?: { screenName?: string; fatal?: boolean; type?: string; metadata?: Record<string, unknown> },
1103
- ) {
1104
- return noThrow(() => {
1105
- const err = typeof error === 'string' ? new Error(error) : error;
1106
- const isFatal = context?.fatal ?? false;
1107
-
1108
- getCrashReporter().report({
1109
- source: 'handled',
1110
- type: context?.type ?? (isFatal ? 'crash' : 'handled'),
1111
- isFatal,
1112
- message: err.message,
1113
- stack: err.stack,
1114
- screenName: context?.screenName,
1115
- metadata: context?.metadata,
1116
- });
1117
-
1118
- // Flush the event queue (desktop $crash) too
1119
- this.flush().catch(() => {});
1120
- });
1121
- }
1122
-
1123
- /**
1124
- * DEV/TEST ONLY — trigger a real native crash to validate the native
1125
- * capture → next-launch drain → backend pipeline. No-op when the native
1126
- * module is unavailable. Do not ship calls to this in production code.
1127
- */
1128
- public nativeCrash() {
1129
- return noThrow(() => triggerNativeCrash());
1130
- }
1131
-
1132
- /** Report a bug (convenience wrapper over track) */
1133
- public reportBug(description: string, metadata?: Record<string, unknown>) {
1134
- return this.track('$bug_report', { description, ...metadata });
1135
- }
1136
-
1137
- /** Set a custom attribute on the current session */
1138
- public setAttribute(key: string, value: string | number | boolean) {
1139
- return this.track('$set_attribute', { key, value });
1140
- }
1141
-
1142
- // ─── Flush ──────────────────────────────────────────────────────────
1143
-
1144
- /** Force-flush all pending events */
1145
- public async flush() {
1146
- return safeAsync(async () => {
1147
- if (!this.initialized) return;
1148
- // SaaS mode has two analytics lanes: EventTracker writes normalized
1149
- // product events to /batch, while BackendSessionAdapter writes the
1150
- // matching timeline events to /ingestion/sessions/:id/events. Drain
1151
- // both before an app background/navigation can suspend their timers.
1152
- // The legacy persistent queue posts to /sdk/events, which the SaaS
1153
- // backend does not serve, so it remains exclusive to legacy mode.
1154
- if (this._clientKey) {
1155
- const adapter = SessionManager.getExistingInstance()?.getBackendTransport();
1156
- await Promise.all([
1157
- this._eventTracker?.flush() ?? Promise.resolve(),
1158
- adapter?.flushAnalytics() ?? Promise.resolve(),
1159
- ]);
1160
- return;
1161
- }
1162
- logger.debug('Flushing events from persistent queue...');
1163
- const httpClient = coreContainer.get<HttpClient>('HttpClient');
1164
- await flushQueue(this._getQueue(), httpClient, getDeviceId());
1165
- });
1166
- }
1167
-
1168
- /**
1169
- * Enable the debug subsystem.
1170
- *
1171
- * @deprecated Use `ScaleBun.init({ debug: true })` instead.
1172
- * This method still works for backward compatibility.
1173
- */
1174
- public enableDebug(config: DebugConfig) {
1175
- return noThrow(() => {
1176
- if (!(config as any).__skipDeprecationWarning) {
1177
- logger.warn(
1178
- '[ScaleBun] enableDebug() is deprecated. ' +
1179
- 'Use ScaleBun.init({ ..., debug: true }) instead.',
1180
- );
1181
- }
1182
-
1183
- const gatedConfig = applyFeatureGatesToDebugConfig(config, this._features);
1184
- _enableDebug(gatedConfig);
1185
- _setFlushFn(() => this.flush() as Promise<void>);
1186
-
1187
- const bootstrapPerfFeature = _getPerformanceFeature();
1188
- if (bootstrapPerfFeature) {
1189
- this._performanceFeature = bootstrapPerfFeature;
1190
- logger.debug('Performance feature linked from bootstrap');
1191
- }
1192
-
1193
- logger.info('Debug enabled');
1194
- });
1195
- }
1196
-
1197
- /** Disable the debug subsystem and clean up */
1198
- public disableDebug() {
1199
- return noThrow(() => {
1200
- _disableDebug();
1201
- });
1202
- }
1203
-
1204
- /**
1205
- * Diagnostic-only: stamp the *expected* target for the very next gesture
1206
- * event. Calibration screens call this immediately before their onPress
1207
- * fires so SessionManager merges expectedTargetId / expectedNX / expectedNY
1208
- * into the stored gesture payload. Pure observability — never affects
1209
- * capture, normalization, or marker placement. TTL ≈ 500 ms.
1210
- */
1211
- public setCalibrationTarget(target: { targetId: string; expectedNX: number; expectedNY: number }): void {
1212
- noThrow(() => {
1213
- const mod = require('../features/journey/calibrationContext') as
1214
- typeof import('../features/journey/calibrationContext');
1215
- mod.setCalibrationTarget(target);
1216
- });
1217
- }
1218
-
1219
- /**
1220
- * Debug utilities namespace.
1221
- * All methods are no-op if debug is not enabled.
1222
- */
1223
- public debug = {
1224
- addBreadcrumb: (message: string, data?: Record<string, unknown>) => {
1225
- noThrow(() => _addBreadcrumb(message, data));
1226
- },
1227
- ping: () => {
1228
- noThrow(() => _ping());
1229
- },
1230
- isEnabled: () => isDebugEnabled(),
1231
- sendMetric: (name: string, value: number, unit?: string, tags?: Record<string, string>) => {
1232
- sendDebugMetric(name, value, unit, tags);
1233
- },
1234
- };
1235
-
1236
- // ─── Replay ─────────────────────────────────────────────────────────
1237
-
1238
- /**
1239
- * Session Replay namespace.
1240
- * Provides control over session replay: recording, capture,
1241
- * user identity, privacy, breadcrumbs, and transport.
1242
- * All methods are no-op if replay feature is disabled.
1243
- */
1244
- public replay = {
1245
- start: (): Promise<void> => ReplaySdk.start(),
1246
- stop: (): Promise<void> => ReplaySdk.stop(),
1247
- pause: (): Promise<void> => ReplaySdk.pause(),
1248
- resume: (): Promise<void> => ReplaySdk.resume(),
1249
- captureFrame: (): Promise<void> => ReplaySdk.captureManualFrame(),
1250
- setUser: (user: ReplayUser): Promise<void> => ReplaySdk.setUser(user),
1251
- clearUser: (): Promise<void> => ReplaySdk.clearUser(),
1252
- addBreadcrumb: (breadcrumb: ReplayBreadcrumb): Promise<void> =>
1253
- ReplaySdk.addBreadcrumb(breadcrumb),
1254
- setPrivacy: (opts: Partial<ReplayPrivacyOptions>): Promise<void> =>
1255
- ReplaySdk.setPrivacyOptions(opts),
1256
- setEnabled: (enabled: boolean): Promise<void> => ReplaySdk.setEnabled(enabled),
1257
- setQuality: (quality: any): Promise<void> => ReplaySdk.setScreenshotQuality(quality),
1258
- setCaptureMode: (mode: any): Promise<void> => ReplaySdk.setCapturingMode(mode),
1259
- setScreen: (name: string): Promise<void> => ReplaySdk.setCurrentScreen(name),
1260
- flush: (): Promise<void> => ReplaySdk.flush(),
1261
- get isRecording(): boolean {
1262
- return ReplaySdk.isRecording;
1263
- },
1264
- get sessionId(): string | null {
1265
- return ReplaySdk.sessionId;
1266
- },
1267
- };
1268
-
1269
- // ─── Performance ────────────────────────────────────────────────────
1270
-
1271
- /**
1272
- * Performance monitoring namespace.
1273
- * Provides control over custom traces, screen load markers,
1274
- * and access to captured metrics.
1275
- * All methods are no-op if performance feature is disabled.
1276
- */
1277
- public performance = {
1278
- /** Start a custom trace. Returns traceId or null. */
1279
- startTrace: (name: string): string | null => {
1280
- return this._performanceFeature?.startTrace(name) ?? null;
1281
- },
1282
- /** Stop a custom trace by ID. */
1283
- stopTrace: (traceId: string): void => {
1284
- this._performanceFeature?.stopTrace(traceId);
1285
- },
1286
- /** Add a span to an active custom trace. */
1287
- addTraceSpan: (traceId: string, name: string, durationMs: number, data?: Record<string, unknown>): void => {
1288
- this._performanceFeature?.addTraceSpan(traceId, name, durationMs, data);
1289
- },
1290
- /** Attach a measurement to an active custom trace. */
1291
- addTraceMeasurement: (traceId: string, name: string, value: number, unit: string): void => {
1292
- this._performanceFeature?.addTraceMeasurement(traceId, name, value, unit);
1293
- },
1294
- /** Mark the start of a screen load. */
1295
- markScreenLoadStart: (screenName: string): void => {
1296
- this._performanceFeature?.markScreenLoadStart(screenName);
1297
- },
1298
- /** Mark the end of a screen load. */
1299
- markScreenLoadEnd: (screenName: string): void => {
1300
- this._performanceFeature?.markScreenLoadEnd(screenName);
1301
- },
1302
- /** Set the current screen for context correlation. */
1303
- setCurrentScreen: (screenName: string): void => {
1304
- this._performanceFeature?.setCurrentScreen(screenName);
1305
- },
1306
- /** Forward navigation state changes for auto screen load detection. */
1307
- onNavigationStateChange: (state: unknown): void => {
1308
- this._performanceFeature?.onNavigationStateChange(state);
1309
- },
1310
- /** Check if performance monitoring is active */
1311
- isActive: (): boolean => {
1312
- return this._performanceFeature?.isActive ?? false;
1313
- },
1314
- /**
1315
- * Send a raw performance metric through the transport.
1316
- * Used for manual/simulated performance metrics.
1317
- */
1318
- sendMetric: (name: string, value: number, unit?: string, tags?: Record<string, string>): void => {
1319
- if (!this._performanceFeature) {
1320
- logger.warn('performance.sendMetric: PerformanceFeature not available — is debug enabled?');
1321
- return;
1322
- }
1323
- this._performanceFeature.sendMetric(name, value, unit, tags);
1324
- },
1325
- };
1326
-
1327
- // ─── Unified Session ────────────────────────────────────────────────
1328
-
1329
- /**
1330
- * Unified Session namespace.
1331
- * Provides access to the unified SessionManager.
1332
- * Sessions auto-start on desktop connect.
1333
- */
1334
- public session = {
1335
- get isActive(): boolean {
1336
- return SessionManager.getExistingInstance()?.isActive ?? false;
1337
- },
1338
- get currentSessionId(): string | null {
1339
- return SessionManager.getExistingInstance()?.currentSessionId ?? null;
1340
- },
1341
- start: (metadata?: Record<string, unknown>): boolean => {
1342
- const sm = SessionManager.getExistingInstance();
1343
- if (!sm) {
1344
- logger.warn('session.start() — SessionManager not available.');
1345
- return false;
1346
- }
1347
- sm.startSession(metadata as Parameters<SessionManager['startSession']>[0]);
1348
- logger.info('session.start() sessionId:', sm.currentSessionId);
1349
- return true;
1350
- },
1351
- end: (reason?: 'ended' | 'timeout'): boolean => {
1352
- const sm = SessionManager.getExistingInstance();
1353
- if (!sm || !sm.isActive) return false;
1354
- sm.endSession(reason);
1355
- logger.info('session.end() ✅');
1356
- return true;
1357
- },
1358
- emitEvent: (type: string, data?: Record<string, unknown>) => {
1359
- const sm = SessionManager.getExistingInstance();
1360
- if (!sm || !sm.isActive) return;
1361
- sm.emitEvent(type as JourneyEventType, data as Parameters<SessionManager['emitEvent']>[1]);
1362
- },
1363
- };
1364
-
1365
- // ─── Session Convenience Methods ────────────────────────────────────
1366
-
1367
- /** Start a session (delegates to session namespace) */
1368
- public startSession(metadata?: Record<string, unknown>): boolean {
1369
- return this.session.start(metadata);
1370
- }
1371
-
1372
- /** Stop the current session (delegates to session namespace) */
1373
- public stopSession(reason?: 'ended' | 'timeout'): boolean {
1374
- return this.session.end(reason);
1375
- }
1376
-
1377
- // ─── Report / Export ───────────────────────────────────────────
1378
-
1379
- /**
1380
- * Report generation and export namespace.
1381
- *
1382
- * Usage:
1383
- * ```ts
1384
- * // Export with default preset
1385
- * const result = await ScaleBun.report.export();
1386
- *
1387
- * // Export with a named preset
1388
- * const result = await ScaleBun.report.export('engineering');
1389
- *
1390
- * // Export with custom options
1391
- * const result = await ScaleBun.report.export({ format: 'pdf', detail: 'detailed' });
1392
- * ```
1393
- *
1394
- * Requires an active desktop debug connection (`debug: true` in init).
1395
- */
1396
- public report = {
1397
- /**
1398
- * Trigger a report export on the desktop application.
1399
- *
1400
- * @param presetOrOptions - Optional. A preset name ('executive', 'engineering', 'qa',
1401
- * 'forensic', 'journey', 'compact') or a SimplifiedExportOptions object.
1402
- * @returns Promise<ExportResult> with success status, file path, or error.
1403
- */
1404
- export: (presetOrOptions?: ExportPresetName | SimplifiedExportOptions): Promise<ExportResult> => {
1405
- return _requestExport(presetOrOptions);
1406
- },
1407
-
1408
- /** Set SDK-wide privacy settings for report generation. */
1409
- setPrivacy: (config: PrivacyConfig): void => {
1410
- this._privacyConfig = { ...this._privacyConfig, ...config };
1411
- logger.debug('[report] Privacy config updated');
1412
- },
1413
-
1414
- /** Set branding for exported reports. */
1415
- setBranding: (config: BrandingConfig): void => {
1416
- this._brandingConfig = { ...this._brandingConfig, ...config };
1417
- logger.debug('[report] Branding config updated');
1418
- },
1419
-
1420
- /** Get current privacy config. */
1421
- getPrivacy: (): PrivacyConfig => ({ ...this._privacyConfig }),
1422
-
1423
- /** Get current branding config. */
1424
- getBranding: (): BrandingConfig => ({ ...this._brandingConfig }),
1425
- };
1426
-
1427
- // ─── Navigation ───────────────────────────────────────────────
1428
-
1429
- /**
1430
- * Set the React Navigation container ref for automatic screen detection.
1431
- *
1432
- * This is the **recommended** way to enable auto screen detection.
1433
- * Once set, the SDK automatically detects screen changes and feeds them
1434
- * to all subsystems (SessionManager, PerformanceFeature, ProfilerFeature).
1435
- * No per-screen `<ScaleBunScreen>` or `useScaleBunScreen()` needed.
1436
- *
1437
- * ```ts
1438
- * import { NavigationContainer } from '@react-navigation/native';
1439
- * import ScaleBun from '@scalebun/react-native';
1440
- *
1441
- * const navigationRef = React.createRef();
1442
- *
1443
- * function App() {
1444
- * useEffect(() => {
1445
- * ScaleBun.setNavigationRef(navigationRef);
1446
- * }, []);
1447
- *
1448
- * return (
1449
- * <NavigationContainer ref={navigationRef}>
1450
- * ...screens...
1451
- * </NavigationContainer>
1452
- * );
1453
- * }
1454
- * ```
1455
- */
1456
- public setNavigationRef(ref: any): void {
1457
- noThrow(() => {
1458
- // Always stash on the global so heuristic polling / late consumers resolve it.
1459
- (globalThis as any).__scalebun_navigationRef = ref;
1460
-
1461
- // Wire the LIVE AutoScreenDetector singleton (started by SDKBootstrapper in
1462
- // production). _getAutoScreenDetector() is the debug-only handle and is null
1463
- // when desktopDebug is off, so relying on it alone never wires the explicit
1464
- // React-Navigation 'state' listener and degrades to slow heuristic polling.
1465
- try {
1466
- const { AutoScreenDetector } = require('../features/navigation/AutoScreenDetector');
1467
- AutoScreenDetector.getInstance().setNavigationRef(ref);
1468
- logger.info('[ScaleBun] Navigation ref set → auto screen detection active');
1469
- } catch (err: any) {
1470
- logger.debug('[ScaleBun] Navigation ref stashed (detector not ready):', err?.message);
1471
- }
1472
- });
1473
- }
1474
- }
1475
-
1476
- /** Singleton Facade instance */
1477
- const instance = new ScaleBunFacade();
1478
- export default instance;
1479
- export { ScaleBunFacade };
1
+ /**
2
+ * ScaleBun SDK — Public Facade
3
+ *
4
+ * Single clean entry point for the ScaleBun SDK.
5
+ * Delegates initialization to SDKBootstrapper, which handles config validation,
6
+ * core service setup, handshake, and feature registration via FeatureRegistry.
7
+ *
8
+ * Config model preserved exactly: projectId, publishableKey, apiBaseUrl.
9
+ * Features are default-on with explicit opt-out via `features: { replay: false }`.
10
+ */
11
+
12
+ import { noThrow, safeAsync } from '../core/lifecycle/crashSafe';
13
+ import { logger } from '../core/logger/internalLogger';
14
+ import { createEnvelope } from '../pipeline/envelope/envelope';
15
+ import { generateEventId } from '../features/replay/core/ids/sessionId';
16
+ import { buildBugReportPayload } from '../features/bugreport/buildPayload';
17
+ import type { BugSubmitResult } from '../features/bugreport/BugReportFeature';
18
+ import { BugReportFeature } from '../features/bugreport/BugReportFeature';
19
+ import { PersistentQueue } from '../pipeline/queue/persistentQueue';
20
+ import { MemoryBackend, createStorageBackend } from '../storage/StorageBackend';
21
+ import { HttpClient } from '../transport/http/httpClient';
22
+ import { getDeviceId } from '../core/id/deviceId';
23
+ import { mergeDeviceContext } from '../core/context/device';
24
+ import { coreContainer } from '../core/di/container';
25
+ import { flushQueue } from '../pipeline/queue/flushQueue';
26
+ import {
27
+ enableDebug as _enableDebug,
28
+ disableDebug as _disableDebug,
29
+ isDebugEnabled,
30
+ addBreadcrumb as _addBreadcrumb,
31
+ ping as _ping,
32
+ _getStream,
33
+ _setFlushFn,
34
+ _getSessionManager,
35
+ _getAutoScreenDetector,
36
+ getPerformanceFeature as _getPerformanceFeature,
37
+ requestExport as _requestExport,
38
+ buildDebugConfigFromInitConfig,
39
+ applyFeatureGatesToDebugConfig,
40
+ sendDebugMetric,
41
+ } from '../debug';
42
+ import type { DebugConfig } from '../debug';
43
+ import { ReplaySdk } from '../features/replay/public/api';
44
+ import type {
45
+ ReplayUser,
46
+ ReplayBreadcrumb,
47
+ ReplayPrivacyOptions,
48
+ } from '../features/replay/public/types';
49
+ import { SDKBootstrapper } from '../bootstrap/SDKBootstrapper';
50
+ import { EventTracker } from '../analytics/EventTracker';
51
+ import {
52
+ emitAutomaticEvent,
53
+ type AutomaticEventName,
54
+ } from '../analytics/automaticEvents';
55
+ import { resolveEventLane } from '../analytics/eventLane';
56
+ import { ConfigManager } from '../config/ConfigManager';
57
+ import { SDK_VERSION } from '../core/constants/version';
58
+ import { EngageTransport, type SubmitStage } from '../features/engage/EngageTransport';
59
+ import {
60
+ getNativePushToken,
61
+ subscribeNativePushTokenRefresh,
62
+ } from '../features/engage/engagePushTokenBridge';
63
+ import { requestNativeStoreReview } from '../features/engage/engageStoreReviewBridge';
64
+ import { PushManager } from '../push/PushManager';
65
+ import type { EnablePushOptions, EnablePushResult, PushNotification } from '../push/types';
66
+ import { ENGAGE_SCHEMA_VERSION } from '../features/engage/engageTypes';
67
+ import { EngageThrottleStore } from '../features/engage/engageThrottle';
68
+ import { EngageTestSeenStore } from '../features/engage/engageTestSeenStore';
69
+ import { engageSignals } from '../features/engage/engageSignals';
70
+ import type {
71
+ EngageAttachmentDraft,
72
+ EngageConfigContext,
73
+ EngageConfigResponse,
74
+ EngageEventInput,
75
+ EngageResponseInput,
76
+ RatingFunnelEventInput,
77
+ SurveyImpressionInput,
78
+ } from '../features/engage/engageTypes';
79
+ import { PerformanceFeature } from '../features/performance/PerformanceFeature';
80
+ import { SessionManager } from '../features/session/SessionManager';
81
+ import type { JourneyEventType } from '../features/session/sessionTypes';
82
+ import { getCrashReporter } from '../features/crash/CrashReporter';
83
+ import { triggerNativeCrash } from '../features/crash/nativeCrashBridge';
84
+ import { updateSkanConversionValue, isSkanAvailable, type SkanCoarseValue } from '../features/skan/skanBridge';
85
+ import { SkanConversionManager } from '../features/skan/skanConversionManager';
86
+ import {
87
+ isInstallReferrerAvailable,
88
+ getInstallReferrer,
89
+ captureInstallReferrerOnce,
90
+ type InstallReferrerSink,
91
+ } from '../features/install-referrer/installReferrer';
92
+ import type {
93
+ ScaleBunInitConfig,
94
+ ScaleBunUser,
95
+ ScaleBunFeatures,
96
+ SimplifiedInitConfig,
97
+ DebugConnectionConfig,
98
+ PrivacyConfig,
99
+ BrandingConfig,
100
+ ExportPresetName,
101
+ SimplifiedExportOptions,
102
+ ExportResult,
103
+ } from './types';
104
+
105
+ class ScaleBunFacade {
106
+ private initialized = false;
107
+ /** In-flight init promise guards against a second init() racing before the first resolves. */
108
+ private _initInFlight: Promise<void> | null = null;
109
+ private bootstrapper = new SDKBootstrapper();
110
+ private _features: ScaleBunFeatures = {};
111
+ private _performanceFeature: PerformanceFeature | null = null;
112
+ private _privacyConfig: PrivacyConfig = {};
113
+ private _brandingConfig: BrandingConfig = {};
114
+ private _clientKey: string | undefined = undefined;
115
+ private _apiBaseUrl: string | undefined = undefined;
116
+ private _engageTransport: EngageTransport | null = null;
117
+ private _engageTokenUnsubscribe: (() => void) | null = null;
118
+ private _pushManager: PushManager | null = null;
119
+ /** Phase 1 envelope event-tracking lane (POST /v1/batch). Null until init with appId. */
120
+ private _eventTracker: EventTracker | null = null;
121
+ /** External identity last supplied through identify(); used by config targeting. */
122
+ private _identifiedUserId: string | null = null;
123
+ /** Identity supplied while async initialization is still in flight. */
124
+ private _pendingIdentity: {
125
+ userId: string;
126
+ traits?: Record<string, any>;
127
+ } | null = null;
128
+ private _configManager: ConfigManager | null = null;
129
+ /** Signature of the last identity POSTed to the ingestion identify endpoint, to skip redundant re-sends. */
130
+ private _lastIngestionIdentityKey: string | null = null;
131
+ /** Phase 3: auto-applies SKAN conversion values from the server schema (iOS only). */
132
+ private _skanManager: SkanConversionManager | null = null;
133
+
134
+ /**
135
+ * Pre-init memory buffer.
136
+ * Events tracked before init() completes are buffered here,
137
+ * then drained into the real persistent queue post-init.
138
+ */
139
+ private _preInitBuffer: PersistentQueue = new PersistentQueue(new MemoryBackend(), {
140
+ enabled: false,
141
+ maxEntries: 500,
142
+ maxBytes: 1_048_576, // 1 MB
143
+ redactBeforeWrite: false, // No redaction for memory-only buffer
144
+ });
145
+
146
+ /** Resolve the active queue (DI container or pre-init buffer) */
147
+ private _getQueue(): PersistentQueue {
148
+ if (this.initialized) {
149
+ try {
150
+ return coreContainer.get<PersistentQueue>('PersistentQueue');
151
+ } catch {
152
+ // Container not ready yet — shouldn't happen post-init
153
+ }
154
+ }
155
+ return this._preInitBuffer;
156
+ }
157
+
158
+ // ─── Initialization ─────────────────────────────────────────────────
159
+
160
+ /**
161
+ * Initialize the ScaleBun SDK.
162
+ *
163
+ * **Simplified usage** (recommended):
164
+ * ```ts
165
+ * await ScaleBun.init({
166
+ * projectId: 'proj_xxx',
167
+ * publishableKey: 'pk_xxx',
168
+ * apiBaseUrl: 'https://api.scalebun.com',
169
+ * debug: true,
170
+ * });
171
+ * ```
172
+ *
173
+ * Accepts both `SimplifiedInitConfig` (new) and `ScaleBunInitConfig` (legacy).
174
+ * If `debug` key is present, auto-connects to the desktop debugger.
175
+ */
176
+ public async init(rawConfig: SimplifiedInitConfig | ScaleBunInitConfig | any) {
177
+ if (this.initialized) return;
178
+ // Coalesce concurrent init() calls: a second call before the first resolves
179
+ // must not run a second bootstrap (which would double-register lifecycle
180
+ // listeners and repeat the backend handshake).
181
+ if (this._initInFlight) return this._initInFlight;
182
+ this._initInFlight = safeAsync(async () => {
183
+ if (this.initialized) return;
184
+
185
+ // Store feature flags (all default true)
186
+ this._features = rawConfig?.features ?? {};
187
+ if (rawConfig?.sessionReplay !== undefined) {
188
+ this._features.replay = rawConfig.sessionReplay;
189
+ }
190
+
191
+ // Store privacy config if provided
192
+ if (rawConfig?.privacy) {
193
+ this._privacyConfig = rawConfig.privacy;
194
+ }
195
+
196
+ // Phase 3 (entitlements) — COST suppression: don't even register a
197
+ // collector the org isn't entitled to (no traffic → no server cost).
198
+ // Read from the cached /config (sync); first run has no cache → fail-open
199
+ // (all entitled), and the server still rejects a closed feature anyway.
200
+ const ent = ConfigManager.readCachedEntitlements();
201
+ const effectiveFeatures: ScaleBunFeatures = {
202
+ ...this._features,
203
+ replay: this._features.replay !== false && ent.replay !== false,
204
+ network: this._features.network !== false && ent.networkMonitoring !== false,
205
+ crashes: this._features.crashes !== false && ent.crashReporting !== false,
206
+ performance: this._features.performance !== false && ent.performanceMonitoring !== false,
207
+ };
208
+
209
+ // Backend bootstrap (non-blocking for debug connection)
210
+ // If the backend is unreachable, the debug WebSocket should still connect.
211
+ try {
212
+ const result = await this.bootstrapper.bootstrap(
213
+ rawConfig,
214
+ (name, payload) => this.track(name, payload),
215
+ () => this.flush() as Promise<void>,
216
+ effectiveFeatures,
217
+ );
218
+
219
+ if (result) {
220
+ this.initialized = true;
221
+ this._clientKey = result.config.clientKey;
222
+ this._apiBaseUrl = result.config.apiBaseUrl;
223
+
224
+ // Phase 1 envelope tracking lane. Enabled when an appId is supplied
225
+ // (and not explicitly disabled). Runs alongside the replay lane.
226
+ this._maybeStartEventTracker(rawConfig);
227
+ if (this._pendingIdentity) {
228
+ const pending = this._pendingIdentity;
229
+ this._pendingIdentity = null;
230
+ this.identify(pending.userId, pending.traits);
231
+ }
232
+
233
+ // Drain pre-init buffer into the real persistent queue
234
+ const realQueue = coreContainer.get<PersistentQueue>('PersistentQueue');
235
+ const buffered = this._preInitBuffer.popBatch(this._preInitBuffer.length());
236
+ if (buffered.length > 0) {
237
+ logger.debug(`[ScaleBun] Draining ${buffered.length} pre-init events into persistent queue`);
238
+ for (const envelope of buffered) {
239
+ realQueue.add(envelope);
240
+ }
241
+ }
242
+
243
+ // Grab a reference to the PerformanceFeature for the public API
244
+ const perfFeature = result.featureRegistry.get('performance');
245
+ if (perfFeature && perfFeature instanceof PerformanceFeature) {
246
+ this._performanceFeature = perfFeature;
247
+ }
248
+ }
249
+ } catch (bootstrapErr: any) {
250
+ logger.warn('[ScaleBun] Backend bootstrap failed (non-blocking):', bootstrapErr?.message);
251
+ // Continue debug connection is independent of backend API
252
+ }
253
+
254
+ // Auto debug connection from init config — runs regardless of backend status
255
+ const debugConfig = (rawConfig?.desktopDebug ?? rawConfig?.debug) as DebugConnectionConfig | undefined;
256
+ if (debugConfig) {
257
+ this._autoEnableDebug(debugConfig);
258
+ }
259
+ });
260
+ try {
261
+ return await this._initInFlight;
262
+ } finally {
263
+ this._initInFlight = null;
264
+ }
265
+ }
266
+
267
+ private _autoEnableDebug(debugConfig: DebugConnectionConfig): void {
268
+ try {
269
+ const dbgConfig = buildDebugConfigFromInitConfig(debugConfig);
270
+ if (!dbgConfig) return;
271
+ (dbgConfig as any).__skipDeprecationWarning = true;
272
+ this.enableDebug(dbgConfig);
273
+ logger.info('[ScaleBun] Debug auto-connected via init({ debug }).');
274
+ } catch (err: any) {
275
+ logger.warn('[ScaleBun] Auto debug connection failed:', err?.message);
276
+ }
277
+ }
278
+
279
+ /** Boot the Phase 1 envelope tracking lane if an appId is configured. */
280
+ private _maybeStartEventTracker(rawConfig: any): void {
281
+ try {
282
+ const appId = rawConfig?.appId;
283
+ const enabled = rawConfig?.eventTracking !== false;
284
+ const clientKey = this._clientKey ?? rawConfig?.clientKey;
285
+ // apiBaseUrl is LOCKED — use only the bootstrapped value, never fall back to raw
286
+ // integrator input, so the event-tracker/SKAdNetwork lane can't be repointed either.
287
+ const apiBaseUrl = this._apiBaseUrl;
288
+ if (!enabled || !appId || !clientKey || !apiBaseUrl) {
289
+ if (enabled && !appId) {
290
+ logger.info('[ScaleBun] Envelope event tracking disabled no appId in init config.');
291
+ }
292
+ return;
293
+ }
294
+ // Phase 3: auto-apply SKAdNetwork conversion values from the server-side
295
+ // CV schema (iOS only; no-op elsewhere). Created BEFORE the tracker so the
296
+ // onEvent hook is live for the very first event (first_open).
297
+ if (isSkanAvailable()) {
298
+ this._skanManager = new SkanConversionManager({ apiBaseUrl, clientKey });
299
+ this._skanManager.refreshSchema().catch(() => {});
300
+ }
301
+ this._eventTracker = new EventTracker({
302
+ appId,
303
+ clientKey,
304
+ apiBaseUrl,
305
+ platform: rawConfig?.platform ?? 'react_native',
306
+ appVersion: rawConfig?.appVersion,
307
+ osVersion: rawConfig?.osVersion,
308
+ autoLifecycleEvents: rawConfig?.autoLifecycleEvents !== false,
309
+ // Backward-compatible opt-in: existing init-only integrations do
310
+ // not begin uploading the new automatic collector stream merely
311
+ // because they upgraded the package. ScaleBunProvider sets this
312
+ // to true unless the integrator explicitly disables it.
313
+ automaticEventTracking:
314
+ rawConfig?.automaticEventTracking === true,
315
+ flushIntervalMs: rawConfig?.flushIntervalMs,
316
+ /**
317
+ * DETECTED, not configured.
318
+ *
319
+ * This was `rawConfig?.context` — whatever the app typed. Production carries
320
+ * `device_model: "android"` and `manufacturer: "android"` from a hand-written
321
+ * literal, while the replay lane was reading the real values off the native bridge
322
+ * the whole time. The SDK knows the device; the integrator is guessing at it.
323
+ * Everything outside the detected keys is still theirs.
324
+ */
325
+ context: mergeDeviceContext(rawConfig?.context),
326
+ // Use the same foreground id as replay/journey capture. The
327
+ // callback is resolved per event because the session subsystem
328
+ // may start after this tracker is constructed.
329
+ sessionIdProvider: () => {
330
+ const manager = SessionManager.getExistingInstance();
331
+ return manager?.currentSessionId
332
+ ?? manager?.getBackendTransport()?.analyticsSessionId
333
+ ?? null;
334
+ },
335
+ // Feed every tracked event to the SKAN CV manager (iOS; no-op otherwise).
336
+ onEvent: (eventName, revenue) => this._skanManager?.onEvent(eventName, revenue),
337
+ });
338
+ this._eventTracker.start();
339
+ logger.info('[ScaleBun] Envelope event tracking started → /v1/batch.');
340
+
341
+ // Android: capture the Play Install Referrer once per install → feeds the
342
+ // deterministic click_id path + a one-off install_referrer event (UTM/gclid).
343
+ // Fire-and-forget; no-op off Android.
344
+ this._captureInstallReferrer(this._eventTracker);
345
+
346
+ // Phase 4: runtime config (flags / remote config / experiments / rollouts).
347
+ // Resolves locally; exposure + stamps flow through the event lane above.
348
+ const tracker = this._eventTracker;
349
+ this._configManager = new ConfigManager({
350
+ apiBaseUrl,
351
+ clientKey,
352
+ installationId: tracker.ids.installationId,
353
+ emitExposure: (experiment, variant) => tracker.track('experiment_exposure', { experiment, variant }),
354
+ stamp: (key, value) => tracker.stamp(key, value),
355
+ });
356
+ this._configManager.refresh().catch(() => {});
357
+ } catch (err: any) {
358
+ logger.warn('[ScaleBun] Failed to start envelope event tracking:', err?.message);
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Android-only: read the Play Install Referrer once per install and route it into
364
+ * attribution. `scalebun_click_id` → the deterministic click path; the full
365
+ * referrer (utm_source/gclid/…) rides on a one-off `install_referrer` event. A
366
+ * `null` fetch (Play unavailable/transient) is not marked captured, so a later
367
+ * launch retries while Play still has the referrer. Never throws.
368
+ */
369
+ private _captureInstallReferrer(tracker: EventTracker): void {
370
+ try {
371
+ if (!isInstallReferrerAvailable()) return;
372
+ const storage = createStorageBackend();
373
+ const KEY = 'scalebun_install_referrer_done';
374
+ const sink: InstallReferrerSink = {
375
+ alreadyCaptured: () => { try { return storage.get(KEY) === '1'; } catch { return false; } },
376
+ markCaptured: () => { try { storage.set(KEY, '1'); } catch { /* no-throw */ } },
377
+ setClickId: (id) => tracker.setAttributionClickId(id),
378
+ emit: (name, props) => tracker.track(name, props as Record<string, any>),
379
+ fetch: () => getInstallReferrer(),
380
+ };
381
+ void captureInstallReferrerOnce(sink);
382
+ } catch (err: any) {
383
+ logger.warn('[ScaleBun] Install Referrer capture failed:', err?.message);
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Phase 1 envelope event tracking API (POST /v1/batch).
389
+ * Methods are no-ops (never throw) until init() is called with an `appId`.
390
+ */
391
+ public get events() {
392
+ const tracker = this._eventTracker;
393
+ return {
394
+ track: (eventName: string, properties?: Record<string, any>) => tracker?.track(eventName, properties),
395
+ identify: (userId: string, traits?: Record<string, any>) => tracker?.identify(userId, traits),
396
+ trackPurchase: (input: { revenue: number; currency: string; transactionId: string; [k: string]: any }) =>
397
+ tracker?.trackPurchase(input),
398
+ setIdentifiers: (ids: { idfa?: string; gaid?: string; idfv?: string }) => tracker?.setIdentifiers(ids),
399
+ // Phase 2: record a deferred deep-link click token for deterministic install attribution.
400
+ setAttributionClickId: (clickId: string) => tracker?.setAttributionClickId(clickId),
401
+ flush: () => tracker?.flush() ?? Promise.resolve(),
402
+ newSession: () => tracker?.newSession(),
403
+ ids: () => tracker?.ids ?? null,
404
+ // Phase 3: update the SKAdNetwork conversion value (iOS only; no-op elsewhere).
405
+ updateSkanConversionValue: (value: number, coarseValue?: SkanCoarseValue, lockWindow?: boolean) =>
406
+ updateSkanConversionValue(value, coarseValue, lockWindow),
407
+ };
408
+ }
409
+
410
+ /**
411
+ * Phase 4: runtime config delivered via GET /v1/config. All resolution is local
412
+ * and non-throwing; values default sensibly until init() runs / config is fetched.
413
+ *
414
+ * ScaleBun.config.get('max_items', 10)
415
+ * ScaleBun.flags.isEnabled('new_checkout')
416
+ * ScaleBun.rollouts.isOn('beta_paywall')
417
+ * ScaleBun.experiments.variant('checkout_cta') // → 'control' | 'treatment' | null
418
+ */
419
+ public get config() {
420
+ const cm = this._configManager;
421
+ return {
422
+ get: <T = any>(key: string, fallback: T): T => (cm ? cm.get(key, fallback) : fallback),
423
+ refresh: () => cm?.refresh() ?? Promise.resolve(),
424
+ };
425
+ }
426
+
427
+ public get flags() {
428
+ const cm = this._configManager;
429
+ return { isEnabled: (key: string) => cm?.isEnabled(key) ?? false };
430
+ }
431
+
432
+ public get rollouts() {
433
+ const cm = this._configManager;
434
+ return { isOn: (key: string) => cm?.rolloutIsOn(key) ?? false };
435
+ }
436
+
437
+ public get experiments() {
438
+ const cm = this._configManager;
439
+ return { variant: (key: string): string | null => cm?.variant(key) ?? null };
440
+ }
441
+
442
+ /** Convenience: emit a Phase 1 purchase event (revenue + currency + transaction_id). */
443
+ public trackPurchase(input: { revenue: number; currency: string; transactionId: string; [k: string]: any }): void {
444
+ noThrow(() => this._eventTracker?.trackPurchase(input));
445
+ }
446
+
447
+ /**
448
+ * Phase 3: set the SKAdNetwork fine conversion value (0–63), optionally with a
449
+ * SKAN 4.0 coarse value and window-lock. iOS only — a no-op on Android / Expo Go.
450
+ */
451
+ public updateSkanConversionValue(value: number, coarseValue?: SkanCoarseValue, lockWindow?: boolean): void {
452
+ noThrow(() => { void updateSkanConversionValue(value, coarseValue, lockWindow); });
453
+ }
454
+
455
+ // ─── Feature Flags ──────────────────────────────────────────────────
456
+
457
+ /** Get the current feature flags (consumed by enableDebug) */
458
+ public getFeatureFlags(): ScaleBunFeatures {
459
+ return this._features;
460
+ }
461
+
462
+ // ─── Identity ───────────────────────────────────────────────────────
463
+
464
+ /** Identify a user by ID and optional traits */
465
+ public identify(userId: string, traits?: Record<string, any>) {
466
+ return noThrow(() => {
467
+ this._identifiedUserId = userId;
468
+ if (!this.initialized) {
469
+ this._pendingIdentity = { userId, traits };
470
+ return;
471
+ }
472
+ this._pendingIdentity = null;
473
+ // Forward to the Phase 1 envelope lane (sets user_id for subsequent events).
474
+ this._eventTracker?.identify(userId, traits);
475
+ this.track('$identify', { id: userId, ...traits });
476
+ const sessionId = SessionManager.getExistingInstance()?.currentSessionId;
477
+ if (this._clientKey && sessionId) {
478
+ // Skip the network POST when the same identity was already sent for this
479
+ // session (repeat identify() with identical traits is a no-op upsert).
480
+ const identityKey = `${sessionId}|${userId}|${JSON.stringify(traits ?? {})}`;
481
+ if (identityKey !== this._lastIngestionIdentityKey) {
482
+ this._lastIngestionIdentityKey = identityKey;
483
+ const user: ScaleBunUser = {
484
+ id: userId,
485
+ name: traits?.name,
486
+ email: traits?.email,
487
+ properties: traits,
488
+ };
489
+ this._callIngestionIdentify(sessionId, user).catch(() => {
490
+ // Re-arm on failure so a later retry is not suppressed.
491
+ this._lastIngestionIdentityKey = null;
492
+ });
493
+ }
494
+ }
495
+ });
496
+ }
497
+
498
+ /**
499
+ * Stable public alias for {@link identify}. Part of the minimal public push
500
+ * API surface (ScaleBun.init / identifyUser / enablePush) that stays
501
+ * identical across RN versions and future platforms.
502
+ */
503
+ public identifyUser(userId: string, traits?: Record<string, any>) {
504
+ return this.identify(userId, traits);
505
+ }
506
+
507
+ /** POST user identity to the SaaS ingestion identify endpoint */
508
+ private async _callIngestionIdentify(sessionId: string, user: ScaleBunUser): Promise<void> {
509
+ if (!this._clientKey || !this._apiBaseUrl) return;
510
+ const url = `${this._apiBaseUrl}/ingestion/sessions/${sessionId}/identify`;
511
+ try {
512
+ await fetch(url, {
513
+ method: 'POST',
514
+ headers: {
515
+ 'Content-Type': 'application/json',
516
+ 'x-scalebun-client-key': this._clientKey,
517
+ },
518
+ body: JSON.stringify({
519
+ userId: user.id,
520
+ username: user.name,
521
+ email: user.email,
522
+ properties: user.properties,
523
+ }),
524
+ });
525
+ } catch (err: any) {
526
+ logger.warn('[ScaleBun] ingestion identify failed:', err?.message);
527
+ }
528
+ }
529
+
530
+ /** Set user identity (for session context) */
531
+ public setUser(user: ScaleBunUser) {
532
+ return noThrow(() => {
533
+ this.identify(user.id, {
534
+ name: user.name,
535
+ email: user.email,
536
+ ...user.attributes,
537
+ });
538
+ });
539
+ }
540
+
541
+ /** Clear user identity */
542
+ public clearUser() {
543
+ return noThrow(() => {
544
+ this._identifiedUserId = null;
545
+ this._pendingIdentity = null;
546
+ if (!this.initialized) return;
547
+ this._eventTracker?.clearIdentity();
548
+ this.track('$clear_user', {});
549
+ });
550
+ }
551
+
552
+ /**
553
+ * Submit in-app rating (1-5 stars).
554
+ * Attaches to current session when available; otherwise sends standalone.
555
+ * Never throws.
556
+ */
557
+ public submitRating(input: {
558
+ rating: number;
559
+ comment?: string;
560
+ source?: 'in_app' | 'prompt' | 'manual';
561
+ /** [ADDITIVE] client-generated UUID for app-rating idempotency (contract §1.4, D8). */
562
+ clientRatingId?: string;
563
+ }) {
564
+ return safeAsync(async () => {
565
+ if (!this._clientKey || !this._apiBaseUrl) return { ok: false, reason: 'sdk_not_configured' as const };
566
+ const rating = Math.round(Number(input?.rating));
567
+ if (!Number.isFinite(rating) || rating < 1 || rating > 5) {
568
+ return { ok: false, reason: 'invalid_rating' as const };
569
+ }
570
+
571
+ const sessionId = this.getActiveSessionId();
572
+ const meta = SessionManager.getExistingInstance()?.currentSessionMetadata;
573
+ const path = sessionId
574
+ ? `/ingestion/sessions/${sessionId}/rating`
575
+ : `/ingestion/ratings`;
576
+ const url = `${this._apiBaseUrl}${path}`;
577
+
578
+ try {
579
+ const res = await fetch(url, {
580
+ method: 'POST',
581
+ headers: {
582
+ 'Content-Type': 'application/json',
583
+ 'x-scalebun-client-key': this._clientKey,
584
+ },
585
+ body: JSON.stringify({
586
+ rating,
587
+ comment: input.comment,
588
+ source: input.source ?? 'in_app',
589
+ appVersion: meta?.appVersion,
590
+ platform: meta?.platform,
591
+ // [ADDITIVE] idempotency + versioning (contract §1.4); omitted when unset.
592
+ ...(input.clientRatingId ? { clientRatingId: input.clientRatingId } : {}),
593
+ schemaVersion: ENGAGE_SCHEMA_VERSION,
594
+ }),
595
+ });
596
+ if (!res.ok) {
597
+ logger.warn('[ScaleBun] submitRating non-ok', res.status);
598
+ return { ok: false, reason: 'http_error' as const, status: res.status };
599
+ }
600
+ return { ok: true as const };
601
+ } catch (err: any) {
602
+ logger.warn('[ScaleBun] submitRating failed:', err?.message);
603
+ return { ok: false, reason: 'network_error' as const };
604
+ }
605
+ });
606
+ }
607
+
608
+ private getActiveSessionId(): string | null {
609
+ try {
610
+ return SessionManager.getExistingInstance()?.currentSessionId ?? null;
611
+ } catch {}
612
+ return null;
613
+ }
614
+
615
+ // ─── Bug reports (F-BUG) ────────────────────────────────────────────
616
+
617
+ /**
618
+ * Thin feature object; the facade owns the HTTP, mirroring the web SDK split.
619
+ * Its only job here is raising the 'report' capture signal so replay flushes.
620
+ */
621
+ private readonly _bugReport = new BugReportFeature();
622
+
623
+ /**
624
+ * Submit a bug report against the CURRENT session.
625
+ *
626
+ * Mirrors the web SDK's `reportBugDetailed` ordering, which is load-bearing rather than
627
+ * incidental:
628
+ *
629
+ * 1. resolve the session — a report with no session cannot be joined to its evidence
630
+ * 2. signal 'report' — replay flushes its buffer so the report has visual context
631
+ * 3. snapshot the anchor — BEFORE the POST. A flush asks the recorder to deliver pending
632
+ * bytes; it cannot retroactively manufacture a frame, so an absent
633
+ * coordinate must stay absent rather than becoming a misleading
634
+ * "start of session" link in the dashboard
635
+ * 4. build + POST — bounds enforced by buildBugReportPayload against the server DTO
636
+ *
637
+ * Returns the report id, or `{ e }` naming which branch failed — 'init' (SDK not configured)
638
+ * reads differently from 'send' (network), and that difference is what tells an integrator
639
+ * whether to check their setup or their connection. It never throws: this is called from a UI
640
+ * the host app renders, usually from a user gesture, and an exception escaping into a React
641
+ * Native render tree is a redbox shown to the customer's user over a report they were sending us.
642
+ */
643
+ public async reportBugDetailed(input: {
644
+ message: string;
645
+ title?: string;
646
+ email?: string;
647
+ clientReportId?: string;
648
+ }): Promise<BugSubmitResult> {
649
+ if (!input || !input.message || input.message.trim().length === 0) {
650
+ logger.warn('[ScaleBun] reportBug: a message is required');
651
+ return { e: 'empty' };
652
+ }
653
+ if (!this._clientKey || !this._apiBaseUrl) {
654
+ logger.warn('[ScaleBun] reportBug: SDK is not configured (clientKey/apiBaseUrl)');
655
+ return { e: 'init' };
656
+ }
657
+
658
+ const sessionId = this.getActiveSessionId();
659
+ if (!sessionId) {
660
+ // No session means no row to attach to, and the ingestion route is session-scoped.
661
+ logger.warn('[ScaleBun] reportBug: no active session');
662
+ return { e: 'init' };
663
+ }
664
+
665
+ try {
666
+ // Flush replay into the session BEFORE reading the anchor below.
667
+ this._bugReport.signalReport();
668
+
669
+ const coord = this._replayCoord();
670
+ const payload = buildBugReportPayload(input, this._recentBreadcrumbs(), {
671
+ replayCoord: coord,
672
+ timestamp: Date.now(),
673
+ });
674
+
675
+ const res = await fetch(
676
+ `${this._apiBaseUrl}/ingestion/sessions/${sessionId}/bug-reports`,
677
+ {
678
+ method: 'POST',
679
+ headers: {
680
+ 'Content-Type': 'application/json',
681
+ 'x-scalebun-client-key': this._clientKey,
682
+ },
683
+ body: JSON.stringify(payload),
684
+ },
685
+ );
686
+ if (!res.ok) {
687
+ logger.warn('[ScaleBun] reportBug: server rejected the report', res.status);
688
+ return { e: 'send' };
689
+ }
690
+ const body = await res.json().catch(() => null);
691
+ return body?.id ?? { e: 'send' };
692
+ } catch (err: any) {
693
+ logger.warn('[ScaleBun] reportBug failed:', err?.message);
694
+ return { e: 'send' };
695
+ }
696
+ }
697
+
698
+ /**
699
+ * The replay coordinate at submit time, or null.
700
+ *
701
+ * Deliberately returns null rather than a zeroed coordinate when replay is disabled, paused, or
702
+ * has not produced a frame yet see the anchor note on reportBug.
703
+ */
704
+ /**
705
+ * The replay coordinate at submit time.
706
+ *
707
+ * ALWAYS null today, deliberately and visibly.
708
+ *
709
+ * The web SDK reads this from its recorder, but the RN replay subsystem exposes no sequence or
710
+ * segment accessor on its public API (features/replay/public/api.ts) -- there is currently no
711
+ * supported way to ask it where playback is. Probing for it through an `any` cast would compile,
712
+ * miss, and leave every report anchor-less while looking wired: the same defect as the existing
713
+ * reportBug(), which emits an analytics event and looks like it files a report.
714
+ *
715
+ * Returning null keeps the payload HONEST -- buildBugReportPayload omits replaySeq entirely, so
716
+ * the dashboard shows no anchor rather than a false one pointing at the start of the session.
717
+ * To finish this: expose the current seq + segment id from the replay recorder, then read them
718
+ * here. The payload builder and its contract tests already handle a real coordinate, including
719
+ * a genuine seq of 0.
720
+ */
721
+ private _replayCoord(): { seq?: number | null; segmentId?: string | null } | null {
722
+ return null;
723
+ }
724
+ /** Recent console breadcrumbs for quick triage. The full set already travels with the session. */
725
+ private _recentBreadcrumbs(): readonly unknown[] {
726
+ try {
727
+ const f = (this as any)._loggerFeature ?? (this as any)._consoleFeature;
728
+ return f?.getRecent?.() ?? [];
729
+ } catch {
730
+ return [];
731
+ }
732
+ }
733
+
734
+ // ─── Engage ─────────────────────────────────────────────────────────
735
+
736
+ /**
737
+ * Lazily resolve the Engage transport. Requires a configured SaaS clientKey +
738
+ * apiBaseUrl (same gate as the rating/ingestion lanes); returns null otherwise.
739
+ * The transport mirrors the existing BackendSessionAdapter outbox: upload lanes
740
+ * batch-flush and re-queue on failure, the config GET is a direct fetch.
741
+ */
742
+ private _getEngageTransport(): EngageTransport | null {
743
+ if (!this._clientKey || !this._apiBaseUrl) return null;
744
+ if (!this._engageTransport) {
745
+ this._engageTransport = new EngageTransport({
746
+ endpoint: this._apiBaseUrl,
747
+ clientKey: this._clientKey,
748
+ });
749
+ }
750
+ return this._engageTransport;
751
+ }
752
+
753
+ /**
754
+ * Engage surface namespace (foundation: transport + native push-token plumbing).
755
+ *
756
+ * Rendering of campaigns/in-app messages is a SHARED cross-platform JS overlay
757
+ * (D4) built in a later stage. This namespace exposes only the foundation:
758
+ * versioned config fetch, idempotent response/event upload (via the existing
759
+ * outbox), and native push-token registration on both platforms.
760
+ */
761
+ public engage = {
762
+ /** Current external identity, forwarded by the provider for segment targeting. */
763
+ getIdentifiedUserId: (): string | undefined =>
764
+ this._identifiedUserId ?? undefined,
765
+
766
+ /**
767
+ * Fetch the versioned Engage config (campaigns + in-app messages).
768
+ *
769
+ * slice-agent: the shared cross-platform JS overlay renderer consumes this
770
+ * payload (EngageConfigResponse.campaigns / .inAppMessages) in a later stage.
771
+ */
772
+ fetchConfig: async (
773
+ context?: EngageConfigContext,
774
+ ): Promise<EngageConfigResponse | null> => {
775
+ const transport = this._getEngageTransport();
776
+ if (!transport) return null;
777
+ const [engageConfig, coachConfig] = await Promise.all([
778
+ transport.fetchEngageConfig(context),
779
+ transport.fetchCoachConfig(),
780
+ ]);
781
+ if (!engageConfig && !coachConfig) return null;
782
+ const coachMessages = (coachConfig?.tours ?? [])
783
+ .filter((tour) => Array.isArray(tour.steps) && tour.steps.length > 0)
784
+ .map((tour) => ({
785
+ id: tour.id,
786
+ layout: 'tooltip' as const,
787
+ trigger: 'app_open',
788
+ variantKey: 'coachmark_spotlight',
789
+ revision: String(tour.version),
790
+ preview: tour.preview === true,
791
+ spec: {
792
+ title: tour.name,
793
+ body: tour.steps[0]?.body ?? tour.name,
794
+ anchorKey: tour.steps[0]?.anchorKey,
795
+ ext: {
796
+ coachTourId: tour.id,
797
+ coachTourVersion: tour.version,
798
+ steps: tour.steps,
799
+ },
800
+ },
801
+ }));
802
+ return {
803
+ configVersion: engageConfig?.configVersion ?? 1,
804
+ serverTime: engageConfig?.serverTime ?? new Date().toISOString(),
805
+ campaigns: engageConfig?.campaigns ?? [],
806
+ inAppMessages: [...(engageConfig?.inAppMessages ?? []), ...coachMessages],
807
+ };
808
+ },
809
+
810
+ /** Internal bridge used by the shared renderer to feed standalone tour analytics. */
811
+ trackCoachmarkEvent: (name: string, properties: Record<string, unknown>): void => {
812
+ this.track(name, properties as Record<string, any>);
813
+ },
814
+
815
+ /**
816
+ * DEBUG/DEV ONLY — clear the persisted in-app/campaign frequency-cap state
817
+ * (every `scalebun_engage_throttle:*` key: impressions, showOnce/completed, cooldown).
818
+ * Lets a tester see throttled/dismissed messages again WITHOUT uninstalling the
819
+ * app. Does NOT change the device id (identity is preserved). Returns the number
820
+ * of cleared entries. NOT a substitute for the real fix (revision-scoped state +
821
+ * test-preview bypass already make normal Send Test work without this).
822
+ */
823
+ clearInAppMessageCache: (): number => {
824
+ return noThrow(() => new EngageThrottleStore().clearAll() + new EngageTestSeenStore().clear()) ?? 0;
825
+ },
826
+
827
+ /**
828
+ * DEBUG/DEV ONLY alias of {@link clearInAppMessageCache} with the broader name
829
+ * used in docs. Resets all on-device in-app frequency/dismiss/impression state so
830
+ * the next config poll can show messages again. Identity (device id) is untouched.
831
+ */
832
+ resetInAppState: (): number => {
833
+ // Clears BOTH lanes: production frequency/dismiss/impression state (throttle
834
+ // store) AND the one-shot test-seen store — so a dismissed test reappears after
835
+ // a debug reset (the "block forever UNLESS debug reset" contract). Identity
836
+ // (device id) is a separate key and stays untouched.
837
+ return noThrow(() => new EngageThrottleStore().clearAll() + new EngageTestSeenStore().clear()) ?? 0;
838
+ },
839
+
840
+ /**
841
+ * Force an immediate flush of queued in-app events. The provider calls this right
842
+ * after a TEST preview's impression/dismiss ACK so the backend consumes the
843
+ * one-shot preview row promptly — a fast close→kill→reopen can't re-serve a
844
+ * still-`delivered` test. Best-effort, never throws.
845
+ */
846
+ flushEvents: (): void => {
847
+ noThrow(() => this._getEngageTransport()?.flushEventsNow());
848
+ },
849
+
850
+ /**
851
+ * DEBUG/DEV ONLY — force a fresh config fetch (deviceId in context) and return the
852
+ * in-app messages the backend is serving THIS device right now, including any
853
+ * queued test previews (`preview:true`). Use it to verify Send Test targeting/
854
+ * delivery without rendering. Logs a one-line summary for the dev console.
855
+ */
856
+ debugFetchInAppMessages: async (
857
+ context?: EngageConfigContext,
858
+ ): Promise<EngageConfigResponse['inAppMessages']> => {
859
+ const cfg = await (this._getEngageTransport()?.fetchEngageConfig(context) ?? Promise.resolve(null));
860
+ const messages = cfg?.inAppMessages ?? [];
861
+ const previews = messages.filter((m) => m.preview === true || m.isTest === true);
862
+ logger.info(
863
+ `[Engage] debugFetchInAppMessages ${messages.length} message(s), ${previews.length} test preview(s)`,
864
+ );
865
+ return messages;
866
+ },
867
+
868
+ /** Upload a survey/NPS/feedback response (idempotent, rides the outbox). */
869
+ submitResponse: (input: EngageResponseInput): void => {
870
+ noThrow(() => this._getEngageTransport()?.uploadEngageResponse(input));
871
+ },
872
+
873
+ /**
874
+ * [P3-e] Submit a response carrying native attachments (screenshot/voice).
875
+ * Presigns + PUTs bytes direct to storage, then enqueues the response with
876
+ * key-only metadata linked by responseId. Falls back to a plain response
877
+ * (no media) when storage is disabled. Best-effort, never throws.
878
+ */
879
+ submitResponseWithAttachments: (
880
+ input: EngageResponseInput,
881
+ attachments: EngageAttachmentDraft[],
882
+ ): void => {
883
+ noThrow(() => {
884
+ void this._getEngageTransport()?.submitResponseWithAttachments(input, attachments);
885
+ });
886
+ },
887
+
888
+ /**
889
+ * [Slice D5] CONFIRMED response submit for the in-prompt submitting→success→error
890
+ * UI. UNLIKE submitResponse*, this AWAITS real server persistence (presign+PUT any
891
+ * audio/screenshot bytes, then a direct response POST) and REJECTS on failure so the
892
+ * caller can show a retryable error. Idempotent: pass the SAME `responseId` on retry
893
+ * both response and attachments de-dupe server-side. Used by EVERY question type.
894
+ */
895
+ submitResponseConfirmed: (
896
+ input: EngageResponseInput,
897
+ attachments: EngageAttachmentDraft[],
898
+ opts: { responseId: string; onStage?: (stage: SubmitStage) => void },
899
+ ): Promise<void> => {
900
+ const transport = this._getEngageTransport();
901
+ if (!transport) return Promise.reject(new Error('sdk_not_configured'));
902
+ return transport.submitResponseConfirmed(input, attachments, opts);
903
+ },
904
+
905
+ /** Upload an in-app impression/click/dismiss event (idempotent, rides the outbox). */
906
+ trackEvent: (input: EngageEventInput): void => {
907
+ noThrow(() => {
908
+ const automaticName: Partial<Record<EngageEventInput['type'], AutomaticEventName>> = {
909
+ impression: 'in_app_displayed',
910
+ rendered: 'in_app_displayed',
911
+ completion: 'in_app_completed',
912
+ click: 'in_app_clicked',
913
+ dismiss: 'in_app_dismissed',
914
+ interaction: 'in_app_interaction',
915
+ render_failed: 'in_app_render_failed',
916
+ cta_open_failed: 'in_app_cta_open_failed',
917
+ };
918
+ const eventName = automaticName[input.type];
919
+ if (eventName) {
920
+ emitAutomaticEvent(eventName, {
921
+ campaign_id: input.campaignId,
922
+ variant_id: input.variantId,
923
+ preview_id: input.previewId,
924
+ is_test: input.isTest,
925
+ source: input.source,
926
+ interaction_type:
927
+ typeof input.meta?.type === 'string'
928
+ ? input.meta.type
929
+ : undefined,
930
+ });
931
+ }
932
+ this._getEngageTransport()?.uploadEngageEvent(input);
933
+ });
934
+ },
935
+
936
+ /** Upload an idempotent survey shown/started funnel beacon. */
937
+ trackSurveyImpression: (input: SurveyImpressionInput): void => {
938
+ noThrow(() => this._getEngageTransport()?.uploadSurveyImpression(input));
939
+ },
940
+
941
+ /**
942
+ * Emit a rating-funnel tracking event (ratings-rebuild CONTRACT §1.2). These
943
+ * are dimensioned FACTS feeding the Overview funnel — NOT campaign responses
944
+ * (D1) so they ride their own `/ingestion/rating-events` lane. Idempotent
945
+ * (client `eventId`, D8). Best-effort, never throws.
946
+ */
947
+ emitRatingEvent: (input: RatingFunnelEventInput): void => {
948
+ noThrow(() => {
949
+ emitAutomaticEvent(input.type, {
950
+ prompt_id: input.promptId,
951
+ trigger_id: input.triggerId,
952
+ variant_id: input.variantId,
953
+ stars: input.stars,
954
+ });
955
+ this._getEngageTransport()?.uploadRatingEvent(input);
956
+ });
957
+ },
958
+
959
+ /**
960
+ * Trigger the native in-app review sheet (Play In-App Review on Android,
961
+ * SKStoreReviewController on iOS) the genuinely-native leg of the rating
962
+ * funnel (D5). Resolves `true` ONLY when the OS flow ran/resolved after a
963
+ * positive route, so the caller emits `store_redirect_clicked` solely on a
964
+ * `true` result. Fail-soft: resolves `false` when native review is unavailable.
965
+ */
966
+ requestStoreReview: async (): Promise<boolean> => {
967
+ return (await safeAsync(async () => requestNativeStoreReview())) ?? false;
968
+ },
969
+
970
+ /**
971
+ * Submit a 1–5 app-store rating via the EXISTING app-rating lane (D1 keeps
972
+ * ratings a distinct funnel — NOT submitResponse). Delegates to the
973
+ * facade's `submitRating`, threading the renderer's `clientRatingId` for
974
+ * idempotency (D8). Used by the RATING_PROMPT render branch.
975
+ */
976
+ submitRating: (input: {
977
+ rating: number;
978
+ comment?: string;
979
+ source?: 'in_app' | 'prompt' | 'manual';
980
+ clientRatingId?: string;
981
+ }): void => {
982
+ noThrow(() => {
983
+ void this.submitRating(input);
984
+ });
985
+ },
986
+
987
+ /**
988
+ * Acquire the native push token (FCM/APNs) and register it for delivery.
989
+ * Subscribes to native token-refresh (rotation) so the backend always holds
990
+ * the live token. Fail-soft: no-op when native push is unavailable.
991
+ */
992
+ registerForPush: async (): Promise<void> => {
993
+ return safeAsync(async () => {
994
+ const transport = this._getEngageTransport();
995
+ if (!transport) return;
996
+
997
+ const initial = await getNativePushToken();
998
+ if (initial) {
999
+ transport.registerDeviceToken({
1000
+ pushToken: initial.token,
1001
+ platform: initial.platform,
1002
+ pushProvider: initial.platform === 'ios' ? 'apns' : 'fcm',
1003
+ });
1004
+ }
1005
+
1006
+ // Avoid stacking listeners on repeated calls.
1007
+ this._engageTokenUnsubscribe?.();
1008
+ this._engageTokenUnsubscribe = subscribeNativePushTokenRefresh((refreshed) => {
1009
+ this._getEngageTransport()?.registerDeviceToken({
1010
+ pushToken: refreshed.token,
1011
+ platform: refreshed.platform,
1012
+ pushProvider: refreshed.platform === 'ios' ? 'apns' : 'fcm',
1013
+ });
1014
+ });
1015
+ }) as Promise<void>;
1016
+ },
1017
+ };
1018
+
1019
+ // ─── Push Notifications ─────────────────────────────────────────────
1020
+
1021
+ /**
1022
+ * Lazily build the PushManager. Backend token registration is injected and
1023
+ * routes through the existing Engage outbox (EngageTransport.registerDeviceToken),
1024
+ * so push reuses the SDK's single device-token lane rather than a parallel
1025
+ * fetch. Returns {ok:false} when the SDK isn't configured (clientKey absent).
1026
+ */
1027
+ private _getPushManager(): PushManager {
1028
+ if (!this._pushManager) {
1029
+ this._pushManager = new PushManager({
1030
+ registerToken: async (input) => {
1031
+ const transport = this._getEngageTransport();
1032
+ if (!transport) return { ok: false, reason: 'sdk_not_configured' as const };
1033
+ transport.registerDeviceToken({
1034
+ pushToken: input.pushToken,
1035
+ platform: input.platform,
1036
+ pushProvider: input.pushProvider,
1037
+ sdkVersion: SDK_VERSION,
1038
+ ...(this._eventTracker
1039
+ ? { installationId: this._eventTracker.getInstallationId() }
1040
+ : {}),
1041
+ });
1042
+ return { ok: true as const };
1043
+ },
1044
+ });
1045
+ }
1046
+ return this._pushManager;
1047
+ }
1048
+
1049
+ /**
1050
+ * Enable push notifications with smart, version-aware adapter selection.
1051
+ *
1052
+ * Detects the RN version, architecture (legacy bridge vs New
1053
+ * Architecture/bridgeless), whether @react-native-firebase/messaging is
1054
+ * installed & compatible, and whether the ScaleBunEngage native token bridge is
1055
+ * linked, then picks the safest supported path automatically: RNFirebase
1056
+ * (full callbacks) native ScaleBunEngage bridge (token-only fallback that works
1057
+ * under bridgeless regardless of RNFirebase version) → manual → noop.
1058
+ *
1059
+ * Requests OS permission, creates the Android channel, acquires the push
1060
+ * token, keeps it in sync on refresh, registers it with the ScaleBun backend
1061
+ * (via the Engage outbox), and wires foreground/opened callbacks.
1062
+ *
1063
+ * Fails clearly (ok:false + actionable reason) when no usable provider
1064
+ * exists — never silently breaks. Never throws.
1065
+ *
1066
+ * ```ts
1067
+ * await ScaleBun.enablePush({
1068
+ * onForegroundNotification: (n) => {},
1069
+ * onNotificationOpened: (n) => {},
1070
+ * });
1071
+ * ```
1072
+ */
1073
+ public enablePush(options?: EnablePushOptions): Promise<EnablePushResult> {
1074
+ return this._getPushManager().enable(options ?? {});
1075
+ }
1076
+
1077
+ /**
1078
+ * Subscribe to notifications received while the app is foregrounded. Thin,
1079
+ * platform-agnostic alias for `enablePush({ onForegroundNotification })`; use it
1080
+ * to attach a handler after enablePush. Returns an unsubscribe function. Inert
1081
+ * until push is enabled. (iOS direct APNs delivers these via the native
1082
+ * UNUserNotificationCenter surface.)
1083
+ */
1084
+ public onForegroundNotification(cb: (notification: PushNotification) => void): () => void {
1085
+ return noThrow(() => this._getPushManager().onForegroundNotification(cb)) ?? (() => {});
1086
+ }
1087
+
1088
+ /**
1089
+ * Subscribe to the user tapping a notification (open / deep-link), including the
1090
+ * cold-start notification that launched the app. Thin alias for
1091
+ * `enablePush({ onNotificationOpened })`. Returns an unsubscribe function. The
1092
+ * event shape ({ data, title?, body? }) matches across Android and iOS.
1093
+ */
1094
+ public onNotificationOpened(cb: (notification: PushNotification) => void): () => void {
1095
+ return noThrow(() => this._getPushManager().onNotificationOpened(cb)) ?? (() => {});
1096
+ }
1097
+
1098
+ /**
1099
+ * Push control namespace. Most apps only need {@link enablePush}; these are
1100
+ * for the manual/custom provider path and diagnostics.
1101
+ */
1102
+ public push = {
1103
+ /** Inject/rotate a token (manual provider) — syncs to the backend. */
1104
+ setToken: (token: string): void => {
1105
+ noThrow(() => this._getPushManager().setToken(token));
1106
+ },
1107
+ /** Current push token, if acquired. */
1108
+ getToken: (): string | null => {
1109
+ return noThrow(() => this._getPushManager().getToken()) ?? null;
1110
+ },
1111
+ /** Deliver a foreground notification to registered callbacks (manual provider). */
1112
+ emitForeground: (message: PushNotification): void => {
1113
+ noThrow(() => this._getPushManager().emitForeground(message));
1114
+ },
1115
+ /** Deliver a notification-open event to registered callbacks (manual provider). */
1116
+ emitNotificationOpened: (message: PushNotification): void => {
1117
+ noThrow(() => this._getPushManager().emitNotificationOpened(message));
1118
+ },
1119
+ /** Current push status: selected adapter, usability, reason, token. */
1120
+ status: () => this._getPushManager().status(),
1121
+ /** Tear down all push listeners. */
1122
+ teardown: (): void => {
1123
+ noThrow(() => this._pushManager?.teardown());
1124
+ },
1125
+ };
1126
+
1127
+ // ─── Event Tracking ─────────────────────────────────────────────────
1128
+
1129
+ /**
1130
+ * Report the outcome of an OS permission prompt.
1131
+ *
1132
+ * Permission results were state the SDK held privately and never an event, so the core mobile
1133
+ * growth loop "reached the paywall → was prompted → granted" — could not be expressed as a funnel.
1134
+ *
1135
+ * Notification permission is captured AUTOMATICALLY (the SDK runs that prompt itself, see
1136
+ * PushManager). Every other permission belongs to the host app: the SDK never sees a camera or
1137
+ * location request, so guessing at one would be inventing data. Call this right after the prompt
1138
+ * resolves:
1139
+ *
1140
+ * ```ts
1141
+ * const { status } = await Location.requestForegroundPermissionsAsync();
1142
+ * ScaleBun.trackPermission('location', status === 'granted' ? 'granted' : 'denied');
1143
+ * ```
1144
+ *
1145
+ * `permission` is free-form on purpose — platforms disagree on names and a fixed enum would go
1146
+ * stale but stick to one spelling per permission or the funnel splits in two.
1147
+ */
1148
+ public trackPermission(
1149
+ permission: string,
1150
+ status: 'granted' | 'denied' | 'blocked' | 'undetermined' | 'limited',
1151
+ details?: Record<string, any>,
1152
+ ) {
1153
+ return noThrow(() => {
1154
+ const name = String(permission || '').trim();
1155
+ if (!name) return; // Nothing to attribute the result to — drop rather than emit a blank.
1156
+ emitAutomaticEvent('permission_result', {
1157
+ ...details,
1158
+ permission: name,
1159
+ status,
1160
+ // Distinguishes a host-reported result from the SDK's own push prompt.
1161
+ source: 'host',
1162
+ });
1163
+ });
1164
+ }
1165
+
1166
+ /** Track a named event with optional payload */
1167
+ public track(name: string, payload?: Record<string, any>) {
1168
+ return noThrow(() => {
1169
+ if (!this.initialized && !name.startsWith('$')) {
1170
+ logger.warn('SDK not initialized. Event dropped:', name);
1171
+ return;
1172
+ }
1173
+ logger.debug('Tracking event:', name);
1174
+
1175
+ // Fan this event out to the Engage trigger engine. Same single funnel,
1176
+ // extra observer lets behavioral triggers (custom_event, failed_action,
1177
+ // after_crash, network_error, before_logout, …) fire off events the SDK
1178
+ // already produces, without a parallel capture pipeline.
1179
+ engageSignals.emit(name, payload);
1180
+
1181
+ const adapter = SessionManager.getExistingInstance()?.getBackendTransport();
1182
+ if (this._clientKey && adapter) {
1183
+ // SaaS mode → always-on analytics ingestion lane (NOT /sdk/events).
1184
+ // sessionId is stamped by the lane at flush time, so the call-time
1185
+ // value is a placeholder; endpoint id == body sessionId by construction.
1186
+ adapter.trackEvent({
1187
+ eventId: generateEventId(),
1188
+ sessionId: adapter.analyticsSessionId ?? '',
1189
+ ts: Date.now(),
1190
+ type: name === '$log' ? 'LOG_EMITTED' : 'USER_ACTION',
1191
+ subtype: name,
1192
+ payload,
1193
+ });
1194
+ } else {
1195
+ // Legacy mode (projectId/publishableKey): persistent queue → /sdk/events.
1196
+ const envelope = createEnvelope('event', { name, ...payload });
1197
+ this._getQueue().add(envelope);
1198
+ }
1199
+
1200
+ // Phase 1 analytics envelope lane (/batch → raw_events → events).
1201
+ // Runs alongside the session/replay lane above; only active when an
1202
+ // appId was configured at init. SDK-internal ($-prefixed) signals stay
1203
+ // on the session/debug lane and must not pollute the events table — the
1204
+ // split is owned by resolveEventLane (see analytics/eventLane).
1205
+ if (this._eventTracker && resolveEventLane(name) === 'analytics') {
1206
+ this._eventTracker.track(name, payload);
1207
+ }
1208
+
1209
+ // Tap into debug stream if enabled (non-blocking)
1210
+ const stream = _getStream();
1211
+ if (stream) {
1212
+ stream.tapEnvelope(createEnvelope('event', { name, ...payload }));
1213
+ }
1214
+
1215
+ // Tap network events into performance feature
1216
+ if (name === '$network_request' && this._performanceFeature?.isActive && payload) {
1217
+ this._performanceFeature.processNetworkEvent(payload);
1218
+ }
1219
+ });
1220
+ }
1221
+
1222
+ /** Log a message (convenience wrapper over track) */
1223
+ public log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: Record<string, unknown>) {
1224
+ return this.track('$log', { level, message, ...data });
1225
+ }
1226
+
1227
+ /**
1228
+ * Capture a handled error/exception and deliver it to the backend
1229
+ * errors endpoint (shows up in the dashboard Crashes view).
1230
+ *
1231
+ * No-throw. Routes to: desktop debug stream ($crash event) + SaaS
1232
+ * backend errors ingestion (when a clientKey session is active).
1233
+ */
1234
+ public captureError(
1235
+ error: Error | string,
1236
+ context?: { screenName?: string; fatal?: boolean; type?: string; metadata?: Record<string, unknown> },
1237
+ ) {
1238
+ return noThrow(() => {
1239
+ const err = typeof error === 'string' ? new Error(error) : error;
1240
+ const isFatal = context?.fatal ?? false;
1241
+
1242
+ getCrashReporter().report({
1243
+ source: 'handled',
1244
+ type: context?.type ?? (isFatal ? 'crash' : 'handled'),
1245
+ isFatal,
1246
+ message: err.message,
1247
+ stack: err.stack,
1248
+ screenName: context?.screenName,
1249
+ metadata: context?.metadata,
1250
+ });
1251
+
1252
+ // Flush the event queue (desktop $crash) too
1253
+ this.flush().catch(() => {});
1254
+ });
1255
+ }
1256
+
1257
+ /**
1258
+ * DEV/TEST ONLY trigger a real native crash to validate the native
1259
+ * capture next-launch drain → backend pipeline. No-op when the native
1260
+ * module is unavailable. Do not ship calls to this in production code.
1261
+ */
1262
+ public nativeCrash() {
1263
+ return noThrow(() => triggerNativeCrash());
1264
+ }
1265
+
1266
+ /** Report a bug (convenience wrapper over track) */
1267
+ public reportBug(description: string, metadata?: Record<string, unknown>) {
1268
+ // D11: this used to be ONLY `track('$bug_report')` — an analytics event
1269
+ // with zero consumers (no mapper, no handler, no BugReport row), so
1270
+ // /diagnose/bug-reports stayed empty forever for RN apps while the web
1271
+ // SDK used the real ingest. Route to the same endpoint the web SDK
1272
+ // uses; the analytics event is kept as a breadcrumb, not the delivery.
1273
+ try {
1274
+ const transport = SessionManager.getExistingInstance()?.getBackendTransport();
1275
+ transport?.submitBugReport({
1276
+ message: description,
1277
+ title:
1278
+ typeof metadata?.title === 'string' ? (metadata.title as string) : undefined,
1279
+ email:
1280
+ typeof metadata?.email === 'string' ? (metadata.email as string) : undefined,
1281
+ });
1282
+ } catch {
1283
+ /* delivery is best-effort; the track below still records intent */
1284
+ }
1285
+ return this.track('$bug_report', { description, ...metadata });
1286
+ }
1287
+
1288
+ /** Set a custom attribute on the current session */
1289
+ public setAttribute(key: string, value: string | number | boolean) {
1290
+ return this.track('$set_attribute', { key, value });
1291
+ }
1292
+
1293
+ // ─── Flush ──────────────────────────────────────────────────────────
1294
+
1295
+ /** Force-flush all pending events */
1296
+ public async flush() {
1297
+ return safeAsync(async () => {
1298
+ if (!this.initialized) return;
1299
+ // SaaS mode has two analytics lanes: EventTracker writes normalized
1300
+ // product events to /batch, while BackendSessionAdapter writes the
1301
+ // matching timeline events to /ingestion/sessions/:id/events. Drain
1302
+ // both before an app background/navigation can suspend their timers.
1303
+ // The legacy persistent queue posts to /sdk/events, which the SaaS
1304
+ // backend does not serve, so it remains exclusive to legacy mode.
1305
+ if (this._clientKey) {
1306
+ const adapter = SessionManager.getExistingInstance()?.getBackendTransport();
1307
+ await Promise.all([
1308
+ this._eventTracker?.flush() ?? Promise.resolve(),
1309
+ adapter?.flushAnalytics() ?? Promise.resolve(),
1310
+ ]);
1311
+ return;
1312
+ }
1313
+ logger.debug('Flushing events from persistent queue...');
1314
+ const httpClient = coreContainer.get<HttpClient>('HttpClient');
1315
+ await flushQueue(this._getQueue(), httpClient, getDeviceId());
1316
+ });
1317
+ }
1318
+
1319
+ /**
1320
+ * Enable the debug subsystem.
1321
+ *
1322
+ * @deprecated Use `ScaleBun.init({ debug: true })` instead.
1323
+ * This method still works for backward compatibility.
1324
+ */
1325
+ public enableDebug(config: DebugConfig) {
1326
+ return noThrow(() => {
1327
+ if (!(config as any).__skipDeprecationWarning) {
1328
+ logger.warn(
1329
+ '[ScaleBun] enableDebug() is deprecated. ' +
1330
+ 'Use ScaleBun.init({ ..., debug: true }) instead.',
1331
+ );
1332
+ }
1333
+
1334
+ const gatedConfig = applyFeatureGatesToDebugConfig(config, this._features);
1335
+ _enableDebug(gatedConfig);
1336
+ _setFlushFn(() => this.flush() as Promise<void>);
1337
+
1338
+ const bootstrapPerfFeature = _getPerformanceFeature();
1339
+ if (bootstrapPerfFeature) {
1340
+ this._performanceFeature = bootstrapPerfFeature;
1341
+ logger.debug('Performance feature linked from bootstrap');
1342
+ }
1343
+
1344
+ logger.info('Debug enabled');
1345
+ });
1346
+ }
1347
+
1348
+ /** Disable the debug subsystem and clean up */
1349
+ public disableDebug() {
1350
+ return noThrow(() => {
1351
+ _disableDebug();
1352
+ });
1353
+ }
1354
+
1355
+ /**
1356
+ * Diagnostic-only: stamp the *expected* target for the very next gesture
1357
+ * event. Calibration screens call this immediately before their onPress
1358
+ * fires so SessionManager merges expectedTargetId / expectedNX / expectedNY
1359
+ * into the stored gesture payload. Pure observability — never affects
1360
+ * capture, normalization, or marker placement. TTL ≈ 500 ms.
1361
+ */
1362
+ public setCalibrationTarget(target: { targetId: string; expectedNX: number; expectedNY: number }): void {
1363
+ noThrow(() => {
1364
+ const mod = require('../features/journey/calibrationContext') as
1365
+ typeof import('../features/journey/calibrationContext');
1366
+ mod.setCalibrationTarget(target);
1367
+ });
1368
+ }
1369
+
1370
+ /**
1371
+ * Debug utilities namespace.
1372
+ * All methods are no-op if debug is not enabled.
1373
+ */
1374
+ public debug = {
1375
+ addBreadcrumb: (message: string, data?: Record<string, unknown>) => {
1376
+ noThrow(() => _addBreadcrumb(message, data));
1377
+ },
1378
+ ping: () => {
1379
+ noThrow(() => _ping());
1380
+ },
1381
+ isEnabled: () => isDebugEnabled(),
1382
+ sendMetric: (name: string, value: number, unit?: string, tags?: Record<string, string>) => {
1383
+ sendDebugMetric(name, value, unit, tags);
1384
+ },
1385
+ };
1386
+
1387
+ // ─── Replay ─────────────────────────────────────────────────────────
1388
+
1389
+ /**
1390
+ * Session Replay namespace.
1391
+ * Provides control over session replay: recording, capture,
1392
+ * user identity, privacy, breadcrumbs, and transport.
1393
+ * All methods are no-op if replay feature is disabled.
1394
+ */
1395
+ public replay = {
1396
+ start: (): Promise<void> => ReplaySdk.start(),
1397
+ stop: (): Promise<void> => ReplaySdk.stop(),
1398
+ pause: (): Promise<void> => ReplaySdk.pause(),
1399
+ resume: (): Promise<void> => ReplaySdk.resume(),
1400
+ captureFrame: (): Promise<void> => ReplaySdk.captureManualFrame(),
1401
+ setUser: (user: ReplayUser): Promise<void> => ReplaySdk.setUser(user),
1402
+ clearUser: (): Promise<void> => ReplaySdk.clearUser(),
1403
+ addBreadcrumb: (breadcrumb: ReplayBreadcrumb): Promise<void> =>
1404
+ ReplaySdk.addBreadcrumb(breadcrumb),
1405
+ setPrivacy: (opts: Partial<ReplayPrivacyOptions>): Promise<void> =>
1406
+ ReplaySdk.setPrivacyOptions(opts),
1407
+ setEnabled: (enabled: boolean): Promise<void> => ReplaySdk.setEnabled(enabled),
1408
+ setQuality: (quality: any): Promise<void> => ReplaySdk.setScreenshotQuality(quality),
1409
+ setCaptureMode: (mode: any): Promise<void> => ReplaySdk.setCapturingMode(mode),
1410
+ setScreen: (name: string): Promise<void> => ReplaySdk.setCurrentScreen(name),
1411
+ flush: (): Promise<void> => ReplaySdk.flush(),
1412
+ get isRecording(): boolean {
1413
+ return ReplaySdk.isRecording;
1414
+ },
1415
+ get sessionId(): string | null {
1416
+ return ReplaySdk.sessionId;
1417
+ },
1418
+ };
1419
+
1420
+ // ─── Performance ────────────────────────────────────────────────────
1421
+
1422
+ /**
1423
+ * Performance monitoring namespace.
1424
+ * Provides control over custom traces, screen load markers,
1425
+ * and access to captured metrics.
1426
+ * All methods are no-op if performance feature is disabled.
1427
+ */
1428
+ public performance = {
1429
+ /** Start a custom trace. Returns traceId or null. */
1430
+ startTrace: (name: string): string | null => {
1431
+ return this._performanceFeature?.startTrace(name) ?? null;
1432
+ },
1433
+ /** Stop a custom trace by ID. */
1434
+ stopTrace: (traceId: string): void => {
1435
+ this._performanceFeature?.stopTrace(traceId);
1436
+ },
1437
+ /** Add a span to an active custom trace. */
1438
+ addTraceSpan: (traceId: string, name: string, durationMs: number, data?: Record<string, unknown>): void => {
1439
+ this._performanceFeature?.addTraceSpan(traceId, name, durationMs, data);
1440
+ },
1441
+ /** Attach a measurement to an active custom trace. */
1442
+ addTraceMeasurement: (traceId: string, name: string, value: number, unit: string): void => {
1443
+ this._performanceFeature?.addTraceMeasurement(traceId, name, value, unit);
1444
+ },
1445
+ /** Mark the start of a screen load. */
1446
+ markScreenLoadStart: (screenName: string): void => {
1447
+ this._performanceFeature?.markScreenLoadStart(screenName);
1448
+ },
1449
+ /** Mark the end of a screen load. */
1450
+ markScreenLoadEnd: (screenName: string): void => {
1451
+ this._performanceFeature?.markScreenLoadEnd(screenName);
1452
+ },
1453
+ /** Set the current screen for context correlation. */
1454
+ setCurrentScreen: (screenName: string): void => {
1455
+ this._performanceFeature?.setCurrentScreen(screenName);
1456
+ },
1457
+ /** Forward navigation state changes for auto screen load detection. */
1458
+ onNavigationStateChange: (state: unknown): void => {
1459
+ this._performanceFeature?.onNavigationStateChange(state);
1460
+ },
1461
+ /** Check if performance monitoring is active */
1462
+ isActive: (): boolean => {
1463
+ return this._performanceFeature?.isActive ?? false;
1464
+ },
1465
+ /**
1466
+ * Send a raw performance metric through the transport.
1467
+ * Used for manual/simulated performance metrics.
1468
+ */
1469
+ sendMetric: (name: string, value: number, unit?: string, tags?: Record<string, string>): void => {
1470
+ if (!this._performanceFeature) {
1471
+ logger.warn('performance.sendMetric: PerformanceFeature not available — is debug enabled?');
1472
+ return;
1473
+ }
1474
+ this._performanceFeature.sendMetric(name, value, unit, tags);
1475
+ },
1476
+ };
1477
+
1478
+ // ─── Unified Session ────────────────────────────────────────────────
1479
+
1480
+ /**
1481
+ * Unified Session namespace.
1482
+ * Provides access to the unified SessionManager.
1483
+ * Sessions auto-start on desktop connect.
1484
+ */
1485
+ public session = {
1486
+ get isActive(): boolean {
1487
+ return SessionManager.getExistingInstance()?.isActive ?? false;
1488
+ },
1489
+ get currentSessionId(): string | null {
1490
+ return SessionManager.getExistingInstance()?.currentSessionId ?? null;
1491
+ },
1492
+ start: (metadata?: Record<string, unknown>): boolean => {
1493
+ const sm = SessionManager.getExistingInstance();
1494
+ if (!sm) {
1495
+ logger.warn('session.start() — SessionManager not available.');
1496
+ return false;
1497
+ }
1498
+ sm.startSession(metadata as Parameters<SessionManager['startSession']>[0]);
1499
+ logger.info('session.start() ✅ sessionId:', sm.currentSessionId);
1500
+ return true;
1501
+ },
1502
+ end: (reason?: 'ended' | 'timeout'): boolean => {
1503
+ const sm = SessionManager.getExistingInstance();
1504
+ if (!sm || !sm.isActive) return false;
1505
+ sm.endSession(reason);
1506
+ logger.info('session.end() ✅');
1507
+ return true;
1508
+ },
1509
+ emitEvent: (type: string, data?: Record<string, unknown>) => {
1510
+ const sm = SessionManager.getExistingInstance();
1511
+ if (!sm || !sm.isActive) return;
1512
+ sm.emitEvent(type as JourneyEventType, data as Parameters<SessionManager['emitEvent']>[1]);
1513
+ },
1514
+ };
1515
+
1516
+ // ─── Session Convenience Methods ────────────────────────────────────
1517
+
1518
+ /** Start a session (delegates to session namespace) */
1519
+ public startSession(metadata?: Record<string, unknown>): boolean {
1520
+ return this.session.start(metadata);
1521
+ }
1522
+
1523
+ /** Stop the current session (delegates to session namespace) */
1524
+ public stopSession(reason?: 'ended' | 'timeout'): boolean {
1525
+ return this.session.end(reason);
1526
+ }
1527
+
1528
+ // ─── Report / Export ───────────────────────────────────────────
1529
+
1530
+ /**
1531
+ * Report generation and export namespace.
1532
+ *
1533
+ * Usage:
1534
+ * ```ts
1535
+ * // Export with default preset
1536
+ * const result = await ScaleBun.report.export();
1537
+ *
1538
+ * // Export with a named preset
1539
+ * const result = await ScaleBun.report.export('engineering');
1540
+ *
1541
+ * // Export with custom options
1542
+ * const result = await ScaleBun.report.export({ format: 'pdf', detail: 'detailed' });
1543
+ * ```
1544
+ *
1545
+ * Requires an active desktop debug connection (`debug: true` in init).
1546
+ */
1547
+ public report = {
1548
+ /**
1549
+ * Trigger a report export on the desktop application.
1550
+ *
1551
+ * @param presetOrOptions - Optional. A preset name ('executive', 'engineering', 'qa',
1552
+ * 'forensic', 'journey', 'compact') or a SimplifiedExportOptions object.
1553
+ * @returns Promise<ExportResult> with success status, file path, or error.
1554
+ */
1555
+ export: (presetOrOptions?: ExportPresetName | SimplifiedExportOptions): Promise<ExportResult> => {
1556
+ return _requestExport(presetOrOptions);
1557
+ },
1558
+
1559
+ /** Set SDK-wide privacy settings for report generation. */
1560
+ setPrivacy: (config: PrivacyConfig): void => {
1561
+ this._privacyConfig = { ...this._privacyConfig, ...config };
1562
+ logger.debug('[report] Privacy config updated');
1563
+ },
1564
+
1565
+ /** Set branding for exported reports. */
1566
+ setBranding: (config: BrandingConfig): void => {
1567
+ this._brandingConfig = { ...this._brandingConfig, ...config };
1568
+ logger.debug('[report] Branding config updated');
1569
+ },
1570
+
1571
+ /** Get current privacy config. */
1572
+ getPrivacy: (): PrivacyConfig => ({ ...this._privacyConfig }),
1573
+
1574
+ /** Get current branding config. */
1575
+ getBranding: (): BrandingConfig => ({ ...this._brandingConfig }),
1576
+ };
1577
+
1578
+ // ─── Navigation ───────────────────────────────────────────────
1579
+
1580
+ /**
1581
+ * Set the React Navigation container ref for automatic screen detection.
1582
+ *
1583
+ * This is the **recommended** way to enable auto screen detection.
1584
+ * Once set, the SDK automatically detects screen changes and feeds them
1585
+ * to all subsystems (SessionManager, PerformanceFeature, ProfilerFeature).
1586
+ * No per-screen `<ScaleBunScreen>` or `useScaleBunScreen()` needed.
1587
+ *
1588
+ * ```ts
1589
+ * import { NavigationContainer } from '@react-navigation/native';
1590
+ * import ScaleBun from '@scalebun/react-native';
1591
+ *
1592
+ * const navigationRef = React.createRef();
1593
+ *
1594
+ * function App() {
1595
+ * useEffect(() => {
1596
+ * ScaleBun.setNavigationRef(navigationRef);
1597
+ * }, []);
1598
+ *
1599
+ * return (
1600
+ * <NavigationContainer ref={navigationRef}>
1601
+ * ...screens...
1602
+ * </NavigationContainer>
1603
+ * );
1604
+ * }
1605
+ * ```
1606
+ */
1607
+ public setNavigationRef(ref: any): void {
1608
+ noThrow(() => {
1609
+ // Always stash on the global so heuristic polling / late consumers resolve it.
1610
+ (globalThis as any).__scalebun_navigationRef = ref;
1611
+
1612
+ // Wire the LIVE AutoScreenDetector singleton (started by SDKBootstrapper in
1613
+ // production). _getAutoScreenDetector() is the debug-only handle and is null
1614
+ // when desktopDebug is off, so relying on it alone never wires the explicit
1615
+ // React-Navigation 'state' listener and degrades to slow heuristic polling.
1616
+ try {
1617
+ const { AutoScreenDetector } = require('../features/navigation/AutoScreenDetector');
1618
+ AutoScreenDetector.getInstance().setNavigationRef(ref);
1619
+ logger.info('[ScaleBun] Navigation ref set → auto screen detection active');
1620
+ } catch (err: any) {
1621
+ logger.debug('[ScaleBun] Navigation ref stashed (detector not ready):', err?.message);
1622
+ }
1623
+ });
1624
+ }
1625
+ }
1626
+
1627
+ /** Singleton Facade instance */
1628
+ const instance = new ScaleBunFacade();
1629
+ export default instance;
1630
+ export { ScaleBunFacade };