@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.
- package/LICENSE +21 -21
- package/README.md +65 -65
- package/android/build.gradle +86 -86
- package/android/consumer-rules.pro +28 -28
- package/android/src/main/AndroidManifest.xml +14 -14
- package/android/src/main/java/com/scalebun/core/crash/CrashStorage.kt +155 -41
- package/android/src/main/java/com/scalebun/core/crash/NativeCrashHandler.kt +93 -79
- package/android/src/main/java/com/scalebun/core/performance/ANRWatchdog.kt +100 -100
- package/android/src/main/java/com/scalebun/core/performance/AppStartCollector.kt +132 -132
- package/android/src/main/java/com/scalebun/core/performance/FrameMetricsCollector.kt +230 -230
- package/android/src/main/java/com/scalebun/core/performance/PerformanceCore.kt +165 -165
- package/android/src/main/java/com/scalebun/profiler/ProfilerModule.kt +398 -398
- package/android/src/main/java/com/scalebun/profiler/ProfilerPackage.kt +24 -24
- package/android/src/main/java/com/scalebun/profiler/collectors/CpuCollector.kt +161 -161
- package/android/src/main/java/com/scalebun/profiler/collectors/IncidentDetector.kt +223 -223
- package/android/src/main/java/com/scalebun/profiler/collectors/MemoryCollector.kt +157 -157
- package/android/src/main/java/com/scalebun/profiler/collectors/RenderCollector.kt +194 -194
- package/android/src/main/java/com/scalebun/profiler/collectors/SamplerScheduler.kt +218 -218
- package/android/src/main/java/com/scalebun/profiler/collectors/ThreadCollector.kt +142 -142
- package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkModule.kt +982 -966
- package/android/src/main/java/com/scalebun/replaysdk/ReplaySdkPackage.kt +24 -24
- package/android/src/main/java/com/scalebun/replaysdk/capture/CaptureReason.kt +47 -47
- package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureManager.kt +508 -508
- package/android/src/main/java/com/scalebun/replaysdk/capture/FrameCaptureScheduler.kt +187 -187
- package/android/src/main/java/com/scalebun/replaysdk/capture/UiStabilityDetector.kt +214 -214
- package/android/src/main/java/com/scalebun/replaysdk/core/ReplayConfig.kt +144 -144
- package/android/src/main/java/com/scalebun/replaysdk/core/ReplayLogger.kt +31 -31
- package/android/src/main/java/com/scalebun/replaysdk/core/SessionIdGenerator.kt +15 -15
- package/android/src/main/java/com/scalebun/replaysdk/models/ReplayModels.kt +88 -88
- package/android/src/main/java/com/scalebun/replaysdk/outbox/NativeOutbox.kt +541 -541
- package/android/src/main/java/com/scalebun/replaysdk/outbox/OutboxUploader.kt +407 -407
- package/android/src/main/java/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.kt +126 -126
- package/android/src/main/java/com/scalebun/replaysdk/session/SessionManager.kt +281 -281
- package/android/src/main/java/com/scalebun/replaysdk/storage/ReplayStorage.kt +136 -136
- package/android/src/main/java/com/scalebun/replaysdk/timeline/TimelineCollector.kt +28 -28
- package/android/src/main/java/com/scalebun/replaysdk/tracking/InteractionTracker.kt +419 -419
- package/android/src/main/java/com/scalebun/replaysdk/tracking/ScreenTracker.kt +20 -20
- package/android/src/main/java/com/scalebun/replaysdk/transport/ReplayTransport.kt +99 -99
- package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceRecorder.kt +121 -121
- package/android/src/main/java/com/scalebun/replaysdk/voice/VoiceTranscriber.kt +170 -104
- package/android/src/main/java/com/scalebun/rn/ScaleBunPackage.kt +113 -113
- package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashModule.kt +164 -100
- package/android/src/main/java/com/scalebun/rn/crash/ScaleBunCrashPackage.kt +22 -22
- package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngageModule.kt +579 -579
- package/android/src/main/java/com/scalebun/rn/engage/ScaleBunEngagePackage.kt +22 -22
- package/android/src/main/java/com/scalebun/rn/engage/ScaleBunNotificationPresenter.kt +110 -110
- package/android/src/main/java/com/scalebun/rn/ota/BundleDownloader.kt +170 -0
- package/android/src/main/java/com/scalebun/rn/ota/ScaleBunOtaModule.kt +284 -136
- package/android/src/main/java/com/scalebun/rn/ota/SlotManager.kt +311 -285
- package/android/src/main/java/com/scalebun/rn/performance/PerformanceModule.kt +206 -206
- package/android/src/main/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.kt +77 -77
- package/android/src/main/java/com/scalebun/rn/storage/ScaleBunStorageModule.kt +68 -68
- package/android/src/main/java/com/scalebun/storage/KvFileStore.kt +174 -174
- package/android/src/newarch/java/com/scalebun/profiler/ProfilerSpec.kt +12 -12
- package/android/src/newarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +12 -12
- package/android/src/newarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +15 -15
- package/android/src/newarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +16 -16
- package/android/src/newarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +12 -12
- package/android/src/newarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +14 -14
- package/android/src/newarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +16 -16
- package/android/src/oldarch/java/com/scalebun/profiler/ProfilerSpec.kt +34 -34
- package/android/src/oldarch/java/com/scalebun/replaysdk/ReplaySdkSpec.kt +76 -76
- package/android/src/oldarch/java/com/scalebun/rn/crash/ScaleBunCrashSpec.kt +21 -21
- package/android/src/oldarch/java/com/scalebun/rn/ota/ScaleBunOtaSpec.kt +31 -25
- package/android/src/oldarch/java/com/scalebun/rn/performance/PerformanceSpec.kt +27 -27
- package/android/src/oldarch/java/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.kt +18 -18
- package/android/src/oldarch/java/com/scalebun/rn/storage/ScaleBunStorageSpec.kt +26 -26
- package/bin/lib/iosCodemod.js +266 -266
- package/bin/scalebun.js +640 -640
- package/ios/Capture/InteractionTracker.swift +191 -191
- package/ios/Capture/PrivacyMaskProcessor.swift +158 -158
- package/ios/Capture/ScreenshotCaptureManager.swift +315 -315
- package/ios/Capture/WindowResolver.swift +63 -63
- package/ios/Core/ReplayConfig.swift +100 -100
- package/ios/Core/ReplayLogger.swift +22 -22
- package/ios/Core/SessionIdGenerator.swift +18 -18
- package/ios/Crash/ScaleBunCrashBridge.mm +69 -63
- package/ios/Crash/ScaleBunCrashHandler.swift +80 -67
- package/ios/Crash/ScaleBunCrashModule.swift +83 -69
- package/ios/Crash/ScaleBunCrashSignalBridge.h +49 -18
- package/ios/Crash/ScaleBunCrashSignalBridge.m +296 -131
- package/ios/Crash/ScaleBunCrashSignalStress.c +137 -0
- package/ios/Crash/ScaleBunCrashStorage.swift +121 -46
- package/ios/Engage/ScaleBunEngageBridge.m +32 -32
- package/ios/Engage/ScaleBunEngageModule.swift +250 -250
- package/ios/Engage/ScaleBunPushNotificationCenter.swift +185 -185
- package/ios/Ota/BundleDownloader.swift +182 -0
- package/ios/Ota/OtaSlotManager.swift +290 -264
- package/ios/Ota/ScaleBunOtaBridge.mm +77 -68
- package/ios/Ota/ScaleBunOtaEventsModule.swift +61 -0
- package/ios/Ota/ScaleBunOtaModule.swift +176 -123
- package/ios/Outbox/NativeOutbox.swift +598 -598
- package/ios/Outbox/OutboxUploader.swift +431 -431
- package/ios/Performance/ScaleBunPerformanceBridge.m +32 -32
- package/ios/Performance/ScaleBunPerformanceModule.swift +290 -290
- package/ios/PrivacyInfo.xcprivacy +97 -97
- package/ios/Profiler/ScaleBunProfilerBridge.m +55 -55
- package/ios/Profiler/ScaleBunProfilerModule.swift +972 -972
- package/ios/ReplaySdk-Bridging-Header.h +2 -2
- package/ios/ReplaySdk.swift +608 -608
- package/ios/ReplaySdkBridge.m +94 -94
- package/ios/Session/SessionManager.swift +203 -203
- package/ios/Skan/ScaleBunSkanBridge.m +14 -14
- package/ios/Skan/ScaleBunSkanModule.swift +61 -61
- package/ios/Storage/ReplayStorage.swift +61 -61
- package/ios/Storage/ScaleBunKvFileStore.swift +125 -125
- package/ios/Storage/ScaleBunStorageBridge.mm +72 -72
- package/ios/Storage/ScaleBunStorageModule.swift +57 -57
- package/ios/Transport/ReplayTransport.swift +70 -70
- package/ios/VoiceRecorder.swift +145 -145
- package/lib/commonjs/analytics/EventTracker.js +64 -36
- package/lib/commonjs/analytics/EventTracker.js.map +1 -1
- package/lib/commonjs/analytics/automaticEvents.js +7 -7
- package/lib/commonjs/analytics/automaticEvents.js.map +1 -1
- package/lib/commonjs/analytics/batching.js +24 -24
- package/lib/commonjs/analytics/batching.js.map +1 -1
- package/lib/commonjs/analytics/eventLane.js +13 -13
- package/lib/commonjs/analytics/eventLane.js.map +1 -1
- package/lib/commonjs/bootstrap/FeatureRegistry.js +17 -17
- package/lib/commonjs/bootstrap/FeatureRegistry.js.map +1 -1
- package/lib/commonjs/bootstrap/SDKBootstrapper.js +83 -56
- package/lib/commonjs/bootstrap/SDKBootstrapper.js.map +1 -1
- package/lib/commonjs/bucketing/fnv1a32.js +10 -10
- package/lib/commonjs/bucketing/fnv1a32.js.map +1 -1
- package/lib/commonjs/compat/codepush.js +6 -6
- package/lib/commonjs/compat/codepush.js.map +1 -1
- package/lib/commonjs/config/ConfigManager.js +20 -20
- package/lib/commonjs/config/ConfigManager.js.map +1 -1
- package/lib/commonjs/config/configTypes.js.map +1 -1
- package/lib/commonjs/core/architecture.js +23 -23
- package/lib/commonjs/core/architecture.js.map +1 -1
- package/lib/commonjs/core/clock/now.js +2 -2
- package/lib/commonjs/core/clock/now.js.map +1 -1
- package/lib/commonjs/core/config/defaults.js.map +1 -1
- package/lib/commonjs/core/config/schema.js +112 -104
- package/lib/commonjs/core/config/schema.js.map +1 -1
- package/lib/commonjs/core/constants/endpoints.js +7 -7
- package/lib/commonjs/core/constants/endpoints.js.map +1 -1
- package/lib/commonjs/core/constants/timings.js +5 -5
- package/lib/commonjs/core/constants/timings.js.map +1 -1
- package/lib/commonjs/core/constants/version.js +4 -4
- package/lib/commonjs/core/constants/version.js.map +1 -1
- package/lib/commonjs/core/context/app.js.map +1 -1
- package/lib/commonjs/core/context/device.js +130 -0
- package/lib/commonjs/core/context/device.js.map +1 -1
- package/lib/commonjs/core/context/session.js.map +1 -1
- package/lib/commonjs/core/context/user.js.map +1 -1
- package/lib/commonjs/core/contracts/IFeature.js.map +1 -1
- package/lib/commonjs/core/di/container.js.map +1 -1
- package/lib/commonjs/core/encoding/base64.js +9 -9
- package/lib/commonjs/core/encoding/base64.js.map +1 -1
- package/lib/commonjs/core/id/deviceId.js +4 -4
- package/lib/commonjs/core/id/deviceId.js.map +1 -1
- package/lib/commonjs/core/id/sessionId.js.map +1 -1
- package/lib/commonjs/core/lifecycle/appLifecycle.js.map +1 -1
- package/lib/commonjs/core/lifecycle/crashSafe.js +3 -3
- package/lib/commonjs/core/lifecycle/crashSafe.js.map +1 -1
- package/lib/commonjs/core/logger/errorClassification.js +30 -30
- package/lib/commonjs/core/logger/errorClassification.js.map +1 -1
- package/lib/commonjs/core/logger/internalLogger.js.map +1 -1
- package/lib/commonjs/core/logger/levels.js.map +1 -1
- package/lib/commonjs/crypto/hmacSha256.js +6 -6
- package/lib/commonjs/crypto/hmacSha256.js.map +1 -1
- package/lib/commonjs/debug/bootstrap.js +26 -26
- package/lib/commonjs/debug/bootstrap.js.map +1 -1
- package/lib/commonjs/debug/commands.js +10 -10
- package/lib/commonjs/debug/commands.js.map +1 -1
- package/lib/commonjs/debug/configBuilder.js +6 -6
- package/lib/commonjs/debug/configBuilder.js.map +1 -1
- package/lib/commonjs/debug/exportBridge.js +17 -17
- package/lib/commonjs/debug/exportBridge.js.map +1 -1
- package/lib/commonjs/debug/hostResolver.js +10 -10
- package/lib/commonjs/debug/hostResolver.js.map +1 -1
- package/lib/commonjs/debug/index.js.map +1 -1
- package/lib/commonjs/debug/metrics.js.map +1 -1
- package/lib/commonjs/debug/perf.js +11 -11
- package/lib/commonjs/debug/perf.js.map +1 -1
- package/lib/commonjs/debug/perfWiring.js +10 -10
- package/lib/commonjs/debug/perfWiring.js.map +1 -1
- package/lib/commonjs/debug/protocol.js.map +1 -1
- package/lib/commonjs/debug/redaction.js +26 -26
- package/lib/commonjs/debug/redaction.js.map +1 -1
- package/lib/commonjs/debug/replayWiring.js +13 -12
- package/lib/commonjs/debug/replayWiring.js.map +1 -1
- package/lib/commonjs/debug/screenTracking.js +7 -7
- package/lib/commonjs/debug/screenTracking.js.map +1 -1
- package/lib/commonjs/debug/sessionWiring.js +8 -8
- package/lib/commonjs/debug/sessionWiring.js.map +1 -1
- package/lib/commonjs/debug/stream.js +26 -26
- package/lib/commonjs/debug/stream.js.map +1 -1
- package/lib/commonjs/debug/transport.js +24 -24
- package/lib/commonjs/debug/transport.js.map +1 -1
- package/lib/commonjs/features/bugreport/BugReportFeature.js +112 -0
- package/lib/commonjs/features/bugreport/BugReportFeature.js.map +1 -0
- package/lib/commonjs/features/bugreport/buildPayload.js +97 -0
- package/lib/commonjs/features/bugreport/buildPayload.js.map +1 -0
- package/lib/commonjs/features/bugreport/index.js.map +1 -1
- package/lib/commonjs/features/crash/CrashFeature.js +27 -9
- package/lib/commonjs/features/crash/CrashFeature.js.map +1 -1
- package/lib/commonjs/features/crash/CrashReporter.js +53 -29
- package/lib/commonjs/features/crash/CrashReporter.js.map +1 -1
- package/lib/commonjs/features/crash/NativeCrashFeature.js +7 -7
- package/lib/commonjs/features/crash/NativeCrashFeature.js.map +1 -1
- package/lib/commonjs/features/crash/capture.js +27 -9
- package/lib/commonjs/features/crash/capture.js.map +1 -1
- package/lib/commonjs/features/crash/globalHandler.js +11 -11
- package/lib/commonjs/features/crash/globalHandler.js.map +1 -1
- package/lib/commonjs/features/crash/index.js.map +1 -1
- package/lib/commonjs/features/crash/nativeCrashBridge.js +179 -44
- package/lib/commonjs/features/crash/nativeCrashBridge.js.map +1 -1
- package/lib/commonjs/features/crash/rejectionHandler.js +123 -0
- package/lib/commonjs/features/crash/rejectionHandler.js.map +1 -0
- package/lib/commonjs/features/engage/EngageAnchor.js +3 -3
- package/lib/commonjs/features/engage/EngageAnchor.js.map +1 -1
- package/lib/commonjs/features/engage/EngageArchetypeRenderers.js +19 -19
- package/lib/commonjs/features/engage/EngageArchetypeRenderers.js.map +1 -1
- package/lib/commonjs/features/engage/EngageInAppView.js +35 -35
- package/lib/commonjs/features/engage/EngageInAppView.js.map +1 -1
- package/lib/commonjs/features/engage/EngageInlinePlacement.js +7 -7
- package/lib/commonjs/features/engage/EngageInlinePlacement.js.map +1 -1
- package/lib/commonjs/features/engage/EngagePromptProvider.js +124 -88
- package/lib/commonjs/features/engage/EngagePromptProvider.js.map +1 -1
- package/lib/commonjs/features/engage/EngagePromptView.js +65 -32
- package/lib/commonjs/features/engage/EngagePromptView.js.map +1 -1
- package/lib/commonjs/features/engage/EngageTransport.js +79 -79
- package/lib/commonjs/features/engage/EngageTransport.js.map +1 -1
- package/lib/commonjs/features/engage/EngageVariantContent.js +10 -10
- package/lib/commonjs/features/engage/EngageVariantContent.js.map +1 -1
- package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js +7 -7
- package/lib/commonjs/features/engage/__test-support__/reactNativeStub.js.map +1 -1
- package/lib/commonjs/features/engage/attachmentCapture.js +12 -12
- package/lib/commonjs/features/engage/attachmentCapture.js.map +1 -1
- package/lib/commonjs/features/engage/captureVoiceAttachment.js +20 -20
- package/lib/commonjs/features/engage/captureVoiceAttachment.js.map +1 -1
- package/lib/commonjs/features/engage/engageCoachmarkTour.js +4 -4
- package/lib/commonjs/features/engage/engageCoachmarkTour.js.map +1 -1
- package/lib/commonjs/features/engage/engageGameLogic.js.map +1 -1
- package/lib/commonjs/features/engage/engageMediaSizing.js +15 -15
- package/lib/commonjs/features/engage/engageMediaSizing.js.map +1 -1
- package/lib/commonjs/features/engage/engageMultiStepSheet.js +6 -6
- package/lib/commonjs/features/engage/engageMultiStepSheet.js.map +1 -1
- package/lib/commonjs/features/engage/engageOutcome.js +6 -6
- package/lib/commonjs/features/engage/engageOutcome.js.map +1 -1
- package/lib/commonjs/features/engage/engagePushTokenBridge.js +20 -20
- package/lib/commonjs/features/engage/engagePushTokenBridge.js.map +1 -1
- package/lib/commonjs/features/engage/engageShakeBridge.js +16 -16
- package/lib/commonjs/features/engage/engageShakeBridge.js.map +1 -1
- package/lib/commonjs/features/engage/engageSignals.js.map +1 -1
- package/lib/commonjs/features/engage/engageStoreReviewBridge.js +19 -19
- package/lib/commonjs/features/engage/engageStoreReviewBridge.js.map +1 -1
- package/lib/commonjs/features/engage/engageTestSeenStore.js +29 -29
- package/lib/commonjs/features/engage/engageTestSeenStore.js.map +1 -1
- package/lib/commonjs/features/engage/engageThrottle.js +117 -86
- package/lib/commonjs/features/engage/engageThrottle.js.map +1 -1
- package/lib/commonjs/features/engage/engageTriggerEngine.js +17 -7
- package/lib/commonjs/features/engage/engageTriggerEngine.js.map +1 -1
- package/lib/commonjs/features/engage/engageTypes.js +33 -33
- package/lib/commonjs/features/engage/engageTypes.js.map +1 -1
- package/lib/commonjs/features/engage/engageVariantResolver.js +13 -13
- package/lib/commonjs/features/engage/engageVariantResolver.js.map +1 -1
- package/lib/commonjs/features/engage/engageWindowInsets.js +10 -10
- package/lib/commonjs/features/engage/engageWindowInsets.js.map +1 -1
- package/lib/commonjs/features/engage/gestureTriggerDetector.js.map +1 -1
- package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js +16 -16
- package/lib/commonjs/features/engage/transcription/TranscriptionProvider.js.map +1 -1
- package/lib/commonjs/features/install-referrer/installReferrer.js +26 -26
- package/lib/commonjs/features/install-referrer/installReferrer.js.map +1 -1
- package/lib/commonjs/features/journey/ScaleBunDebugRoot.js +30 -29
- package/lib/commonjs/features/journey/ScaleBunDebugRoot.js.map +1 -1
- package/lib/commonjs/features/journey/ScaleBunFlatList.js +15 -15
- package/lib/commonjs/features/journey/ScaleBunFlatList.js.map +1 -1
- package/lib/commonjs/features/journey/ScaleBunImpression.js +22 -22
- package/lib/commonjs/features/journey/ScaleBunImpression.js.map +1 -1
- package/lib/commonjs/features/journey/ScaleBunScrollView.js +20 -20
- package/lib/commonjs/features/journey/ScaleBunScrollView.js.map +1 -1
- package/lib/commonjs/features/journey/ScaleBunSectionList.js +15 -15
- package/lib/commonjs/features/journey/ScaleBunSectionList.js.map +1 -1
- package/lib/commonjs/features/journey/calibrationContext.js +12 -12
- package/lib/commonjs/features/journey/calibrationContext.js.map +1 -1
- package/lib/commonjs/features/journey/gestureBuffer.js +9 -9
- package/lib/commonjs/features/journey/gestureBuffer.js.map +1 -1
- package/lib/commonjs/features/journey/gestureDetector.js +10 -10
- package/lib/commonjs/features/journey/gestureDetector.js.map +1 -1
- package/lib/commonjs/features/journey/impression.js +18 -18
- package/lib/commonjs/features/journey/impression.js.map +1 -1
- package/lib/commonjs/features/journey/journeyManager.js +6 -6
- package/lib/commonjs/features/journey/journeyManager.js.map +1 -1
- package/lib/commonjs/features/journey/journeyTypes.js +5 -5
- package/lib/commonjs/features/journey/journeyTypes.js.map +1 -1
- package/lib/commonjs/features/journey/navDetector.js +7 -7
- package/lib/commonjs/features/journey/navDetector.js.map +1 -1
- package/lib/commonjs/features/journey/screenshotHelper.js +7 -7
- package/lib/commonjs/features/journey/screenshotHelper.js.map +1 -1
- package/lib/commonjs/features/journey/targetRegistry.js +17 -17
- package/lib/commonjs/features/journey/targetRegistry.js.map +1 -1
- package/lib/commonjs/features/journey/touchTarget.js +29 -29
- package/lib/commonjs/features/journey/touchTarget.js.map +1 -1
- package/lib/commonjs/features/navigation/AutoScreenDetector.js +114 -71
- package/lib/commonjs/features/navigation/AutoScreenDetector.js.map +1 -1
- package/lib/commonjs/features/network/NetworkFeature.js +23 -23
- package/lib/commonjs/features/network/NetworkFeature.js.map +1 -1
- package/lib/commonjs/features/network/index.js +5 -5
- package/lib/commonjs/features/network/index.js.map +1 -1
- package/lib/commonjs/features/ota/OtaEventEmitter.js +21 -21
- package/lib/commonjs/features/ota/OtaEventEmitter.js.map +1 -1
- package/lib/commonjs/features/ota/OtaOrchestrator.js +595 -42
- package/lib/commonjs/features/ota/OtaOrchestrator.js.map +1 -1
- package/lib/commonjs/features/ota/OtaTypes.js.map +1 -1
- package/lib/commonjs/features/ota/deviceAttributes.js +48 -0
- package/lib/commonjs/features/ota/deviceAttributes.js.map +1 -0
- package/lib/commonjs/features/ota/environment.js +172 -0
- package/lib/commonjs/features/ota/environment.js.map +1 -0
- package/lib/commonjs/features/ota/geoCountry.js +93 -0
- package/lib/commonjs/features/ota/geoCountry.js.map +1 -0
- package/lib/commonjs/features/ota/retry.js +96 -0
- package/lib/commonjs/features/ota/retry.js.map +1 -0
- package/lib/commonjs/features/ota/signature.js +115 -0
- package/lib/commonjs/features/ota/signature.js.map +1 -0
- package/lib/commonjs/features/ota/useOtaUpdate.js +18 -15
- package/lib/commonjs/features/ota/useOtaUpdate.js.map +1 -1
- package/lib/commonjs/features/performance/PerformanceFeature.js +49 -35
- package/lib/commonjs/features/performance/PerformanceFeature.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js +13 -13
- package/lib/commonjs/features/performance/collectors/AppLaunchCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js +32 -32
- package/lib/commonjs/features/performance/collectors/AutoScreenLoadCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js +13 -13
- package/lib/commonjs/features/performance/collectors/CustomTraceCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js +80 -20
- package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/JsStallCollector.js +12 -12
- package/lib/commonjs/features/performance/collectors/JsStallCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js +10 -10
- package/lib/commonjs/features/performance/collectors/NetworkPerfCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js +11 -11
- package/lib/commonjs/features/performance/collectors/ScreenLoadCollector.js.map +1 -1
- package/lib/commonjs/features/performance/collectors/UiHangCollector.js +5 -5
- package/lib/commonjs/features/performance/collectors/UiHangCollector.js.map +1 -1
- package/lib/commonjs/features/performance/config.js +11 -11
- package/lib/commonjs/features/performance/config.js.map +1 -1
- package/lib/commonjs/features/performance/getNativePerformanceModule.js +11 -11
- package/lib/commonjs/features/performance/getNativePerformanceModule.js.map +1 -1
- package/lib/commonjs/features/performance/index.js.map +1 -1
- package/lib/commonjs/features/performance/metrics/MetricsEngine.js +13 -13
- package/lib/commonjs/features/performance/metrics/MetricsEngine.js.map +1 -1
- package/lib/commonjs/features/performance/models.js +8 -8
- package/lib/commonjs/features/performance/models.js.map +1 -1
- package/lib/commonjs/features/performance/transport/PerformanceTransport.js +31 -6
- package/lib/commonjs/features/performance/transport/PerformanceTransport.js.map +1 -1
- package/lib/commonjs/features/profiler/ProfilerFeature.js +53 -53
- package/lib/commonjs/features/profiler/ProfilerFeature.js.map +1 -1
- package/lib/commonjs/features/profiler/config.js +15 -15
- package/lib/commonjs/features/profiler/config.js.map +1 -1
- package/lib/commonjs/features/profiler/contracts.js +22 -22
- package/lib/commonjs/features/profiler/contracts.js.map +1 -1
- package/lib/commonjs/features/profiler/index.js.map +1 -1
- package/lib/commonjs/features/profiler/models.js +44 -44
- package/lib/commonjs/features/profiler/models.js.map +1 -1
- package/lib/commonjs/features/profiler/transport/ProfilerTransport.js +9 -9
- package/lib/commonjs/features/profiler/transport/ProfilerTransport.js.map +1 -1
- package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js +17 -17
- package/lib/commonjs/features/replay/bridge/adapters/bridgeAdapter.js.map +1 -1
- package/lib/commonjs/features/replay/bridge/eventEmitter.js +8 -8
- package/lib/commonjs/features/replay/bridge/eventEmitter.js.map +1 -1
- package/lib/commonjs/features/replay/bridge/nativeModule.js +20 -20
- package/lib/commonjs/features/replay/bridge/nativeModule.js.map +1 -1
- package/lib/commonjs/features/replay/core/clock/clock.js +6 -6
- package/lib/commonjs/features/replay/core/clock/clock.js.map +1 -1
- package/lib/commonjs/features/replay/core/config/defaults.js +2 -2
- package/lib/commonjs/features/replay/core/config/defaults.js.map +1 -1
- package/lib/commonjs/features/replay/core/config/validator.js +5 -5
- package/lib/commonjs/features/replay/core/config/validator.js.map +1 -1
- package/lib/commonjs/features/replay/core/env/environmentDetector.js +10 -10
- package/lib/commonjs/features/replay/core/env/environmentDetector.js.map +1 -1
- package/lib/commonjs/features/replay/core/errors/safeCall.js +4 -4
- package/lib/commonjs/features/replay/core/errors/safeCall.js.map +1 -1
- package/lib/commonjs/features/replay/core/ids/sessionId.js +5 -5
- package/lib/commonjs/features/replay/core/ids/sessionId.js.map +1 -1
- package/lib/commonjs/features/replay/core/logger/logger.js +5 -5
- package/lib/commonjs/features/replay/core/logger/logger.js.map +1 -1
- package/lib/commonjs/features/replay/core/privacy/privacyTypes.js +4 -4
- package/lib/commonjs/features/replay/core/privacy/privacyTypes.js.map +1 -1
- package/lib/commonjs/features/replay/core/queue/boundedQueue.js +5 -5
- package/lib/commonjs/features/replay/core/queue/boundedQueue.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js +59 -59
- package/lib/commonjs/features/replay/integrations/alert/alertInstrumentation.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js +19 -19
- package/lib/commonjs/features/replay/integrations/logs/consoleIntegration.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/network/networkAdapter.js +30 -30
- package/lib/commonjs/features/replay/integrations/network/networkAdapter.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js +19 -19
- package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js +16 -16
- package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
- package/lib/commonjs/features/replay/pipeline/batching/batchManager.js +5 -5
- package/lib/commonjs/features/replay/pipeline/batching/batchManager.js.map +1 -1
- package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js +5 -5
- package/lib/commonjs/features/replay/pipeline/envelope/envelopeBuilder.js.map +1 -1
- package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js +4 -4
- package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
- package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js +7 -7
- package/lib/commonjs/features/replay/pipeline/transport/transportTypes.js.map +1 -1
- package/lib/commonjs/features/replay/public/api.js +21 -21
- package/lib/commonjs/features/replay/public/api.js.map +1 -1
- package/lib/commonjs/features/replay/public/enums.js +5 -5
- package/lib/commonjs/features/replay/public/enums.js.map +1 -1
- package/lib/commonjs/features/replay/public/types.js.map +1 -1
- package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js +5 -5
- package/lib/commonjs/features/replay/replay/breadcrumbs/breadcrumbCollector.js.map +1 -1
- package/lib/commonjs/features/replay/replay/frames/frameModels.js +4 -4
- package/lib/commonjs/features/replay/replay/frames/frameModels.js.map +1 -1
- package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js +10 -10
- package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
- package/lib/commonjs/features/replay/replay/timeline/timelineModels.js +4 -4
- package/lib/commonjs/features/replay/replay/timeline/timelineModels.js.map +1 -1
- package/lib/commonjs/features/replay/transport/BackendReplayTransport.js +13 -13
- package/lib/commonjs/features/replay/transport/BackendReplayTransport.js.map +1 -1
- package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js +8 -8
- package/lib/commonjs/features/replay/transport/CompositeReplayTransport.js.map +1 -1
- package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js +14 -14
- package/lib/commonjs/features/replay/transport/DesktopReplayTransport.js.map +1 -1
- package/lib/commonjs/features/replay/transport/ReplayTransport.js.map +1 -1
- package/lib/commonjs/features/session/BackendSessionAdapter.js +486 -164
- package/lib/commonjs/features/session/BackendSessionAdapter.js.map +1 -1
- package/lib/commonjs/features/session/DesktopSessionTransport.js +14 -14
- package/lib/commonjs/features/session/DesktopSessionTransport.js.map +1 -1
- package/lib/commonjs/features/session/JourneyEventPipeline.js +20 -19
- package/lib/commonjs/features/session/JourneyEventPipeline.js.map +1 -1
- package/lib/commonjs/features/session/ReplayCaptureManager.js +169 -123
- package/lib/commonjs/features/session/ReplayCaptureManager.js.map +1 -1
- package/lib/commonjs/features/session/ScrollTracker.js +17 -17
- package/lib/commonjs/features/session/ScrollTracker.js.map +1 -1
- package/lib/commonjs/features/session/SessionManager.js +185 -155
- package/lib/commonjs/features/session/SessionManager.js.map +1 -1
- package/lib/commonjs/features/session/SyncDecisionEngine.js +23 -23
- package/lib/commonjs/features/session/SyncDecisionEngine.js.map +1 -1
- package/lib/commonjs/features/session/index.js.map +1 -1
- package/lib/commonjs/features/session/nativeCapture.js +9 -9
- package/lib/commonjs/features/session/nativeCapture.js.map +1 -1
- package/lib/commonjs/features/session/outboxFrameCapture.js +18 -17
- package/lib/commonjs/features/session/outboxFrameCapture.js.map +1 -1
- package/lib/commonjs/features/session/sessionTypes.js +44 -44
- package/lib/commonjs/features/session/sessionTypes.js.map +1 -1
- package/lib/commonjs/features/skan/skanBridge.js +11 -11
- package/lib/commonjs/features/skan/skanBridge.js.map +1 -1
- package/lib/commonjs/features/skan/skanConversionManager.js +23 -23
- package/lib/commonjs/features/skan/skanConversionManager.js.map +1 -1
- package/lib/commonjs/index.js +20 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/integrations/fetch/fetchInterceptor.js +21 -21
- package/lib/commonjs/integrations/fetch/fetchInterceptor.js.map +1 -1
- package/lib/commonjs/integrations/navigation/screenTracker.js.map +1 -1
- package/lib/commonjs/integrations/network/bodyCapture.js +69 -69
- package/lib/commonjs/integrations/network/bodyCapture.js.map +1 -1
- package/lib/commonjs/integrations/xhr/xhrInterceptor.js +24 -24
- package/lib/commonjs/integrations/xhr/xhrInterceptor.js.map +1 -1
- package/lib/commonjs/metro/index.js +37 -37
- package/lib/commonjs/metro/index.js.map +1 -1
- package/lib/commonjs/metro/optionalDependencyStub.js.map +1 -1
- package/lib/commonjs/metro/optionalModules.js +16 -16
- package/lib/commonjs/metro/optionalModules.js.map +1 -1
- package/lib/commonjs/pipeline/dispatcher/dispatcher.js.map +1 -1
- package/lib/commonjs/pipeline/envelope/envelope.js.map +1 -1
- package/lib/commonjs/pipeline/envelope/serializer.js.map +1 -1
- package/lib/commonjs/pipeline/processors/dedupe.js.map +1 -1
- package/lib/commonjs/pipeline/processors/enrich.js.map +1 -1
- package/lib/commonjs/pipeline/processors/sampling.js.map +1 -1
- package/lib/commonjs/pipeline/processors/sanitize.js.map +1 -1
- package/lib/commonjs/pipeline/queue/flushQueue.js +4 -4
- package/lib/commonjs/pipeline/queue/flushQueue.js.map +1 -1
- package/lib/commonjs/pipeline/queue/memoryQueue.js.map +1 -1
- package/lib/commonjs/pipeline/queue/persistentQueue.js +80 -80
- package/lib/commonjs/pipeline/queue/persistentQueue.js.map +1 -1
- package/lib/commonjs/pipeline/queue/queuePolicy.js.map +1 -1
- package/lib/commonjs/pipeline/scheduler/flushScheduler.js.map +1 -1
- package/lib/commonjs/pipeline/scheduler/retryPolicy.js +2 -2
- package/lib/commonjs/pipeline/scheduler/retryPolicy.js.map +1 -1
- package/lib/commonjs/public/ScaleBunErrorBoundary.js +79 -0
- package/lib/commonjs/public/ScaleBunErrorBoundary.js.map +1 -0
- package/lib/commonjs/public/ScaleBunFacade.js +424 -276
- package/lib/commonjs/public/ScaleBunFacade.js.map +1 -1
- package/lib/commonjs/public/ScaleBunProvider.js +3 -3
- package/lib/commonjs/public/ScaleBunProvider.js.map +1 -1
- package/lib/commonjs/public/typedTracker.js +36 -36
- package/lib/commonjs/public/typedTracker.js.map +1 -1
- package/lib/commonjs/public/types.js.map +1 -1
- package/lib/commonjs/push/PushManager.js +21 -21
- package/lib/commonjs/push/PushManager.js.map +1 -1
- package/lib/commonjs/push/adapters/ManualAdapter.js +14 -14
- package/lib/commonjs/push/adapters/ManualAdapter.js.map +1 -1
- package/lib/commonjs/push/adapters/NativeBridgeAdapter.js +17 -17
- package/lib/commonjs/push/adapters/NativeBridgeAdapter.js.map +1 -1
- package/lib/commonjs/push/adapters/NoopAdapter.js +5 -5
- package/lib/commonjs/push/adapters/NoopAdapter.js.map +1 -1
- package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js +17 -17
- package/lib/commonjs/push/adapters/RNFirebaseMessagingAdapter.js.map +1 -1
- package/lib/commonjs/push/adapters/loadMessaging.js +12 -12
- package/lib/commonjs/push/adapters/loadMessaging.js.map +1 -1
- package/lib/commonjs/push/adapters/loadNotifee.js +12 -12
- package/lib/commonjs/push/adapters/loadNotifee.js.map +1 -1
- package/lib/commonjs/push/adapters/selectAdapter.js +14 -14
- package/lib/commonjs/push/adapters/selectAdapter.js.map +1 -1
- package/lib/commonjs/push/detect/capabilities.js +19 -19
- package/lib/commonjs/push/detect/capabilities.js.map +1 -1
- package/lib/commonjs/push/index.js.map +1 -1
- package/lib/commonjs/push/native/nativeNotifications.js +32 -32
- package/lib/commonjs/push/native/nativeNotifications.js.map +1 -1
- package/lib/commonjs/push/types.js.map +1 -1
- package/lib/commonjs/specs/NativeReplaySdk.js +18 -18
- package/lib/commonjs/specs/NativeReplaySdk.js.map +1 -1
- package/lib/commonjs/specs/NativeScaleBunCrash.js +19 -19
- package/lib/commonjs/specs/NativeScaleBunCrash.js.map +1 -1
- package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js +14 -14
- package/lib/commonjs/specs/NativeScaleBunInstallReferrer.js.map +1 -1
- package/lib/commonjs/specs/NativeScaleBunOta.js +21 -21
- package/lib/commonjs/specs/NativeScaleBunOta.js.map +1 -1
- package/lib/commonjs/specs/NativeScaleBunPerformance.js +15 -15
- package/lib/commonjs/specs/NativeScaleBunPerformance.js.map +1 -1
- package/lib/commonjs/specs/NativeScaleBunProfiler.js +16 -16
- package/lib/commonjs/specs/NativeScaleBunProfiler.js.map +1 -1
- package/lib/commonjs/specs/NativeScaleBunStorage.js +29 -29
- package/lib/commonjs/specs/NativeScaleBunStorage.js.map +1 -1
- package/lib/commonjs/storage/StorageBackend.js +83 -83
- package/lib/commonjs/storage/StorageBackend.js.map +1 -1
- package/lib/commonjs/storage/db/sqlite.js.map +1 -1
- package/lib/commonjs/storage/files/fileStore.js.map +1 -1
- package/lib/commonjs/transport/auth/sdkSession.js.map +1 -1
- package/lib/commonjs/transport/backoff/exponentialJitter.js +2 -2
- package/lib/commonjs/transport/backoff/exponentialJitter.js.map +1 -1
- package/lib/commonjs/transport/http/endpoints.js.map +1 -1
- package/lib/commonjs/transport/http/httpClient.js +3 -3
- package/lib/commonjs/transport/http/httpClient.js.map +1 -1
- package/lib/commonjs/transport/rateLimit/retryAfter.js.map +1 -1
- package/lib/commonjs/transport/signing/requestSigner.js.map +1 -1
- package/lib/commonjs/vendor/protocol/index.js +74 -74
- package/lib/commonjs/vendor/protocol/index.js.map +1 -1
- package/lib/commonjs/vendor/protocol/internal/validation.js +23 -23
- package/lib/commonjs/vendor/protocol/internal/validation.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/bridge.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/config.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/events.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/features.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/index.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/platform.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/session-boundary.js.map +1 -1
- package/lib/commonjs/vendor/sdk-contracts/session.js.map +1 -1
- package/lib/commonjs/vendor/vendor.manifest +10 -10
- package/lib/module/analytics/EventTracker.js +63 -35
- package/lib/module/analytics/EventTracker.js.map +1 -1
- package/lib/module/analytics/automaticEvents.js +7 -7
- package/lib/module/analytics/automaticEvents.js.map +1 -1
- package/lib/module/analytics/batching.js +24 -24
- package/lib/module/analytics/batching.js.map +1 -1
- package/lib/module/analytics/eventLane.js +13 -13
- package/lib/module/analytics/eventLane.js.map +1 -1
- package/lib/module/bootstrap/FeatureRegistry.js +17 -17
- package/lib/module/bootstrap/FeatureRegistry.js.map +1 -1
- package/lib/module/bootstrap/SDKBootstrapper.js +81 -54
- package/lib/module/bootstrap/SDKBootstrapper.js.map +1 -1
- package/lib/module/bucketing/fnv1a32.js +10 -10
- package/lib/module/bucketing/fnv1a32.js.map +1 -1
- package/lib/module/compat/codepush.js +6 -6
- package/lib/module/compat/codepush.js.map +1 -1
- package/lib/module/config/ConfigManager.js +20 -20
- package/lib/module/config/ConfigManager.js.map +1 -1
- package/lib/module/config/configTypes.js.map +1 -1
- package/lib/module/core/architecture.js +23 -23
- package/lib/module/core/architecture.js.map +1 -1
- package/lib/module/core/clock/now.js +2 -2
- package/lib/module/core/clock/now.js.map +1 -1
- package/lib/module/core/config/defaults.js.map +1 -1
- package/lib/module/core/config/schema.js +112 -104
- package/lib/module/core/config/schema.js.map +1 -1
- package/lib/module/core/constants/endpoints.js +7 -7
- package/lib/module/core/constants/endpoints.js.map +1 -1
- package/lib/module/core/constants/timings.js +5 -5
- package/lib/module/core/constants/timings.js.map +1 -1
- package/lib/module/core/constants/version.js +4 -4
- package/lib/module/core/constants/version.js.map +1 -1
- package/lib/module/core/context/app.js.map +1 -1
- package/lib/module/core/context/device.js +119 -0
- package/lib/module/core/context/device.js.map +1 -1
- package/lib/module/core/context/session.js.map +1 -1
- package/lib/module/core/context/user.js.map +1 -1
- package/lib/module/core/contracts/IFeature.js.map +1 -1
- package/lib/module/core/di/container.js.map +1 -1
- package/lib/module/core/encoding/base64.js +9 -9
- package/lib/module/core/encoding/base64.js.map +1 -1
- package/lib/module/core/id/deviceId.js +4 -4
- package/lib/module/core/id/deviceId.js.map +1 -1
- package/lib/module/core/id/sessionId.js.map +1 -1
- package/lib/module/core/lifecycle/appLifecycle.js.map +1 -1
- package/lib/module/core/lifecycle/crashSafe.js +3 -3
- package/lib/module/core/lifecycle/crashSafe.js.map +1 -1
- package/lib/module/core/logger/errorClassification.js +30 -30
- package/lib/module/core/logger/errorClassification.js.map +1 -1
- package/lib/module/core/logger/internalLogger.js.map +1 -1
- package/lib/module/core/logger/levels.js.map +1 -1
- package/lib/module/crypto/hmacSha256.js +6 -6
- package/lib/module/crypto/hmacSha256.js.map +1 -1
- package/lib/module/debug/bootstrap.js +26 -26
- package/lib/module/debug/bootstrap.js.map +1 -1
- package/lib/module/debug/commands.js +10 -10
- package/lib/module/debug/commands.js.map +1 -1
- package/lib/module/debug/configBuilder.js +6 -6
- package/lib/module/debug/configBuilder.js.map +1 -1
- package/lib/module/debug/exportBridge.js +17 -17
- package/lib/module/debug/exportBridge.js.map +1 -1
- package/lib/module/debug/hostResolver.js +10 -10
- package/lib/module/debug/hostResolver.js.map +1 -1
- package/lib/module/debug/index.js +5 -5
- package/lib/module/debug/index.js.map +1 -1
- package/lib/module/debug/metrics.js.map +1 -1
- package/lib/module/debug/perf.js +11 -11
- package/lib/module/debug/perf.js.map +1 -1
- package/lib/module/debug/perfWiring.js +10 -10
- package/lib/module/debug/perfWiring.js.map +1 -1
- package/lib/module/debug/protocol.js +11 -11
- package/lib/module/debug/protocol.js.map +1 -1
- package/lib/module/debug/redaction.js +26 -26
- package/lib/module/debug/redaction.js.map +1 -1
- package/lib/module/debug/replayWiring.js +13 -12
- package/lib/module/debug/replayWiring.js.map +1 -1
- package/lib/module/debug/screenTracking.js +7 -7
- package/lib/module/debug/screenTracking.js.map +1 -1
- package/lib/module/debug/sessionWiring.js +8 -8
- package/lib/module/debug/sessionWiring.js.map +1 -1
- package/lib/module/debug/stream.js +26 -26
- package/lib/module/debug/stream.js.map +1 -1
- package/lib/module/debug/transport.js +24 -24
- package/lib/module/debug/transport.js.map +1 -1
- package/lib/module/features/bugreport/BugReportFeature.js +105 -0
- package/lib/module/features/bugreport/BugReportFeature.js.map +1 -0
- package/lib/module/features/bugreport/buildPayload.js +91 -0
- package/lib/module/features/bugreport/buildPayload.js.map +1 -0
- package/lib/module/features/bugreport/index.js.map +1 -1
- package/lib/module/features/crash/CrashFeature.js +27 -9
- package/lib/module/features/crash/CrashFeature.js.map +1 -1
- package/lib/module/features/crash/CrashReporter.js +53 -29
- package/lib/module/features/crash/CrashReporter.js.map +1 -1
- package/lib/module/features/crash/NativeCrashFeature.js +7 -7
- package/lib/module/features/crash/NativeCrashFeature.js.map +1 -1
- package/lib/module/features/crash/capture.js +28 -9
- package/lib/module/features/crash/capture.js.map +1 -1
- package/lib/module/features/crash/globalHandler.js +11 -11
- package/lib/module/features/crash/globalHandler.js.map +1 -1
- package/lib/module/features/crash/index.js.map +1 -1
- package/lib/module/features/crash/nativeCrashBridge.js +177 -44
- package/lib/module/features/crash/nativeCrashBridge.js.map +1 -1
- package/lib/module/features/crash/rejectionHandler.js +116 -0
- package/lib/module/features/crash/rejectionHandler.js.map +1 -0
- package/lib/module/features/engage/EngageAnchor.js +3 -3
- package/lib/module/features/engage/EngageAnchor.js.map +1 -1
- package/lib/module/features/engage/EngageArchetypeRenderers.js +19 -19
- package/lib/module/features/engage/EngageArchetypeRenderers.js.map +1 -1
- package/lib/module/features/engage/EngageInAppView.js +35 -35
- package/lib/module/features/engage/EngageInAppView.js.map +1 -1
- package/lib/module/features/engage/EngageInlinePlacement.js +7 -7
- package/lib/module/features/engage/EngageInlinePlacement.js.map +1 -1
- package/lib/module/features/engage/EngagePromptProvider.js +124 -88
- package/lib/module/features/engage/EngagePromptProvider.js.map +1 -1
- package/lib/module/features/engage/EngagePromptView.js +65 -32
- package/lib/module/features/engage/EngagePromptView.js.map +1 -1
- package/lib/module/features/engage/EngageTransport.js +79 -79
- package/lib/module/features/engage/EngageTransport.js.map +1 -1
- package/lib/module/features/engage/EngageVariantContent.js +10 -10
- package/lib/module/features/engage/EngageVariantContent.js.map +1 -1
- package/lib/module/features/engage/__test-support__/reactNativeStub.js +7 -7
- package/lib/module/features/engage/__test-support__/reactNativeStub.js.map +1 -1
- package/lib/module/features/engage/attachmentCapture.js +12 -12
- package/lib/module/features/engage/attachmentCapture.js.map +1 -1
- package/lib/module/features/engage/captureVoiceAttachment.js +20 -20
- package/lib/module/features/engage/captureVoiceAttachment.js.map +1 -1
- package/lib/module/features/engage/engageCoachmarkTour.js +4 -4
- package/lib/module/features/engage/engageCoachmarkTour.js.map +1 -1
- package/lib/module/features/engage/engageGameLogic.js.map +1 -1
- package/lib/module/features/engage/engageMediaSizing.js +15 -15
- package/lib/module/features/engage/engageMediaSizing.js.map +1 -1
- package/lib/module/features/engage/engageMultiStepSheet.js +6 -6
- package/lib/module/features/engage/engageMultiStepSheet.js.map +1 -1
- package/lib/module/features/engage/engageOutcome.js +6 -6
- package/lib/module/features/engage/engageOutcome.js.map +1 -1
- package/lib/module/features/engage/engagePushTokenBridge.js +20 -20
- package/lib/module/features/engage/engagePushTokenBridge.js.map +1 -1
- package/lib/module/features/engage/engageShakeBridge.js +16 -16
- package/lib/module/features/engage/engageShakeBridge.js.map +1 -1
- package/lib/module/features/engage/engageSignals.js.map +1 -1
- package/lib/module/features/engage/engageStoreReviewBridge.js +19 -19
- package/lib/module/features/engage/engageStoreReviewBridge.js.map +1 -1
- package/lib/module/features/engage/engageTestSeenStore.js +29 -29
- package/lib/module/features/engage/engageTestSeenStore.js.map +1 -1
- package/lib/module/features/engage/engageThrottle.js +117 -86
- package/lib/module/features/engage/engageThrottle.js.map +1 -1
- package/lib/module/features/engage/engageTriggerEngine.js +17 -7
- package/lib/module/features/engage/engageTriggerEngine.js.map +1 -1
- package/lib/module/features/engage/engageTypes.js +33 -33
- package/lib/module/features/engage/engageTypes.js.map +1 -1
- package/lib/module/features/engage/engageVariantResolver.js +13 -13
- package/lib/module/features/engage/engageVariantResolver.js.map +1 -1
- package/lib/module/features/engage/engageWindowInsets.js +10 -10
- package/lib/module/features/engage/engageWindowInsets.js.map +1 -1
- package/lib/module/features/engage/gestureTriggerDetector.js.map +1 -1
- package/lib/module/features/engage/transcription/TranscriptionProvider.js +16 -16
- package/lib/module/features/engage/transcription/TranscriptionProvider.js.map +1 -1
- package/lib/module/features/install-referrer/installReferrer.js +26 -26
- package/lib/module/features/install-referrer/installReferrer.js.map +1 -1
- package/lib/module/features/journey/ScaleBunDebugRoot.js +30 -29
- package/lib/module/features/journey/ScaleBunDebugRoot.js.map +1 -1
- package/lib/module/features/journey/ScaleBunFlatList.js +15 -15
- package/lib/module/features/journey/ScaleBunFlatList.js.map +1 -1
- package/lib/module/features/journey/ScaleBunImpression.js +22 -22
- package/lib/module/features/journey/ScaleBunImpression.js.map +1 -1
- package/lib/module/features/journey/ScaleBunScrollView.js +20 -20
- package/lib/module/features/journey/ScaleBunScrollView.js.map +1 -1
- package/lib/module/features/journey/ScaleBunSectionList.js +15 -15
- package/lib/module/features/journey/ScaleBunSectionList.js.map +1 -1
- package/lib/module/features/journey/calibrationContext.js +12 -12
- package/lib/module/features/journey/calibrationContext.js.map +1 -1
- package/lib/module/features/journey/gestureBuffer.js +9 -9
- package/lib/module/features/journey/gestureBuffer.js.map +1 -1
- package/lib/module/features/journey/gestureDetector.js +10 -10
- package/lib/module/features/journey/gestureDetector.js.map +1 -1
- package/lib/module/features/journey/impression.js +18 -18
- package/lib/module/features/journey/impression.js.map +1 -1
- package/lib/module/features/journey/journeyManager.js +6 -6
- package/lib/module/features/journey/journeyManager.js.map +1 -1
- package/lib/module/features/journey/journeyTypes.js +5 -5
- package/lib/module/features/journey/journeyTypes.js.map +1 -1
- package/lib/module/features/journey/navDetector.js +7 -7
- package/lib/module/features/journey/navDetector.js.map +1 -1
- package/lib/module/features/journey/screenshotHelper.js +7 -7
- package/lib/module/features/journey/screenshotHelper.js.map +1 -1
- package/lib/module/features/journey/targetRegistry.js +17 -17
- package/lib/module/features/journey/targetRegistry.js.map +1 -1
- package/lib/module/features/journey/touchTarget.js +29 -29
- package/lib/module/features/journey/touchTarget.js.map +1 -1
- package/lib/module/features/navigation/AutoScreenDetector.js +114 -71
- package/lib/module/features/navigation/AutoScreenDetector.js.map +1 -1
- package/lib/module/features/network/NetworkFeature.js +23 -23
- package/lib/module/features/network/NetworkFeature.js.map +1 -1
- package/lib/module/features/network/index.js +5 -5
- package/lib/module/features/network/index.js.map +1 -1
- package/lib/module/features/ota/OtaEventEmitter.js +21 -21
- package/lib/module/features/ota/OtaEventEmitter.js.map +1 -1
- package/lib/module/features/ota/OtaOrchestrator.js +596 -43
- package/lib/module/features/ota/OtaOrchestrator.js.map +1 -1
- package/lib/module/features/ota/OtaTypes.js.map +1 -1
- package/lib/module/features/ota/deviceAttributes.js +43 -0
- package/lib/module/features/ota/deviceAttributes.js.map +1 -0
- package/lib/module/features/ota/environment.js +165 -0
- package/lib/module/features/ota/environment.js.map +1 -0
- package/lib/module/features/ota/geoCountry.js +86 -0
- package/lib/module/features/ota/geoCountry.js.map +1 -0
- package/lib/module/features/ota/retry.js +87 -0
- package/lib/module/features/ota/retry.js.map +1 -0
- package/lib/module/features/ota/signature.js +109 -0
- package/lib/module/features/ota/signature.js.map +1 -0
- package/lib/module/features/ota/useOtaUpdate.js +18 -15
- package/lib/module/features/ota/useOtaUpdate.js.map +1 -1
- package/lib/module/features/performance/PerformanceFeature.js +49 -35
- package/lib/module/features/performance/PerformanceFeature.js.map +1 -1
- package/lib/module/features/performance/collectors/AppLaunchCollector.js +13 -13
- package/lib/module/features/performance/collectors/AppLaunchCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js +32 -32
- package/lib/module/features/performance/collectors/AutoScreenLoadCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/CustomTraceCollector.js +13 -13
- package/lib/module/features/performance/collectors/CustomTraceCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/FrameMetricsCollector.js +81 -21
- package/lib/module/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/JsStallCollector.js +12 -12
- package/lib/module/features/performance/collectors/JsStallCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/NetworkPerfCollector.js +10 -10
- package/lib/module/features/performance/collectors/NetworkPerfCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/ScreenLoadCollector.js +11 -11
- package/lib/module/features/performance/collectors/ScreenLoadCollector.js.map +1 -1
- package/lib/module/features/performance/collectors/UiHangCollector.js +5 -5
- package/lib/module/features/performance/collectors/UiHangCollector.js.map +1 -1
- package/lib/module/features/performance/config.js +11 -11
- package/lib/module/features/performance/config.js.map +1 -1
- package/lib/module/features/performance/getNativePerformanceModule.js +11 -11
- package/lib/module/features/performance/getNativePerformanceModule.js.map +1 -1
- package/lib/module/features/performance/index.js +2 -2
- package/lib/module/features/performance/index.js.map +1 -1
- package/lib/module/features/performance/metrics/MetricsEngine.js +13 -13
- package/lib/module/features/performance/metrics/MetricsEngine.js.map +1 -1
- package/lib/module/features/performance/models.js +8 -8
- package/lib/module/features/performance/models.js.map +1 -1
- package/lib/module/features/performance/transport/PerformanceTransport.js +31 -6
- package/lib/module/features/performance/transport/PerformanceTransport.js.map +1 -1
- package/lib/module/features/profiler/ProfilerFeature.js +53 -53
- package/lib/module/features/profiler/ProfilerFeature.js.map +1 -1
- package/lib/module/features/profiler/config.js +15 -15
- package/lib/module/features/profiler/config.js.map +1 -1
- package/lib/module/features/profiler/contracts.js +22 -22
- package/lib/module/features/profiler/contracts.js.map +1 -1
- package/lib/module/features/profiler/index.js +4 -4
- package/lib/module/features/profiler/index.js.map +1 -1
- package/lib/module/features/profiler/models.js +44 -44
- package/lib/module/features/profiler/models.js.map +1 -1
- package/lib/module/features/profiler/transport/ProfilerTransport.js +9 -9
- package/lib/module/features/profiler/transport/ProfilerTransport.js.map +1 -1
- package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js +17 -17
- package/lib/module/features/replay/bridge/adapters/bridgeAdapter.js.map +1 -1
- package/lib/module/features/replay/bridge/eventEmitter.js +8 -8
- package/lib/module/features/replay/bridge/eventEmitter.js.map +1 -1
- package/lib/module/features/replay/bridge/nativeModule.js +20 -20
- package/lib/module/features/replay/bridge/nativeModule.js.map +1 -1
- package/lib/module/features/replay/core/clock/clock.js +6 -6
- package/lib/module/features/replay/core/clock/clock.js.map +1 -1
- package/lib/module/features/replay/core/config/defaults.js +2 -2
- package/lib/module/features/replay/core/config/defaults.js.map +1 -1
- package/lib/module/features/replay/core/config/validator.js +5 -5
- package/lib/module/features/replay/core/config/validator.js.map +1 -1
- package/lib/module/features/replay/core/env/environmentDetector.js +10 -10
- package/lib/module/features/replay/core/env/environmentDetector.js.map +1 -1
- package/lib/module/features/replay/core/errors/safeCall.js +4 -4
- package/lib/module/features/replay/core/errors/safeCall.js.map +1 -1
- package/lib/module/features/replay/core/ids/sessionId.js +5 -5
- package/lib/module/features/replay/core/ids/sessionId.js.map +1 -1
- package/lib/module/features/replay/core/logger/logger.js +5 -5
- package/lib/module/features/replay/core/logger/logger.js.map +1 -1
- package/lib/module/features/replay/core/privacy/privacyTypes.js +4 -4
- package/lib/module/features/replay/core/privacy/privacyTypes.js.map +1 -1
- package/lib/module/features/replay/core/queue/boundedQueue.js +5 -5
- package/lib/module/features/replay/core/queue/boundedQueue.js.map +1 -1
- package/lib/module/features/replay/integrations/alert/alertInstrumentation.js +59 -59
- package/lib/module/features/replay/integrations/alert/alertInstrumentation.js.map +1 -1
- package/lib/module/features/replay/integrations/logs/consoleIntegration.js +19 -19
- package/lib/module/features/replay/integrations/logs/consoleIntegration.js.map +1 -1
- package/lib/module/features/replay/integrations/network/networkAdapter.js +30 -30
- package/lib/module/features/replay/integrations/network/networkAdapter.js.map +1 -1
- package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js +19 -19
- package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
- package/lib/module/features/replay/integrations/touch/ReplayRoot.js +16 -16
- package/lib/module/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
- package/lib/module/features/replay/pipeline/batching/batchManager.js +5 -5
- package/lib/module/features/replay/pipeline/batching/batchManager.js.map +1 -1
- package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js +5 -5
- package/lib/module/features/replay/pipeline/envelope/envelopeBuilder.js.map +1 -1
- package/lib/module/features/replay/pipeline/retry/retryPolicy.js +4 -4
- package/lib/module/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
- package/lib/module/features/replay/pipeline/transport/transportTypes.js +7 -7
- package/lib/module/features/replay/pipeline/transport/transportTypes.js.map +1 -1
- package/lib/module/features/replay/public/api.js +21 -21
- package/lib/module/features/replay/public/api.js.map +1 -1
- package/lib/module/features/replay/public/enums.js +5 -5
- package/lib/module/features/replay/public/enums.js.map +1 -1
- package/lib/module/features/replay/public/types.js.map +1 -1
- package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js +5 -5
- package/lib/module/features/replay/replay/breadcrumbs/breadcrumbCollector.js.map +1 -1
- package/lib/module/features/replay/replay/frames/frameModels.js +4 -4
- package/lib/module/features/replay/replay/frames/frameModels.js.map +1 -1
- package/lib/module/features/replay/replay/session/sessionOrchestrator.js +10 -10
- package/lib/module/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
- package/lib/module/features/replay/replay/timeline/timelineModels.js +4 -4
- package/lib/module/features/replay/replay/timeline/timelineModels.js.map +1 -1
- package/lib/module/features/replay/transport/BackendReplayTransport.js +13 -13
- package/lib/module/features/replay/transport/BackendReplayTransport.js.map +1 -1
- package/lib/module/features/replay/transport/CompositeReplayTransport.js +8 -8
- package/lib/module/features/replay/transport/CompositeReplayTransport.js.map +1 -1
- package/lib/module/features/replay/transport/DesktopReplayTransport.js +14 -14
- package/lib/module/features/replay/transport/DesktopReplayTransport.js.map +1 -1
- package/lib/module/features/replay/transport/ReplayTransport.js.map +1 -1
- package/lib/module/features/session/BackendSessionAdapter.js +485 -164
- package/lib/module/features/session/BackendSessionAdapter.js.map +1 -1
- package/lib/module/features/session/DesktopSessionTransport.js +14 -14
- package/lib/module/features/session/DesktopSessionTransport.js.map +1 -1
- package/lib/module/features/session/JourneyEventPipeline.js +20 -19
- package/lib/module/features/session/JourneyEventPipeline.js.map +1 -1
- package/lib/module/features/session/ReplayCaptureManager.js +169 -123
- package/lib/module/features/session/ReplayCaptureManager.js.map +1 -1
- package/lib/module/features/session/ScrollTracker.js +17 -17
- package/lib/module/features/session/ScrollTracker.js.map +1 -1
- package/lib/module/features/session/SessionManager.js +185 -155
- package/lib/module/features/session/SessionManager.js.map +1 -1
- package/lib/module/features/session/SyncDecisionEngine.js +23 -23
- package/lib/module/features/session/SyncDecisionEngine.js.map +1 -1
- package/lib/module/features/session/index.js +5 -5
- package/lib/module/features/session/index.js.map +1 -1
- package/lib/module/features/session/nativeCapture.js +9 -10
- package/lib/module/features/session/nativeCapture.js.map +1 -1
- package/lib/module/features/session/outboxFrameCapture.js +18 -17
- package/lib/module/features/session/outboxFrameCapture.js.map +1 -1
- package/lib/module/features/session/sessionTypes.js +44 -44
- package/lib/module/features/session/sessionTypes.js.map +1 -1
- package/lib/module/features/skan/skanBridge.js +11 -11
- package/lib/module/features/skan/skanBridge.js.map +1 -1
- package/lib/module/features/skan/skanConversionManager.js +23 -23
- package/lib/module/features/skan/skanConversionManager.js.map +1 -1
- package/lib/module/index.js +19 -10
- package/lib/module/index.js.map +1 -1
- package/lib/module/integrations/fetch/fetchInterceptor.js +21 -21
- package/lib/module/integrations/fetch/fetchInterceptor.js.map +1 -1
- package/lib/module/integrations/navigation/screenTracker.js.map +1 -1
- package/lib/module/integrations/network/bodyCapture.js +69 -69
- package/lib/module/integrations/network/bodyCapture.js.map +1 -1
- package/lib/module/integrations/xhr/xhrInterceptor.js +24 -24
- package/lib/module/integrations/xhr/xhrInterceptor.js.map +1 -1
- package/lib/module/metro/index.js +37 -37
- package/lib/module/metro/index.js.map +1 -1
- package/lib/module/metro/optionalDependencyStub.js +11 -11
- package/lib/module/metro/optionalDependencyStub.js.map +1 -1
- package/lib/module/metro/optionalModules.js +16 -16
- package/lib/module/metro/optionalModules.js.map +1 -1
- package/lib/module/pipeline/dispatcher/dispatcher.js.map +1 -1
- package/lib/module/pipeline/envelope/envelope.js.map +1 -1
- package/lib/module/pipeline/envelope/serializer.js.map +1 -1
- package/lib/module/pipeline/processors/dedupe.js.map +1 -1
- package/lib/module/pipeline/processors/enrich.js.map +1 -1
- package/lib/module/pipeline/processors/sampling.js.map +1 -1
- package/lib/module/pipeline/processors/sanitize.js.map +1 -1
- package/lib/module/pipeline/queue/flushQueue.js +4 -4
- package/lib/module/pipeline/queue/flushQueue.js.map +1 -1
- package/lib/module/pipeline/queue/memoryQueue.js.map +1 -1
- package/lib/module/pipeline/queue/persistentQueue.js +80 -80
- package/lib/module/pipeline/queue/persistentQueue.js.map +1 -1
- package/lib/module/pipeline/queue/queuePolicy.js.map +1 -1
- package/lib/module/pipeline/scheduler/flushScheduler.js.map +1 -1
- package/lib/module/pipeline/scheduler/retryPolicy.js +2 -2
- package/lib/module/pipeline/scheduler/retryPolicy.js.map +1 -1
- package/lib/module/public/ScaleBunErrorBoundary.js +70 -0
- package/lib/module/public/ScaleBunErrorBoundary.js.map +1 -0
- package/lib/module/public/ScaleBunFacade.js +424 -276
- package/lib/module/public/ScaleBunFacade.js.map +1 -1
- package/lib/module/public/ScaleBunProvider.js +3 -3
- package/lib/module/public/ScaleBunProvider.js.map +1 -1
- package/lib/module/public/typedTracker.js +36 -36
- package/lib/module/public/typedTracker.js.map +1 -1
- package/lib/module/public/types.js.map +1 -1
- package/lib/module/push/PushManager.js +21 -21
- package/lib/module/push/PushManager.js.map +1 -1
- package/lib/module/push/adapters/ManualAdapter.js +14 -14
- package/lib/module/push/adapters/ManualAdapter.js.map +1 -1
- package/lib/module/push/adapters/NativeBridgeAdapter.js +17 -17
- package/lib/module/push/adapters/NativeBridgeAdapter.js.map +1 -1
- package/lib/module/push/adapters/NoopAdapter.js +5 -5
- package/lib/module/push/adapters/NoopAdapter.js.map +1 -1
- package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js +17 -17
- package/lib/module/push/adapters/RNFirebaseMessagingAdapter.js.map +1 -1
- package/lib/module/push/adapters/loadMessaging.js +12 -12
- package/lib/module/push/adapters/loadMessaging.js.map +1 -1
- package/lib/module/push/adapters/loadNotifee.js +12 -12
- package/lib/module/push/adapters/loadNotifee.js.map +1 -1
- package/lib/module/push/adapters/selectAdapter.js +14 -14
- package/lib/module/push/adapters/selectAdapter.js.map +1 -1
- package/lib/module/push/detect/capabilities.js +19 -19
- package/lib/module/push/detect/capabilities.js.map +1 -1
- package/lib/module/push/index.js +3 -3
- package/lib/module/push/index.js.map +1 -1
- package/lib/module/push/native/nativeNotifications.js +32 -32
- package/lib/module/push/native/nativeNotifications.js.map +1 -1
- package/lib/module/push/types.js.map +1 -1
- package/lib/module/specs/NativeReplaySdk.js +18 -18
- package/lib/module/specs/NativeReplaySdk.js.map +1 -1
- package/lib/module/specs/NativeScaleBunCrash.js +19 -19
- package/lib/module/specs/NativeScaleBunCrash.js.map +1 -1
- package/lib/module/specs/NativeScaleBunInstallReferrer.js +14 -14
- package/lib/module/specs/NativeScaleBunInstallReferrer.js.map +1 -1
- package/lib/module/specs/NativeScaleBunOta.js +21 -21
- package/lib/module/specs/NativeScaleBunOta.js.map +1 -1
- package/lib/module/specs/NativeScaleBunPerformance.js +15 -15
- package/lib/module/specs/NativeScaleBunPerformance.js.map +1 -1
- package/lib/module/specs/NativeScaleBunProfiler.js +16 -16
- package/lib/module/specs/NativeScaleBunProfiler.js.map +1 -1
- package/lib/module/specs/NativeScaleBunStorage.js +29 -29
- package/lib/module/specs/NativeScaleBunStorage.js.map +1 -1
- package/lib/module/storage/StorageBackend.js +83 -83
- package/lib/module/storage/StorageBackend.js.map +1 -1
- package/lib/module/storage/db/sqlite.js.map +1 -1
- package/lib/module/storage/files/fileStore.js.map +1 -1
- package/lib/module/transport/auth/sdkSession.js.map +1 -1
- package/lib/module/transport/backoff/exponentialJitter.js +2 -2
- package/lib/module/transport/backoff/exponentialJitter.js.map +1 -1
- package/lib/module/transport/http/endpoints.js.map +1 -1
- package/lib/module/transport/http/httpClient.js +3 -3
- package/lib/module/transport/http/httpClient.js.map +1 -1
- package/lib/module/transport/rateLimit/retryAfter.js.map +1 -1
- package/lib/module/transport/signing/requestSigner.js.map +1 -1
- package/lib/module/vendor/protocol/index.js +74 -74
- package/lib/module/vendor/protocol/index.js.map +1 -1
- package/lib/module/vendor/protocol/internal/validation.js +23 -23
- package/lib/module/vendor/protocol/internal/validation.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/bridge.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/config.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/events.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/features.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/index.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/platform.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/session-boundary.js.map +1 -1
- package/lib/module/vendor/sdk-contracts/session.js.map +1 -1
- package/lib/module/vendor/vendor.manifest +10 -10
- package/lib/typescript/analytics/EventTracker.d.ts +20 -0
- package/lib/typescript/analytics/EventTracker.d.ts.map +1 -1
- package/lib/typescript/bootstrap/SDKBootstrapper.d.ts.map +1 -1
- package/lib/typescript/core/config/schema.d.ts +1 -1
- package/lib/typescript/core/config/schema.d.ts.map +1 -1
- package/lib/typescript/core/context/device.d.ts +46 -0
- package/lib/typescript/core/context/device.d.ts.map +1 -1
- package/lib/typescript/debug/replayWiring.d.ts.map +1 -1
- package/lib/typescript/features/bugreport/BugReportFeature.d.ts +59 -0
- package/lib/typescript/features/bugreport/BugReportFeature.d.ts.map +1 -0
- package/lib/typescript/features/bugreport/buildPayload.d.ts +51 -0
- package/lib/typescript/features/bugreport/buildPayload.d.ts.map +1 -0
- package/lib/typescript/features/crash/CrashFeature.d.ts.map +1 -1
- package/lib/typescript/features/crash/CrashReporter.d.ts +20 -1
- package/lib/typescript/features/crash/CrashReporter.d.ts.map +1 -1
- package/lib/typescript/features/crash/capture.d.ts +21 -2
- package/lib/typescript/features/crash/capture.d.ts.map +1 -1
- package/lib/typescript/features/crash/nativeCrashBridge.d.ts +16 -3
- package/lib/typescript/features/crash/nativeCrashBridge.d.ts.map +1 -1
- package/lib/typescript/features/crash/rejectionHandler.d.ts +46 -0
- package/lib/typescript/features/crash/rejectionHandler.d.ts.map +1 -0
- package/lib/typescript/features/engage/EngagePromptProvider.d.ts.map +1 -1
- package/lib/typescript/features/engage/EngagePromptView.d.ts.map +1 -1
- package/lib/typescript/features/engage/engageThrottle.d.ts +24 -4
- package/lib/typescript/features/engage/engageThrottle.d.ts.map +1 -1
- package/lib/typescript/features/engage/engageTriggerEngine.d.ts.map +1 -1
- package/lib/typescript/features/engage/engageTypes.d.ts +21 -0
- package/lib/typescript/features/engage/engageTypes.d.ts.map +1 -1
- package/lib/typescript/features/journey/ScaleBunDebugRoot.d.ts.map +1 -1
- package/lib/typescript/features/navigation/AutoScreenDetector.d.ts +9 -0
- package/lib/typescript/features/navigation/AutoScreenDetector.d.ts.map +1 -1
- package/lib/typescript/features/ota/OtaOrchestrator.d.ts +75 -3
- package/lib/typescript/features/ota/OtaOrchestrator.d.ts.map +1 -1
- package/lib/typescript/features/ota/OtaTypes.d.ts +42 -0
- package/lib/typescript/features/ota/OtaTypes.d.ts.map +1 -1
- package/lib/typescript/features/ota/deviceAttributes.d.ts +18 -0
- package/lib/typescript/features/ota/deviceAttributes.d.ts.map +1 -0
- package/lib/typescript/features/ota/environment.d.ts +99 -0
- package/lib/typescript/features/ota/environment.d.ts.map +1 -0
- package/lib/typescript/features/ota/geoCountry.d.ts +14 -0
- package/lib/typescript/features/ota/geoCountry.d.ts.map +1 -0
- package/lib/typescript/features/ota/retry.d.ts +53 -0
- package/lib/typescript/features/ota/retry.d.ts.map +1 -0
- package/lib/typescript/features/ota/signature.d.ts +66 -0
- package/lib/typescript/features/ota/signature.d.ts.map +1 -0
- package/lib/typescript/features/ota/useOtaUpdate.d.ts +20 -2
- package/lib/typescript/features/ota/useOtaUpdate.d.ts.map +1 -1
- package/lib/typescript/features/performance/PerformanceFeature.d.ts +0 -1
- package/lib/typescript/features/performance/PerformanceFeature.d.ts.map +1 -1
- package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts +33 -0
- package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts.map +1 -1
- package/lib/typescript/features/performance/transport/PerformanceTransport.d.ts.map +1 -1
- package/lib/typescript/features/session/BackendSessionAdapter.d.ts +135 -4
- package/lib/typescript/features/session/BackendSessionAdapter.d.ts.map +1 -1
- package/lib/typescript/features/session/JourneyEventPipeline.d.ts +2 -0
- package/lib/typescript/features/session/JourneyEventPipeline.d.ts.map +1 -1
- package/lib/typescript/features/session/ReplayCaptureManager.d.ts +38 -1
- package/lib/typescript/features/session/ReplayCaptureManager.d.ts.map +1 -1
- package/lib/typescript/features/session/SessionManager.d.ts.map +1 -1
- package/lib/typescript/features/session/nativeCapture.d.ts +2 -1
- package/lib/typescript/features/session/nativeCapture.d.ts.map +1 -1
- package/lib/typescript/features/session/outboxFrameCapture.d.ts.map +1 -1
- package/lib/typescript/features/session/sessionTypes.d.ts +20 -3
- package/lib/typescript/features/session/sessionTypes.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +7 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/public/ScaleBunErrorBoundary.d.ts +44 -0
- package/lib/typescript/public/ScaleBunErrorBoundary.d.ts.map +1 -0
- package/lib/typescript/public/ScaleBunFacade.d.ts +58 -0
- package/lib/typescript/public/ScaleBunFacade.d.ts.map +1 -1
- package/lib/typescript/specs/NativeScaleBunCrash.d.ts +14 -0
- package/lib/typescript/specs/NativeScaleBunCrash.d.ts.map +1 -1
- package/lib/typescript/specs/NativeScaleBunOta.d.ts +11 -0
- package/lib/typescript/specs/NativeScaleBunOta.d.ts.map +1 -1
- package/lib/typescript/vendor/protocol/index.d.ts +17 -17
- package/package.json +12 -14
- package/react-native.config.js +24 -24
- package/scalebun-react-native.podspec +37 -37
- package/src/analytics/EventTracker.ts +489 -462
- package/src/analytics/automaticEvents.ts +105 -105
- package/src/analytics/batching.ts +54 -54
- package/src/analytics/eventLane.ts +26 -26
- package/src/bootstrap/FeatureRegistry.ts +81 -81
- package/src/bootstrap/SDKBootstrapper.ts +610 -585
- package/src/bucketing/fnv1a32.ts +40 -40
- package/src/compat/codepush.ts +118 -118
- package/src/config/ConfigManager.ts +167 -167
- package/src/config/configTypes.ts +32 -32
- package/src/core/architecture.ts +39 -39
- package/src/core/clock/now.ts +6 -6
- package/src/core/config/schema.ts +239 -231
- package/src/core/constants/endpoints.ts +9 -9
- package/src/core/constants/timings.ts +23 -23
- package/src/core/constants/version.ts +6 -6
- package/src/core/context/device.ts +146 -0
- package/src/core/context/user.ts +26 -26
- package/src/core/contracts/IFeature.ts +53 -53
- package/src/core/di/container.ts +26 -26
- package/src/core/encoding/base64.ts +46 -46
- package/src/core/id/deviceId.ts +51 -51
- package/src/core/lifecycle/appLifecycle.ts +33 -33
- package/src/core/lifecycle/crashSafe.ts +29 -29
- package/src/core/logger/errorClassification.ts +108 -108
- package/src/core/logger/internalLogger.ts +65 -65
- package/src/crypto/hmacSha256.ts +106 -106
- package/src/debug/bootstrap.ts +366 -366
- package/src/debug/commands.ts +597 -597
- package/src/debug/configBuilder.ts +56 -56
- package/src/debug/exportBridge.ts +153 -153
- package/src/debug/hostResolver.ts +34 -34
- package/src/debug/index.ts +25 -25
- package/src/debug/metrics.ts +29 -29
- package/src/debug/perf.ts +212 -212
- package/src/debug/perfWiring.ts +119 -119
- package/src/debug/protocol.ts +58 -58
- package/src/debug/redaction.ts +290 -290
- package/src/debug/replayWiring.ts +148 -147
- package/src/debug/screenTracking.ts +55 -55
- package/src/debug/sessionWiring.ts +59 -59
- package/src/debug/stream.ts +561 -561
- package/src/debug/transport.ts +439 -439
- package/src/features/bugreport/BugReportFeature.ts +128 -0
- package/src/features/bugreport/buildPayload.ts +116 -0
- package/src/features/crash/CrashFeature.ts +71 -52
- package/src/features/crash/CrashReporter.ts +179 -140
- package/src/features/crash/NativeCrashFeature.ts +42 -42
- package/src/features/crash/capture.ts +48 -21
- package/src/features/crash/globalHandler.ts +39 -39
- package/src/features/crash/index.ts +8 -8
- package/src/features/crash/nativeCrashBridge.ts +266 -132
- package/src/features/crash/rejectionHandler.ts +134 -0
- package/src/features/engage/EngageAnchor.tsx +159 -159
- package/src/features/engage/EngageArchetypeRenderers.tsx +3716 -3716
- package/src/features/engage/EngageInAppView.tsx +2678 -2678
- package/src/features/engage/EngageInlinePlacement.tsx +169 -169
- package/src/features/engage/EngagePromptProvider.tsx +1318 -1270
- package/src/features/engage/EngagePromptView.tsx +1400 -1364
- package/src/features/engage/EngageTransport.ts +668 -668
- package/src/features/engage/EngageVariantContent.tsx +1483 -1483
- package/src/features/engage/__test-support__/reactNativeStub.js +40 -40
- package/src/features/engage/attachmentCapture.ts +45 -45
- package/src/features/engage/captureVoiceAttachment.ts +81 -81
- package/src/features/engage/engageCoachmarkTour.ts +120 -120
- package/src/features/engage/engageGameLogic.ts +347 -347
- package/src/features/engage/engageMediaSizing.ts +76 -76
- package/src/features/engage/engageMultiStepSheet.ts +53 -53
- package/src/features/engage/engageOutcome.ts +157 -157
- package/src/features/engage/engagePushTokenBridge.ts +84 -84
- package/src/features/engage/engageShakeBridge.ts +67 -67
- package/src/features/engage/engageSignals.ts +40 -40
- package/src/features/engage/engageStoreReviewBridge.ts +48 -48
- package/src/features/engage/engageTestSeenStore.ts +95 -95
- package/src/features/engage/engageThrottle.ts +478 -440
- package/src/features/engage/engageTriggerEngine.ts +350 -335
- package/src/features/engage/engageTypes.ts +712 -691
- package/src/features/engage/engageVariantResolver.ts +364 -364
- package/src/features/engage/engageWindowInsets.ts +108 -108
- package/src/features/engage/gestureTriggerDetector.ts +83 -83
- package/src/features/engage/transcription/TranscriptionProvider.ts +68 -68
- package/src/features/install-referrer/installReferrer.ts +112 -112
- package/src/features/journey/ScaleBunDebugRoot.tsx +727 -726
- package/src/features/journey/ScaleBunFlatList.tsx +39 -39
- package/src/features/journey/ScaleBunImpression.tsx +109 -109
- package/src/features/journey/ScaleBunScrollView.tsx +72 -72
- package/src/features/journey/ScaleBunSectionList.tsx +39 -39
- package/src/features/journey/calibrationContext.ts +53 -53
- package/src/features/journey/gestureBuffer.ts +59 -59
- package/src/features/journey/gestureDetector.ts +162 -162
- package/src/features/journey/impression.ts +92 -92
- package/src/features/journey/journeyManager.ts +466 -466
- package/src/features/journey/journeyTypes.ts +215 -215
- package/src/features/journey/navDetector.ts +149 -149
- package/src/features/journey/screenshotHelper.ts +137 -137
- package/src/features/journey/targetRegistry.ts +43 -43
- package/src/features/journey/touchTarget.ts +128 -128
- package/src/features/navigation/AutoScreenDetector.ts +503 -448
- package/src/features/network/NetworkFeature.ts +144 -144
- package/src/features/network/index.ts +31 -31
- package/src/features/ota/OtaEventEmitter.ts +128 -128
- package/src/features/ota/OtaOrchestrator.ts +963 -323
- package/src/features/ota/OtaTypes.ts +118 -62
- package/src/features/ota/deviceAttributes.ts +46 -0
- package/src/features/ota/environment.ts +199 -0
- package/src/features/ota/geoCountry.ts +85 -0
- package/src/features/ota/retry.ts +123 -0
- package/src/features/ota/signature.ts +123 -0
- package/src/features/ota/useOtaUpdate.ts +152 -134
- package/src/features/performance/PerformanceFeature.ts +597 -584
- package/src/features/performance/collectors/AppLaunchCollector.ts +117 -117
- package/src/features/performance/collectors/AutoScreenLoadCollector.ts +258 -258
- package/src/features/performance/collectors/CustomTraceCollector.ts +116 -116
- package/src/features/performance/collectors/FrameMetricsCollector.ts +181 -119
- package/src/features/performance/collectors/JsStallCollector.ts +165 -165
- package/src/features/performance/collectors/NetworkPerfCollector.ts +69 -69
- package/src/features/performance/collectors/ScreenLoadCollector.ts +95 -95
- package/src/features/performance/collectors/UiHangCollector.ts +98 -98
- package/src/features/performance/config.ts +136 -136
- package/src/features/performance/getNativePerformanceModule.ts +38 -38
- package/src/features/performance/index.ts +28 -28
- package/src/features/performance/metrics/MetricsEngine.ts +152 -152
- package/src/features/performance/models.ts +235 -235
- package/src/features/performance/transport/PerformanceTransport.ts +161 -143
- package/src/features/profiler/ProfilerFeature.ts +661 -661
- package/src/features/profiler/config.ts +230 -230
- package/src/features/profiler/contracts.ts +176 -176
- package/src/features/profiler/index.ts +45 -45
- package/src/features/profiler/models.ts +430 -430
- package/src/features/profiler/transport/ProfilerTransport.ts +93 -93
- package/src/features/replay/bridge/adapters/bridgeAdapter.ts +230 -230
- package/src/features/replay/bridge/eventEmitter.ts +176 -176
- package/src/features/replay/bridge/nativeModule.ts +241 -241
- package/src/features/replay/core/clock/clock.ts +38 -38
- package/src/features/replay/core/config/defaults.ts +66 -66
- package/src/features/replay/core/config/validator.ts +113 -113
- package/src/features/replay/core/env/environmentDetector.ts +21 -21
- package/src/features/replay/core/errors/safeCall.ts +34 -34
- package/src/features/replay/core/ids/sessionId.ts +44 -44
- package/src/features/replay/core/logger/logger.ts +40 -40
- package/src/features/replay/core/privacy/privacyTypes.ts +41 -41
- package/src/features/replay/core/queue/boundedQueue.ts +71 -71
- package/src/features/replay/integrations/alert/alertInstrumentation.ts +277 -277
- package/src/features/replay/integrations/logs/consoleIntegration.ts +116 -116
- package/src/features/replay/integrations/network/networkAdapter.ts +128 -128
- package/src/features/replay/integrations/react-navigation/navigationIntegration.ts +89 -89
- package/src/features/replay/integrations/touch/ReplayRoot.tsx +114 -114
- package/src/features/replay/pipeline/batching/batchManager.ts +133 -133
- package/src/features/replay/pipeline/envelope/envelopeBuilder.ts +66 -66
- package/src/features/replay/pipeline/retry/retryPolicy.ts +62 -62
- package/src/features/replay/pipeline/transport/transportTypes.ts +85 -85
- package/src/features/replay/public/api.ts +364 -364
- package/src/features/replay/public/enums.ts +78 -78
- package/src/features/replay/public/types.ts +297 -297
- package/src/features/replay/replay/breadcrumbs/breadcrumbCollector.ts +115 -115
- package/src/features/replay/replay/frames/frameModels.ts +45 -45
- package/src/features/replay/replay/session/sessionOrchestrator.ts +286 -286
- package/src/features/replay/replay/timeline/timelineModels.ts +129 -129
- package/src/features/replay/transport/BackendReplayTransport.ts +215 -215
- package/src/features/replay/transport/CompositeReplayTransport.ts +82 -82
- package/src/features/replay/transport/DesktopReplayTransport.ts +140 -140
- package/src/features/replay/transport/ReplayTransport.ts +84 -84
- package/src/features/session/BackendSessionAdapter.ts +1568 -1233
- package/src/features/session/DesktopSessionTransport.ts +128 -128
- package/src/features/session/JourneyEventPipeline.ts +276 -273
- package/src/features/session/ReplayCaptureManager.ts +998 -946
- package/src/features/session/ScrollTracker.ts +166 -166
- package/src/features/session/SessionManager.ts +1248 -1209
- package/src/features/session/SyncDecisionEngine.ts +117 -117
- package/src/features/session/index.ts +88 -88
- package/src/features/session/nativeCapture.ts +39 -38
- package/src/features/session/outboxFrameCapture.ts +75 -74
- package/src/features/session/sessionTypes.ts +514 -491
- package/src/features/skan/skanBridge.ts +61 -61
- package/src/features/skan/skanConversionManager.ts +173 -173
- package/src/index.ts +200 -191
- package/src/integrations/fetch/fetchInterceptor.ts +182 -182
- package/src/integrations/network/bodyCapture.ts +328 -328
- package/src/integrations/xhr/xhrInterceptor.ts +231 -231
- package/src/metro/index.ts +164 -164
- package/src/metro/optionalDependencyStub.ts +13 -13
- package/src/metro/optionalModules.ts +27 -27
- package/src/pipeline/dispatcher/dispatcher.ts +22 -22
- package/src/pipeline/envelope/envelope.ts +31 -31
- package/src/pipeline/envelope/serializer.ts +14 -14
- package/src/pipeline/processors/enrich.ts +11 -11
- package/src/pipeline/processors/sanitize.ts +23 -23
- package/src/pipeline/queue/flushQueue.ts +144 -144
- package/src/pipeline/queue/memoryQueue.ts +31 -31
- package/src/pipeline/queue/persistentQueue.ts +414 -414
- package/src/pipeline/scheduler/flushScheduler.ts +47 -47
- package/src/pipeline/scheduler/retryPolicy.ts +8 -8
- package/src/public/ScaleBunErrorBoundary.tsx +79 -0
- package/src/public/ScaleBunFacade.ts +1630 -1479
- package/src/public/ScaleBunProvider.tsx +91 -91
- package/src/public/typedTracker.ts +123 -123
- package/src/public/types.ts +312 -312
- package/src/push/PushManager.ts +318 -318
- package/src/push/adapters/ManualAdapter.ts +100 -100
- package/src/push/adapters/NativeBridgeAdapter.ts +142 -142
- package/src/push/adapters/NoopAdapter.ts +46 -46
- package/src/push/adapters/RNFirebaseMessagingAdapter.ts +271 -271
- package/src/push/adapters/loadMessaging.ts +24 -24
- package/src/push/adapters/loadNotifee.ts +29 -29
- package/src/push/adapters/selectAdapter.ts +176 -176
- package/src/push/detect/capabilities.ts +124 -124
- package/src/push/index.ts +22 -22
- package/src/push/native/nativeNotifications.ts +216 -216
- package/src/push/types.ts +159 -159
- package/src/specs/NativeReplaySdk.ts +99 -99
- package/src/specs/NativeScaleBunCrash.ts +52 -36
- package/src/specs/NativeScaleBunInstallReferrer.ts +29 -29
- package/src/specs/NativeScaleBunOta.ts +97 -85
- package/src/specs/NativeScaleBunPerformance.ts +34 -34
- package/src/specs/NativeScaleBunProfiler.ts +41 -41
- package/src/specs/NativeScaleBunStorage.ts +59 -59
- package/src/storage/StorageBackend.ts +272 -272
- package/src/transport/auth/sdkSession.ts +27 -27
- package/src/transport/backoff/exponentialJitter.ts +9 -9
- package/src/transport/http/endpoints.ts +33 -33
- package/src/transport/http/httpClient.ts +73 -73
- package/src/vendor/protocol/index.ts +391 -391
- package/src/vendor/protocol/internal/validation.ts +497 -497
- package/src/vendor/sdk-contracts/bridge.ts +162 -162
- package/src/vendor/sdk-contracts/config.ts +192 -192
- package/src/vendor/sdk-contracts/events.ts +50 -50
- package/src/vendor/sdk-contracts/features.ts +42 -42
- package/src/vendor/sdk-contracts/index.ts +98 -98
- package/src/vendor/sdk-contracts/platform.ts +42 -42
- package/src/vendor/sdk-contracts/session-boundary.ts +55 -55
- package/src/vendor/sdk-contracts/session.ts +225 -225
- package/src/vendor/vendor.manifest +10 -10
- package/android/build/generated/source/buildConfig/debug/com/scalebun/sdk/BuildConfig.java +0 -12
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeReplaySdkSpec.java +0 -208
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunCrashSpec.java +0 -46
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.java +0 -38
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunOtaSpec.java +0 -63
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunPerformanceSpec.java +0 -70
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunProfilerSpec.java +0 -96
- package/android/build/generated/source/codegen/java/com/scalebun/spec/NativeScaleBunStorageSpec.java +0 -50
- package/android/build/generated/source/codegen/jni/CMakeLists.txt +0 -28
- package/android/build/generated/source/codegen/jni/ScaleBunSpec-generated.cpp +0 -554
- package/android/build/generated/source/codegen/jni/ScaleBunSpec.h +0 -79
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ComponentDescriptors.cpp +0 -22
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ComponentDescriptors.h +0 -24
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/EventEmitters.cpp +0 -16
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/EventEmitters.h +0 -17
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/Props.cpp +0 -19
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/Props.h +0 -18
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ScaleBunSpecJSI-generated.cpp +0 -595
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ScaleBunSpecJSI.h +0 -1070
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ShadowNodes.cpp +0 -17
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/ShadowNodes.h +0 -23
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/States.cpp +0 -16
- package/android/build/generated/source/codegen/jni/react/renderer/components/ScaleBunSpec/States.h +0 -20
- package/android/build/generated/source/codegen/schema.json +0 -1
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -20
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
- package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/sdk/BuildConfig.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeReplaySdkSpec.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunCrashSpec.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunOtaSpec.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunPerformanceSpec.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunProfilerSpec.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/scalebun/spec/NativeScaleBunStorageSpec.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -24
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -20
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/CrashStorage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/NativeCrashHandler$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/crash/NativeCrashHandler.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/ANRWatchdog$HangInfo.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/ANRWatchdog.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$AppStartInfo.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$Breakdown.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector$start$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/AppStartCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$FrameMetricsSnapshot.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$start$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector$startChoreographerFallback$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/FrameMetricsCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/PerformanceCore$Listener.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/core/performance/PerformanceCore.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/ProfilerSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/CpuCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/IncidentDetector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/MemoryCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/RenderCollector$frameCallback$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/RenderCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/SamplerScheduler.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/SamplerSchedulerKt.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/ThreadCollector$WhenMappings.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/profiler/collectors/ThreadCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule$registerConnectivity$cb$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/ReplaySdkSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/CaptureReason$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/CaptureReason.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureManager$startFrequencyTimer$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureManager.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$FrameRequest.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/FrameCaptureScheduler.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$SettleWatch.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector$StabilityWatch.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/capture/UiStabilityDetector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/CaptureMode$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/CaptureMode.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayConfig$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ReplayLogger.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ScreenshotQuality$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/ScreenshotQuality.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/SessionIdGenerator.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/core/SessionState.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/ReplayFrame.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/ReplaySession.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/models/TimelineEvent.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox$enforceLimits$lambda$37$$inlined$sortedBy$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/NativeOutbox.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$NetworkError.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$Response.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$Outcome.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader$WhenMappings.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/outbox/OutboxUploader.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/session/SessionManager.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/storage/ReplayStorage$enforceStorageLimit$$inlined$sortedBy$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/storage/ReplayStorage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/timeline/TimelineCollector.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/DialogTouchObserver$start$runnable$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/DialogTouchObserver.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/InteractionTracker.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/NativeTouchInterceptor.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/tracking/ScreenTracker.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport$UploadResult.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport$upload$2.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/transport/ReplayTransport.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder$Result.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceRecorder.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber$TranscriptResult.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber$listener$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/replaysdk/voice/VoiceTranscriber.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ScaleBunPackage$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ScaleBunPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/crash/ScaleBunCrashSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$WindowInsetEdges.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule$shakeListener$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngageModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunEngagePackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/engage/ScaleBunNotificationPresenter.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/ScaleBunOtaSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/SlotManager$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/ota/SlotManager.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule$coreListener$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/performance/PerformanceSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$getInstallReferrer$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/rn/storage/ScaleBunStorageSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/sdk/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeReplaySdkSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunCrashSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunInstallReferrerSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunOtaSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunPerformanceSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunProfilerSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/spec/NativeScaleBunStorageSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/storage/KvFileStore$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/scalebun/storage/KvFileStore.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +0 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +0 -2
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s +0 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -25
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/scalebun_react-native_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/CrashStorage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/NativeCrashHandler$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/crash/NativeCrashHandler.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/ANRWatchdog$HangInfo.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/ANRWatchdog.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$AppStartInfo.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$Breakdown.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector$start$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/AppStartCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$FrameMetricsSnapshot.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$start$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector$startChoreographerFallback$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/FrameMetricsCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/PerformanceCore$Listener.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/core/performance/PerformanceCore.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerPackage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/ProfilerSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/CpuCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/IncidentDetector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/MemoryCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/RenderCollector$frameCallback$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/RenderCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/SamplerScheduler.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/SamplerSchedulerKt.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/ThreadCollector$WhenMappings.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/profiler/collectors/ThreadCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule$registerConnectivity$cb$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkPackage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/ReplaySdkSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/CaptureReason$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/CaptureReason.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureManager$startFrequencyTimer$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureManager.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler$FrameRequest.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/FrameCaptureScheduler.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$SettleWatch.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector$StabilityWatch.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/capture/UiStabilityDetector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/CaptureMode$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/CaptureMode.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayConfig$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayConfig.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ReplayLogger.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ScreenshotQuality$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/ScreenshotQuality.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/SessionIdGenerator.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/core/SessionState.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/ReplayFrame.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/ReplaySession.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/models/TimelineEvent.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox$enforceLimits$lambda$37$$inlined$sortedBy$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/NativeOutbox.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$NetworkError.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult$Response.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$NetResult.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$Outcome.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader$WhenMappings.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/outbox/OutboxUploader.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/privacy/PrivacyMaskProcessor.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/session/SessionManager.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/storage/ReplayStorage$enforceStorageLimit$$inlined$sortedBy$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/storage/ReplayStorage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/timeline/TimelineCollector.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/DialogTouchObserver$start$runnable$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/DialogTouchObserver.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/InteractionTracker.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/NativeTouchInterceptor.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/tracking/ScreenTracker.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport$UploadResult.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport$upload$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/transport/ReplayTransport.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder$Result.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceRecorder.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber$TranscriptResult.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber$listener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/replaysdk/voice/VoiceTranscriber.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ScaleBunPackage$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ScaleBunPackage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashPackage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/crash/ScaleBunCrashSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$WindowInsetEdges.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule$shakeListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngageModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunEngagePackage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/engage/ScaleBunNotificationPresenter.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/ScaleBunOtaSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/SlotManager$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/ota/SlotManager.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule$coreListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/performance/PerformanceSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule$getInstallReferrer$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/referrer/ScaleBunInstallReferrerSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/rn/storage/ScaleBunStorageSpec.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/storage/KvFileStore$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/scalebun/storage/KvFileStore.class +0 -0
|
@@ -1,1233 +1,1568 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ScaleBun SDK — Backend Session Adapter
|
|
3
|
-
*
|
|
4
|
-
* Implements the SessionTransport interface (System A) and bridges
|
|
5
|
-
* session/frame/event data to the backend API via HTTP.
|
|
6
|
-
*
|
|
7
|
-
* This is the ADAPTER that connects the existing SessionManager
|
|
8
|
-
* (which only has DesktopSessionTransport) to the backend.
|
|
9
|
-
*
|
|
10
|
-
* Design:
|
|
11
|
-
* - Uses the same endpoint contract as BackendReplayTransport
|
|
12
|
-
* (POST /v1/replay/sessions, /frames, /events, /finalize)
|
|
13
|
-
* - Batches frames and events with auto-flush
|
|
14
|
-
* - Never throws — all errors are caught and logged
|
|
15
|
-
* - Behind config flag: only constructed when backendUpload is enabled
|
|
16
|
-
*
|
|
17
|
-
* This does NOT duplicate the existing BackendReplayTransport.
|
|
18
|
-
* It exists because SessionManager uses a different interface
|
|
19
|
-
* (SessionTransport from sessionTypes.ts) than ReplayTransport
|
|
20
|
-
* (from features/replay/transport/ReplayTransport.ts).
|
|
21
|
-
* The payload shapes differ, so this adapter maps between them.
|
|
22
|
-
*
|
|
23
|
-
* MVP/dev-only: base64 frames are sent inline in JSON body.
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import { logger } from '../../core/logger/internalLogger';
|
|
27
|
-
import { base64ToBytes } from '../../core/encoding/base64';
|
|
28
|
-
import { ENDPOINTS } from '../../transport/http/endpoints';
|
|
29
|
-
import { SDK_VERSION } from '../../core/constants/version';
|
|
30
|
-
import { bridgeAdapter } from '../replay/bridge/adapters/bridgeAdapter';
|
|
31
|
-
import { getReplaySdkNative } from '../replay/bridge/nativeModule';
|
|
32
|
-
import type { ReplaySdkNativeModule } from '../replay/bridge/nativeModule';
|
|
33
|
-
import type { StorageBackend } from '../../storage/StorageBackend';
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
*
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
private
|
|
113
|
-
/**
|
|
114
|
-
private
|
|
115
|
-
|
|
116
|
-
private
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
private
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
private
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
private
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
logger.info(`[ScaleBun Replay]
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
);
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*/
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
/**
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
//
|
|
489
|
-
//
|
|
490
|
-
|
|
491
|
-
this.
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
this
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
this.
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
if (this.
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
if (this.
|
|
608
|
-
this.
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
this._flushFrames()
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
*/
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
*
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if (!this.
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
private
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
const
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* ScaleBun SDK — Backend Session Adapter
|
|
3
|
+
*
|
|
4
|
+
* Implements the SessionTransport interface (System A) and bridges
|
|
5
|
+
* session/frame/event data to the backend API via HTTP.
|
|
6
|
+
*
|
|
7
|
+
* This is the ADAPTER that connects the existing SessionManager
|
|
8
|
+
* (which only has DesktopSessionTransport) to the backend.
|
|
9
|
+
*
|
|
10
|
+
* Design:
|
|
11
|
+
* - Uses the same endpoint contract as BackendReplayTransport
|
|
12
|
+
* (POST /v1/replay/sessions, /frames, /events, /finalize)
|
|
13
|
+
* - Batches frames and events with auto-flush
|
|
14
|
+
* - Never throws — all errors are caught and logged
|
|
15
|
+
* - Behind config flag: only constructed when backendUpload is enabled
|
|
16
|
+
*
|
|
17
|
+
* This does NOT duplicate the existing BackendReplayTransport.
|
|
18
|
+
* It exists because SessionManager uses a different interface
|
|
19
|
+
* (SessionTransport from sessionTypes.ts) than ReplayTransport
|
|
20
|
+
* (from features/replay/transport/ReplayTransport.ts).
|
|
21
|
+
* The payload shapes differ, so this adapter maps between them.
|
|
22
|
+
*
|
|
23
|
+
* MVP/dev-only: base64 frames are sent inline in JSON body.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { logger } from '../../core/logger/internalLogger';
|
|
27
|
+
import { base64ToBytes } from '../../core/encoding/base64';
|
|
28
|
+
import { ENDPOINTS } from '../../transport/http/endpoints';
|
|
29
|
+
import { SDK_VERSION } from '../../core/constants/version';
|
|
30
|
+
import { bridgeAdapter } from '../replay/bridge/adapters/bridgeAdapter';
|
|
31
|
+
import { getReplaySdkNative } from '../replay/bridge/nativeModule';
|
|
32
|
+
import type { ReplaySdkNativeModule } from '../replay/bridge/nativeModule';
|
|
33
|
+
import type { StorageBackend } from '../../storage/StorageBackend';
|
|
34
|
+
// Reused rather than reimplemented: `chunkEvents` is generic, order-preserving, and already carries
|
|
35
|
+
// a contract test proving it drops and duplicates nothing (analytics/__tests__/batchChunking.test.ts).
|
|
36
|
+
// Its internal ceiling (MAX_BATCH_EVENTS = 500) is well above the 100-frame cap passed here.
|
|
37
|
+
import { chunkEvents } from '../../analytics/batching';
|
|
38
|
+
import type {
|
|
39
|
+
SessionTransport,
|
|
40
|
+
Session,
|
|
41
|
+
SessionMetadata,
|
|
42
|
+
JourneyEvent,
|
|
43
|
+
ReplayFrame,
|
|
44
|
+
} from './sessionTypes';
|
|
45
|
+
|
|
46
|
+
// ─── Config ─────────────────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
export interface BackendSessionConfig {
|
|
49
|
+
/** Backend API base URL (e.g. http://localhost:3001/api) */
|
|
50
|
+
endpoint: string;
|
|
51
|
+
/** Batch size for frames before auto-flush. Default: 5 */
|
|
52
|
+
batchSize?: number;
|
|
53
|
+
/** Auto-flush interval in ms. Default: 3000 */
|
|
54
|
+
flushIntervalMs?: number;
|
|
55
|
+
/** Request timeout in ms. Default: 15000 */
|
|
56
|
+
timeoutMs?: number;
|
|
57
|
+
/** SaaS multi-tenant client key — enables ingestion endpoints and x-scalebun-client-key header */
|
|
58
|
+
clientKey?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Upload frame bytes directly to object storage via presigned PUT instead of
|
|
61
|
+
* inline base64 in the JSON body. Default false → legacy inline path. Flip on
|
|
62
|
+
* after the backend presign endpoint is deployed. Falls back to inline
|
|
63
|
+
* automatically if the backend reports storage is not configured.
|
|
64
|
+
*/
|
|
65
|
+
useObjectStorage?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Route telemetry lanes (events/network/errors/performance/logs) through the
|
|
68
|
+
* durable NATIVE file outbox instead of JS-side HTTP. Only takes effect when BOTH
|
|
69
|
+
* this and `nativeOutboxUploadEnabled` are true AND the native module exposes the
|
|
70
|
+
* outbox methods — otherwise the existing JS upload path is used unchanged. When
|
|
71
|
+
* active, the native uploader owns delivery (no duplicate JS POST). Default false.
|
|
72
|
+
*/
|
|
73
|
+
enableNativeFileOutbox?: boolean;
|
|
74
|
+
/** Native outbox actually uploads (vs. capture/store-only). Gates telemetry routing. */
|
|
75
|
+
nativeOutboxUploadEnabled?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Additive native-outbox tuning flags (retry interval, attempt caps, Retry-After,
|
|
78
|
+
* byte/age GC bounds, etc.) forwarded verbatim to the native `initOutbox` dict.
|
|
79
|
+
* Native parses both `nativeOutbox*` and bare `outbox*` keys and applies its own
|
|
80
|
+
* defaults for anything omitted — so an empty object changes nothing.
|
|
81
|
+
*/
|
|
82
|
+
nativeOutboxTuning?: Record<string, unknown>;
|
|
83
|
+
/** Idle-gap threshold (ms) the SDK recorded with; persisted on the session row. */
|
|
84
|
+
idleThresholdMs?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Durable key-value store used to persist the unflushed frame buffer across a
|
|
87
|
+
* process kill. On background the in-flight frames are snapshotted here; on the
|
|
88
|
+
* next launch they are re-uploaded and linked to the PRIOR session. Omitted →
|
|
89
|
+
* frame-kill recovery is disabled (in-memory only, prior behavior).
|
|
90
|
+
*/
|
|
91
|
+
storage?: StorageBackend;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* One platform-agnostic log line for the logs lane. The queue forwards whatever it is
|
|
96
|
+
* given — `source`/`platform` are neutral string hints set by the PRODUCER (console
|
|
97
|
+
* tags 'console'/'js'; a future native producer tags its own values onto this SAME
|
|
98
|
+
* shape). `level` is free-text. Nothing here is JS-specific.
|
|
99
|
+
*/
|
|
100
|
+
export interface LogQueueItem {
|
|
101
|
+
level: string;
|
|
102
|
+
message: string;
|
|
103
|
+
source: string;
|
|
104
|
+
platform: string;
|
|
105
|
+
timestamp: string;
|
|
106
|
+
metadata?: Record<string, unknown>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ─── Adapter ────────────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
export class BackendSessionAdapter implements SessionTransport {
|
|
112
|
+
private config: Required<Omit<BackendSessionConfig, 'clientKey' | 'storage'>> & { clientKey?: string; storage?: StorageBackend };
|
|
113
|
+
/** Durable store for cross-kill frame recovery (null → recovery disabled). */
|
|
114
|
+
private readonly _frameStore: StorageBackend | null;
|
|
115
|
+
/** Storage key for the snapshotted unflushed frame buffer (see persistPendingFrames). */
|
|
116
|
+
private static readonly PENDING_FRAMES_KEY = 'scalebun_replay_pending_frames';
|
|
117
|
+
/**
|
|
118
|
+
* Byte budget for the cross-kill frame snapshot (see `_selectFramesToPersist`).
|
|
119
|
+
*
|
|
120
|
+
* Replaces a flat 10-frame cap. A count could not bound the KV write at all — these frames carry
|
|
121
|
+
* base64 screenshots, so ten of them is anywhere from ~200 KB to several MB depending on device
|
|
122
|
+
* resolution, and an oversized value is exactly what fails on the background transition where
|
|
123
|
+
* this write happens.
|
|
124
|
+
*
|
|
125
|
+
* 2 MB is deliberately modest: this is a last-resort snapshot for frames that never reached the
|
|
126
|
+
* network, not a mirror of the session. Enough for a keyframe plus a run of deltas on any device;
|
|
127
|
+
* small enough that writing it cannot itself be the reason backgrounding stalls.
|
|
128
|
+
*/
|
|
129
|
+
private static readonly MAX_PERSIST_BYTES = 2 * 1024 * 1024;
|
|
130
|
+
/**
|
|
131
|
+
* Frames the backend accepts in ONE request — `'Max 100 frames per batch'`
|
|
132
|
+
* (`IngestionService.uploadFrames`). Exceeding it is a 4xx, which this SDK classifies as
|
|
133
|
+
* permanent.
|
|
134
|
+
*
|
|
135
|
+
* This has to exist alongside the byte budget, not instead of it. The budget alone cannot bound
|
|
136
|
+
* the COUNT, and the count is what the server checks: measured on real traffic, mobile keyframes
|
|
137
|
+
* average ~16 KB, so a 2 MB snapshot is around 128 frames — over the cap by construction. The old
|
|
138
|
+
* flat 10-frame rule was under it by construction, which is why this failure could not happen
|
|
139
|
+
* before and can now.
|
|
140
|
+
*/
|
|
141
|
+
private static readonly MAX_FRAMES_PER_BATCH = 100;
|
|
142
|
+
// Per-session toggle: cleared to false if the backend reports storage disabled.
|
|
143
|
+
private objectStorageActive: boolean;
|
|
144
|
+
// True when telemetry should divert to the durable native outbox (both flags on).
|
|
145
|
+
// Native module availability is re-checked per call so a missing/old binary falls
|
|
146
|
+
// back to the JS path transparently.
|
|
147
|
+
private readonly nativeOutboxEnabled: boolean;
|
|
148
|
+
// Cached one-shot native-outbox bootstrap promise (see _ensureNativeOutbox).
|
|
149
|
+
private _nativeOutboxReady: Promise<boolean> | null = null;
|
|
150
|
+
private currentSessionId: string | null = null;
|
|
151
|
+
// §11 session_start ordering: a recording sessionId is added here ONLY after its
|
|
152
|
+
// INGESTION_START row is confirmed created on the backend (either via sendSessionStart's
|
|
153
|
+
// own POST, or via startAnalyticsSession when recording adopts the analytics id).
|
|
154
|
+
// Child telemetry lanes (frames/events/network/errors/perf/logs) refuse to flush until
|
|
155
|
+
// the row exists — otherwise the backend 404s the child write. Data stays buffered and
|
|
156
|
+
// the flush timer retries, so nothing is lost to a start/child race. The durable native
|
|
157
|
+
// outbox path has its own ordering; this guards only the JS in-memory fallback.
|
|
158
|
+
private readonly _startedSessionIds = new Set<string>();
|
|
159
|
+
private pendingFrames: Array<{ frame: ReplayFrame; imageData: string }> = [];
|
|
160
|
+
private pendingEvents: JourneyEvent[] = [];
|
|
161
|
+
private pendingNetworkRequests: Array<Record<string, unknown>> = [];
|
|
162
|
+
private pendingErrors: Array<Record<string, unknown>> = [];
|
|
163
|
+
private pendingPerformanceMetrics: Array<Record<string, unknown>> = [];
|
|
164
|
+
// Platform-agnostic logs lane. Neutral by construction — holds whatever LogQueueItems
|
|
165
|
+
// it's handed (console today; native later) and forwards them untouched.
|
|
166
|
+
private pendingLogs: LogQueueItem[] = [];
|
|
167
|
+
private flushTimer: ReturnType<typeof setInterval> | null = null;
|
|
168
|
+
private destroyed = false;
|
|
169
|
+
/**
|
|
170
|
+
* Latch for `sdk_replay_capture_failed` — reported once per adapter, not once per rejected batch.
|
|
171
|
+
*
|
|
172
|
+
* A session whose row was never created rejects EVERY frame batch, so an unlatched report would
|
|
173
|
+
* emit one analytics event per flush for as long as the app stays open, on the same lane it is
|
|
174
|
+
* trying to report through.
|
|
175
|
+
*/
|
|
176
|
+
private _captureFailureReported = false;
|
|
177
|
+
|
|
178
|
+
// ── Analytics lane (always-on, foreground-scoped; isolated from recording) ──
|
|
179
|
+
// Fully separate from currentSessionId/pendingEvents/_flushEvents, which serve
|
|
180
|
+
// recording. This lane carries user track() events and never touches recording
|
|
181
|
+
// state. One queue doubles as the pre-ready buffer (bounded, drop-oldest) and
|
|
182
|
+
// the outgoing queue; sessionId is stamped at flush so endpoint id == body id.
|
|
183
|
+
private static readonly ANALYTICS_BUFFER_CAP = 100;
|
|
184
|
+
/** Logs lane: queue length that triggers an eager flush (mirrors the network lane). */
|
|
185
|
+
private static readonly LOGS_BATCH_SIZE = 20;
|
|
186
|
+
/** Logs lane: max rows posted per flush (server caps at 200/batch). */
|
|
187
|
+
private static readonly LOGS_FLUSH_MAX = 50;
|
|
188
|
+
private _analyticsSessionId: string | null = null;
|
|
189
|
+
private pendingAnalyticsEvents: JourneyEvent[] = [];
|
|
190
|
+
private analyticsFlushTimer: ReturnType<typeof setInterval> | null = null;
|
|
191
|
+
// iOS finalize reconciliation: the id of a backgrounded analytics session whose
|
|
192
|
+
// INGESTION_FINALIZE has NOT been confirmed delivered. Set synchronously in
|
|
193
|
+
// finalizeAnalyticsSession before any await (so it survives an iOS suspension of
|
|
194
|
+
// the awaited fetch), cleared only on a confirmed finalize ACK. On the next
|
|
195
|
+
// foreground the listener calls reconcilePendingFinalize() to close it for real.
|
|
196
|
+
// In-memory is sufficient: the JS context survives background→foreground; only a
|
|
197
|
+
// true process kill drops it (covered by the server-side idle-close backstop).
|
|
198
|
+
private _pendingFinalizeId: string | null = null;
|
|
199
|
+
|
|
200
|
+
constructor(config: BackendSessionConfig) {
|
|
201
|
+
this.config = {
|
|
202
|
+
batchSize: 5,
|
|
203
|
+
flushIntervalMs: 3000,
|
|
204
|
+
timeoutMs: 15_000,
|
|
205
|
+
useObjectStorage: false,
|
|
206
|
+
enableNativeFileOutbox: false,
|
|
207
|
+
nativeOutboxUploadEnabled: false,
|
|
208
|
+
nativeOutboxTuning: {},
|
|
209
|
+
idleThresholdMs: 60_000,
|
|
210
|
+
...config,
|
|
211
|
+
clientKey: config.clientKey,
|
|
212
|
+
};
|
|
213
|
+
this._frameStore = config.storage ?? null;
|
|
214
|
+
this.objectStorageActive = this.config.useObjectStorage;
|
|
215
|
+
this.nativeOutboxEnabled =
|
|
216
|
+
this.config.enableNativeFileOutbox && this.config.nativeOutboxUploadEnabled;
|
|
217
|
+
logger.info(`[ScaleBun Replay] backendUpload enabled`);
|
|
218
|
+
logger.info(`[ScaleBun Replay] backendBaseUrl: ${this.config.endpoint}`);
|
|
219
|
+
logger.info(`[ScaleBun Replay] transport fan-out active: desktop yes, backend yes`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ─── SessionTransport Interface ─────────────────────────────────────
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* §11 gate: true only when the current recording session's INGESTION_START row is
|
|
226
|
+
* confirmed on the backend. Child telemetry lanes consult this before flushing so they
|
|
227
|
+
* never race ahead of session creation (which would 404). Null id → not ready.
|
|
228
|
+
*/
|
|
229
|
+
private _sessionRowReady(): boolean {
|
|
230
|
+
return !!this.currentSessionId && this._startedSessionIds.has(this.currentSessionId);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
sendSessionStart(session: Session): void {
|
|
234
|
+
this.currentSessionId = session.sessionId;
|
|
235
|
+
this._startFlushTimer();
|
|
236
|
+
|
|
237
|
+
logger.info(`[ScaleBun Replay] session start requested`);
|
|
238
|
+
logger.info(`[ScaleBun Replay] sessionId: ${session.sessionId}`);
|
|
239
|
+
logger.info(`[ScaleBun Replay] deviceId: ${session.deviceId}`);
|
|
240
|
+
logger.info(`[ScaleBun Replay] recordingSessionId: ${session.sessionId}`);
|
|
241
|
+
|
|
242
|
+
// One-row merge: when recording adopted the always-on analytics id
|
|
243
|
+
// (SessionManager.startSession), the INGESTION_START row already exists.
|
|
244
|
+
// Do NOT post a second one — just keep the flush timer running so frames/
|
|
245
|
+
// journey/network/errors/perf flush to INGESTION_*(analyticsId). Legacy
|
|
246
|
+
// mode (no clientKey, distinct minted id) still posts /replay/sessions.
|
|
247
|
+
if (this.config.clientKey && session.sessionId === this._analyticsSessionId) {
|
|
248
|
+
logger.info(`[ScaleBun Replay] recording attached to analytics session ${session.sessionId} (no new row)`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
logger.info(`[ScaleBun Replay] backend session upload started`);
|
|
253
|
+
|
|
254
|
+
const startEndpoint = this.config.clientKey ? ENDPOINTS.INGESTION_START : '/replay/sessions';
|
|
255
|
+
|
|
256
|
+
// Fetch native device info to enrich the session payload.
|
|
257
|
+
// Falls back to metadata-only if bridge unavailable (old native binary).
|
|
258
|
+
bridgeAdapter.getDeviceInfo()
|
|
259
|
+
.then(nativeInfo => {
|
|
260
|
+
const m = session.metadata;
|
|
261
|
+
this._cachedAppVersion = nativeInfo?.appVersion ?? m?.appVersion ?? null;
|
|
262
|
+
const payload = {
|
|
263
|
+
sessionId: session.sessionId,
|
|
264
|
+
deviceId: session.deviceId,
|
|
265
|
+
startedAt: session.startedAt,
|
|
266
|
+
// Link the recording row to the always-on analytics row so the
|
|
267
|
+
// dashboard can join them. track() events land on the analytics
|
|
268
|
+
// id; frames/journey land on this recording id. Without this
|
|
269
|
+
// link the two appear as separate sessions (one looks "empty").
|
|
270
|
+
// BACKEND DEPENDENCY: the dashboard must read/join on this field
|
|
271
|
+
// (or treat the analytics row as canonical) to fully merge them.
|
|
272
|
+
analyticsSessionId: this._analyticsSessionId,
|
|
273
|
+
// Carry the idle threshold on the recording lane too: it may
|
|
274
|
+
// create the row before the analytics lane does. Backend
|
|
275
|
+
// upsert leaves it untouched if already set.
|
|
276
|
+
idleThresholdMs: this.config.idleThresholdMs,
|
|
277
|
+
device: {
|
|
278
|
+
platform: nativeInfo?.platform ?? m?.platform,
|
|
279
|
+
osVersion: nativeInfo?.osVersion ?? m?.osVersion,
|
|
280
|
+
deviceModel: nativeInfo?.deviceModel ?? m?.deviceModel,
|
|
281
|
+
screenWidth: m?.screenWidth,
|
|
282
|
+
screenHeight: m?.screenHeight,
|
|
283
|
+
appName: nativeInfo?.appName ?? m?.appName,
|
|
284
|
+
appVersion: nativeInfo?.appVersion ?? m?.appVersion,
|
|
285
|
+
bundleId: nativeInfo?.bundleId ?? m?.bundleId,
|
|
286
|
+
sdkVersion: SDK_VERSION,
|
|
287
|
+
releaseStage: m?.buildType,
|
|
288
|
+
// Backend ingestion source not in this repo; field name
|
|
289
|
+
// unconfirmed. Send both so whichever it reads is populated.
|
|
290
|
+
environment: m?.buildType,
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
logger.debug(`[BackendSessionAdapter] POST session start: ${session.sessionId}`);
|
|
294
|
+
return this._post(startEndpoint, payload);
|
|
295
|
+
})
|
|
296
|
+
.then(() => {
|
|
297
|
+
// §11: row now exists — release the child-lane flush gate for this id.
|
|
298
|
+
this._startedSessionIds.add(session.sessionId);
|
|
299
|
+
logger.info(`[ScaleBun Replay] backend session upload success`);
|
|
300
|
+
})
|
|
301
|
+
.catch(() => logger.info(`[ScaleBun Replay] backend session upload failure`));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
sendSessionEnd(session: Session): void {
|
|
305
|
+
logger.info(`[ScaleBun Replay] finalize started`);
|
|
306
|
+
// Flush all pending data first, then finalize
|
|
307
|
+
Promise.all([
|
|
308
|
+
this._flushFrames(),
|
|
309
|
+
this._flushEvents(),
|
|
310
|
+
this._flushNetwork(),
|
|
311
|
+
this._flushErrors(),
|
|
312
|
+
this._flushPerformance(),
|
|
313
|
+
]).then(() => {
|
|
314
|
+
// One-row merge: if this recording adopted the always-on analytics id,
|
|
315
|
+
// the analytics lane owns the session's lifecycle and finalizes it on
|
|
316
|
+
// background (finalizeAnalyticsSession). Finalizing here would close the
|
|
317
|
+
// shared row mid-foreground and orphan later track() events — so flush
|
|
318
|
+
// (above) but skip finalize. Legacy/distinct-id sessions finalize normally.
|
|
319
|
+
if (this.config.clientKey && session.sessionId === this._analyticsSessionId) {
|
|
320
|
+
logger.info(`[ScaleBun Replay] recording ended; analytics session ${session.sessionId} stays open`);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const finalizeEndpoint = this.config.clientKey
|
|
324
|
+
? ENDPOINTS.INGESTION_FINALIZE(session.sessionId)
|
|
325
|
+
: `/replay/sessions/${session.sessionId}/finalize`;
|
|
326
|
+
return this._post(
|
|
327
|
+
finalizeEndpoint,
|
|
328
|
+
{
|
|
329
|
+
endedAt: session.endedAt ?? Date.now(),
|
|
330
|
+
durationMs: session.endedAt
|
|
331
|
+
? session.endedAt - session.startedAt
|
|
332
|
+
: Date.now() - session.startedAt,
|
|
333
|
+
totalFrames: session.artifactIndex?.frameRefs?.length ?? 0,
|
|
334
|
+
totalEvents: session.artifactIndex?.eventRefs?.length ?? 0,
|
|
335
|
+
finalState: session.status === 'timeout' ? 'timeout' : 'completed',
|
|
336
|
+
},
|
|
337
|
+
);
|
|
338
|
+
}).then(() => {
|
|
339
|
+
logger.info(`[ScaleBun Replay] finalize success`);
|
|
340
|
+
}).catch(() => {
|
|
341
|
+
logger.info(`[ScaleBun Replay] finalize failure`);
|
|
342
|
+
}).finally(() => {
|
|
343
|
+
this._stopFlushTimer();
|
|
344
|
+
// Keep the row-ready gate OPEN for a merged analytics session. The analytics
|
|
345
|
+
// lane still owns it (not finalized on background — the session spans the
|
|
346
|
+
// app-switch), so a foreground restart re-adopts the SAME id and must keep
|
|
347
|
+
// flushing frames/events. Dropping the gate here would 404-buffer everything
|
|
348
|
+
// after the first background cycle. Only clear it for a distinct/legacy
|
|
349
|
+
// recording id that was actually finalized above.
|
|
350
|
+
if (!(this.config.clientKey && session.sessionId === this._analyticsSessionId)) {
|
|
351
|
+
this._startedSessionIds.delete(session.sessionId);
|
|
352
|
+
}
|
|
353
|
+
// Session end: drain any durably-stored telemetry from the native outbox.
|
|
354
|
+
this._triggerNativeFlush();
|
|
355
|
+
logger.debug(`[BackendSessionAdapter] Session finalized: ${session.sessionId}`);
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// ─── Analytics Lane (isolated from recording) ───────────────────────
|
|
360
|
+
|
|
361
|
+
/** Public: the always-on analytics session id, or null before it opens. */
|
|
362
|
+
get analyticsSessionId(): string | null {
|
|
363
|
+
return this._analyticsSessionId;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Open the always-on analytics ingestion session. Sets the analytics id,
|
|
368
|
+
* starts the analytics flush timer, replays any pre-ready buffered events,
|
|
369
|
+
* and POSTs INGESTION_START. Mirrors sendSessionStart's body builder but
|
|
370
|
+
* never touches currentSessionId (recording lane).
|
|
371
|
+
*/
|
|
372
|
+
async startAnalyticsSession(session: {
|
|
373
|
+
sessionId: string;
|
|
374
|
+
deviceId: string;
|
|
375
|
+
startedAt: number;
|
|
376
|
+
metadata?: SessionMetadata;
|
|
377
|
+
/** Idle-gap threshold (ms) the SDK declares for this session; echoed by the
|
|
378
|
+
* backend so the dashboard uses the same value to draw idle bands. */
|
|
379
|
+
idleThresholdMs?: number;
|
|
380
|
+
}): Promise<void> {
|
|
381
|
+
if (this.destroyed) return;
|
|
382
|
+
this._analyticsSessionId = session.sessionId;
|
|
383
|
+
// A new session gets its own capture-failure report. The latch bounds reports WITHIN a
|
|
384
|
+
// session; left standing across sessions it silenced every session after the first in the
|
|
385
|
+
// app process, which is the one place this differs from the web SDK — that pipeline is
|
|
386
|
+
// constructed per page and its session id is readonly, so its latch cannot outlive a session.
|
|
387
|
+
this._captureFailureReported = false;
|
|
388
|
+
this._startAnalyticsFlushTimer();
|
|
389
|
+
|
|
390
|
+
// Replay pre-ready buffered events now that the id exists. sessionId is
|
|
391
|
+
// stamped at flush time, so buffered events need no rewrite.
|
|
392
|
+
this._flushAnalyticsEvents().catch(() => { });
|
|
393
|
+
|
|
394
|
+
const startEndpoint = this.config.clientKey ? ENDPOINTS.INGESTION_START : '/replay/sessions';
|
|
395
|
+
try {
|
|
396
|
+
const nativeInfo = await bridgeAdapter.getDeviceInfo();
|
|
397
|
+
const m = session.metadata;
|
|
398
|
+
this._cachedAppVersion = nativeInfo?.appVersion ?? m?.appVersion ?? null;
|
|
399
|
+
const payload = {
|
|
400
|
+
sessionId: session.sessionId,
|
|
401
|
+
deviceId: session.deviceId,
|
|
402
|
+
startedAt: session.startedAt,
|
|
403
|
+
idleThresholdMs: session.idleThresholdMs,
|
|
404
|
+
device: {
|
|
405
|
+
platform: nativeInfo?.platform ?? m?.platform,
|
|
406
|
+
osVersion: nativeInfo?.osVersion ?? m?.osVersion,
|
|
407
|
+
deviceModel: nativeInfo?.deviceModel ?? m?.deviceModel,
|
|
408
|
+
screenWidth: m?.screenWidth,
|
|
409
|
+
screenHeight: m?.screenHeight,
|
|
410
|
+
appName: nativeInfo?.appName ?? m?.appName,
|
|
411
|
+
appVersion: nativeInfo?.appVersion ?? m?.appVersion,
|
|
412
|
+
bundleId: nativeInfo?.bundleId ?? m?.bundleId,
|
|
413
|
+
sdkVersion: SDK_VERSION,
|
|
414
|
+
releaseStage: m?.buildType,
|
|
415
|
+
environment: m?.buildType,
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
await this._post(startEndpoint, payload);
|
|
419
|
+
// §11: row exists. When recording adopts this analytics id (one-row merge),
|
|
420
|
+
// this also releases the recording child-lane gate (_sessionRowReady).
|
|
421
|
+
this._startedSessionIds.add(session.sessionId);
|
|
422
|
+
// Row is confirmed — replay any events buffered while START was in flight.
|
|
423
|
+
// The pre-ack flush at the top of this method is gated off until now, so
|
|
424
|
+
// this is what actually drains the pre-ready buffer (no premature 404).
|
|
425
|
+
this._flushAnalyticsEvents().catch(() => { });
|
|
426
|
+
logger.info(`[ScaleBun Analytics] session start upload success: ${session.sessionId}`);
|
|
427
|
+
} catch {
|
|
428
|
+
logger.info(`[ScaleBun Analytics] session start upload failure`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Enqueue a user track() event. Buffers (bounded, drop-oldest) when the
|
|
434
|
+
* analytics session is not yet open; flushes at >=20 once it is.
|
|
435
|
+
*/
|
|
436
|
+
trackEvent(event: JourneyEvent): void {
|
|
437
|
+
if (this.destroyed) return;
|
|
438
|
+
this.pendingAnalyticsEvents.push(event);
|
|
439
|
+
const overflow = this.pendingAnalyticsEvents.length - BackendSessionAdapter.ANALYTICS_BUFFER_CAP;
|
|
440
|
+
if (overflow > 0) {
|
|
441
|
+
this.pendingAnalyticsEvents.splice(0, overflow); // drop oldest
|
|
442
|
+
}
|
|
443
|
+
if (this._analyticsSessionId && this.pendingAnalyticsEvents.length >= 20) {
|
|
444
|
+
this._flushAnalyticsEvents().catch(() => { });
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Emit an app-lifecycle boundary marker (APP_BACKGROUND / APP_FOREGROUND) onto
|
|
450
|
+
* the analytics lane so the dashboard can shade the backgrounded span on the
|
|
451
|
+
* replay timeline and exclude it from the active duration. Timestamp is captured
|
|
452
|
+
* at the transition (accurate even if delivery is deferred until the next
|
|
453
|
+
* foreground on iOS). No-op when no analytics session is open. The sessionId is
|
|
454
|
+
* (re)stamped at flush time, so passing the current id here is only a placeholder.
|
|
455
|
+
*/
|
|
456
|
+
emitLifecycleMarker(
|
|
457
|
+
type: 'APP_BACKGROUND' | 'APP_FOREGROUND',
|
|
458
|
+
payload?: Record<string, unknown>,
|
|
459
|
+
): void {
|
|
460
|
+
if (this.destroyed || !this._analyticsSessionId) return;
|
|
461
|
+
this.trackEvent({
|
|
462
|
+
eventId: this._clientId(),
|
|
463
|
+
sessionId: this._analyticsSessionId,
|
|
464
|
+
ts: Date.now(),
|
|
465
|
+
type,
|
|
466
|
+
source: 'sdk',
|
|
467
|
+
...(payload ? { payload } : {}),
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Public: force-flush queued analytics events immediately. Called on
|
|
473
|
+
* APP_BACKGROUND so the lifecycle marker (and any buffered track events) reach
|
|
474
|
+
* the backend before the OS suspends the flush timer. Best-effort on iOS, where
|
|
475
|
+
* the POST may not resolve until the next foreground — the events stay buffered
|
|
476
|
+
* with accurate timestamps and flush then.
|
|
477
|
+
*/
|
|
478
|
+
flushAnalytics(): Promise<void> {
|
|
479
|
+
return this._flushAnalyticsEvents();
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Flush queued analytics events. Mirrors _flushEvents (recording) byte for
|
|
484
|
+
* byte on the wire map, but gates on _analyticsSessionId and STAMPS that id
|
|
485
|
+
* into every event so endpoint id == body sessionId by construction.
|
|
486
|
+
*/
|
|
487
|
+
private async _flushAnalyticsEvents(forSessionId?: string): Promise<void> {
|
|
488
|
+
// finalize clears _analyticsSessionId synchronously, then passes the
|
|
489
|
+
// captured id here so the final drain still targets the right session.
|
|
490
|
+
const sessionId = forSessionId ?? this._analyticsSessionId;
|
|
491
|
+
if (this.pendingAnalyticsEvents.length === 0 || !sessionId) return;
|
|
492
|
+
|
|
493
|
+
// Row-confirmed gate (mirrors the recording lanes' _sessionRowReady). The
|
|
494
|
+
// INGESTION_START create is async and can fail/lag; flushing events before
|
|
495
|
+
// the row exists 404s the child write and re-buffers forever. Keep events
|
|
496
|
+
// queued (bounded, drop-oldest via trackEvent) until START is acked.
|
|
497
|
+
if (!this._startedSessionIds.has(sessionId)) return;
|
|
498
|
+
|
|
499
|
+
const batch = this.pendingAnalyticsEvents.splice(0, 20);
|
|
500
|
+
const events = batch.map(e => this._leanEvent(e, sessionId));
|
|
501
|
+
|
|
502
|
+
try {
|
|
503
|
+
const eventsEndpoint = this.config.clientKey
|
|
504
|
+
? ENDPOINTS.INGESTION_EVENTS(sessionId)
|
|
505
|
+
: `/replay/sessions/${sessionId}/events`;
|
|
506
|
+
await this._post(eventsEndpoint, { events });
|
|
507
|
+
logger.debug(`[BackendSessionAdapter] Flushed ${batch.length} analytics event(s)`);
|
|
508
|
+
} catch (err) {
|
|
509
|
+
if (!BackendSessionAdapter._isPermanentHttpError(err)) this.pendingAnalyticsEvents.unshift(...batch);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/** Flush remaining analytics events, finalize the session, stop its timer. */
|
|
514
|
+
async finalizeAnalyticsSession(): Promise<void> {
|
|
515
|
+
const sessionId = this._analyticsSessionId;
|
|
516
|
+
if (!sessionId) return;
|
|
517
|
+
|
|
518
|
+
// Clear the id and stop the timer SYNCHRONOUSLY, before any await. On iOS
|
|
519
|
+
// the app is suspended on background and the finalize fetch below never
|
|
520
|
+
// resolves until the next foreground, so the old `finally` that nulled the
|
|
521
|
+
// id never ran before the resume guard (SDKBootstrapper: `state==='active'
|
|
522
|
+
// && !adapter.analyticsSessionId`) evaluated → guard stayed false → no new
|
|
523
|
+
// session opened. Clearing up front makes the guard always see null after
|
|
524
|
+
// background, so resume re-opens a fresh analytics session every cycle.
|
|
525
|
+
this._analyticsSessionId = null;
|
|
526
|
+
this._stopAnalyticsFlushTimer();
|
|
527
|
+
|
|
528
|
+
// Mark as pending-finalize BEFORE any await. On iOS the app suspends right
|
|
529
|
+
// after backgrounding, so the awaited _post below may never resolve. Setting
|
|
530
|
+
// the marker synchronously guarantees the next foreground can reconcile-close
|
|
531
|
+
// this id even though the background POST was suspended. Cleared only on a
|
|
532
|
+
// confirmed ACK (below), so a suspended POST leaves the marker in place.
|
|
533
|
+
this._pendingFinalizeId = sessionId;
|
|
534
|
+
|
|
535
|
+
try {
|
|
536
|
+
// Pass the captured id explicitly — the field is already cleared.
|
|
537
|
+
await this._flushAnalyticsEvents(sessionId);
|
|
538
|
+
const finalizeEndpoint = this.config.clientKey
|
|
539
|
+
? ENDPOINTS.INGESTION_FINALIZE(sessionId)
|
|
540
|
+
: `/replay/sessions/${sessionId}/finalize`;
|
|
541
|
+
await this._post(finalizeEndpoint, { endedAt: Date.now() });
|
|
542
|
+
// Confirmed delivered → drop the marker so the foreground reconciler does
|
|
543
|
+
// NOT re-finalize this id (first half of the no-double-finalize guard).
|
|
544
|
+
if (this._pendingFinalizeId === sessionId) this._pendingFinalizeId = null;
|
|
545
|
+
logger.debug(`[BackendSessionAdapter] Analytics session finalized: ${sessionId}`);
|
|
546
|
+
} catch {
|
|
547
|
+
// Leave the marker set — foreground reconciliation will retry the close.
|
|
548
|
+
logger.info(`[ScaleBun Analytics] finalize failure (will reconcile on foreground): ${sessionId}`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Close any analytics session left open by a suspended background finalize.
|
|
554
|
+
* Called on the NEXT foreground (SDKBootstrapper app-state 'active') BEFORE a new
|
|
555
|
+
* analytics session is opened. JS is live on foreground, so this POST completes.
|
|
556
|
+
* No-op when there is no pending id. Idempotent with the background finalize: the
|
|
557
|
+
* marker is cleared on a confirmed background ACK, so this only fires when the
|
|
558
|
+
* background POST was NOT confirmed; if that suspended POST later also lands, the
|
|
559
|
+
* server must treat a repeat INGESTION_FINALIZE for the same id as a no-op.
|
|
560
|
+
*/
|
|
561
|
+
async reconcilePendingFinalize(): Promise<void> {
|
|
562
|
+
const sessionId = this._pendingFinalizeId;
|
|
563
|
+
if (!sessionId) return;
|
|
564
|
+
|
|
565
|
+
try {
|
|
566
|
+
const finalizeEndpoint = this.config.clientKey
|
|
567
|
+
? ENDPOINTS.INGESTION_FINALIZE(sessionId)
|
|
568
|
+
: `/replay/sessions/${sessionId}/finalize`;
|
|
569
|
+
await this._post(finalizeEndpoint, { endedAt: Date.now() });
|
|
570
|
+
logger.info(`[ScaleBun Analytics] reconciled finalize on foreground: ${sessionId}`);
|
|
571
|
+
} catch {
|
|
572
|
+
logger.info(`[ScaleBun Analytics] foreground reconcile finalize failed: ${sessionId}`);
|
|
573
|
+
} finally {
|
|
574
|
+
// Clear after a foreground attempt regardless of outcome: JS is live here
|
|
575
|
+
// so a transient network error is rare, and the server-side idle-close
|
|
576
|
+
// backstop covers any still-orphaned row. Bounds total finalizes per id to
|
|
577
|
+
// at most 2 (suspended-bg + foreground) — never a per-foreground loop.
|
|
578
|
+
if (this._pendingFinalizeId === sessionId) this._pendingFinalizeId = null;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
private _startAnalyticsFlushTimer(): void {
|
|
583
|
+
this._stopAnalyticsFlushTimer();
|
|
584
|
+
this.analyticsFlushTimer = setInterval(() => {
|
|
585
|
+
this._flushAnalyticsEvents().catch(() => { });
|
|
586
|
+
}, this.config.flushIntervalMs);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
private _stopAnalyticsFlushTimer(): void {
|
|
590
|
+
if (this.analyticsFlushTimer) {
|
|
591
|
+
clearInterval(this.analyticsFlushTimer);
|
|
592
|
+
this.analyticsFlushTimer = null;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
sendEvent(event: JourneyEvent): void {
|
|
597
|
+
if (this.destroyed) return;
|
|
598
|
+
|
|
599
|
+
logger.info(`[ScaleBun Replay] event recorded`);
|
|
600
|
+
logger.info(` eventId: ${event.eventId}`);
|
|
601
|
+
logger.info(` type: ${event.type}`);
|
|
602
|
+
logger.info(` timestamp: ${event.ts}`);
|
|
603
|
+
logger.info(` sessionId: ${event.sessionId}`);
|
|
604
|
+
|
|
605
|
+
this.pendingEvents.push(event);
|
|
606
|
+
|
|
607
|
+
if (this.pendingEvents.length >= 20) {
|
|
608
|
+
this._flushEvents().catch(() => { });
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
sendFrame(frame: ReplayFrame, imageData: string): void {
|
|
613
|
+
if (this.destroyed) return;
|
|
614
|
+
|
|
615
|
+
logger.info(`[ScaleBun Replay] frame captured`);
|
|
616
|
+
logger.info(` frameId: ${frame.frameId}`);
|
|
617
|
+
logger.info(` timestamp: ${frame.ts}`);
|
|
618
|
+
logger.info(` sessionId: ${frame.sessionId}`);
|
|
619
|
+
logger.info(` width/height: ${frame.width}x${frame.height}`);
|
|
620
|
+
|
|
621
|
+
this.pendingFrames.push({ frame, imageData });
|
|
622
|
+
|
|
623
|
+
if (this.pendingFrames.length >= this.config.batchSize) {
|
|
624
|
+
this._flushFrames().catch(() => { });
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// ─── SaaS Ingestion Queues ──────────────────────────────────────────
|
|
629
|
+
|
|
630
|
+
queueNetworkRequest(data: {
|
|
631
|
+
method: string; url: string; statusCode?: number; duration?: number;
|
|
632
|
+
screenName?: string; error?: string; requestSize?: number; responseSize?: number;
|
|
633
|
+
requestHeaders?: Record<string, string>; responseHeaders?: Record<string, string>;
|
|
634
|
+
}): void {
|
|
635
|
+
if (this.destroyed || !this.config.clientKey) return;
|
|
636
|
+
// clientId: stable per-row idempotency key so a mobile retry of the same
|
|
637
|
+
// batch upserts instead of inserting duplicates server-side.
|
|
638
|
+
this.pendingNetworkRequests.push({ ...data, clientId: this._clientId(), timestamp: new Date().toISOString() });
|
|
639
|
+
if (this.pendingNetworkRequests.length >= 20) {
|
|
640
|
+
this._flushNetwork().catch(() => {});
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// D8/D9/D12: this signature was {type, message, stack, screenName} — four
|
|
645
|
+
// fields — while the backend row and every dashboard surface were already
|
|
646
|
+
// built for the rest. The consequences of the four-field bottleneck:
|
|
647
|
+
// regression detection permanently false (no appVersion on any mobile
|
|
648
|
+
// error), Issue.primaryPlatform NULL for every RN crash (no platform), and
|
|
649
|
+
// native crash signal/thread/exception-type discarded one call before the
|
|
650
|
+
// wire (no metadata). The receiver needed nothing; only this signature did.
|
|
651
|
+
/** App version resolved at session start; errors stamp it so regression
|
|
652
|
+
* detection has a version to work with (D8). Null until a session starts. */
|
|
653
|
+
private _cachedAppVersion: string | null = null;
|
|
654
|
+
|
|
655
|
+
private _appVersion(): string | undefined {
|
|
656
|
+
return this._cachedAppVersion ?? undefined;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
queueError(data: {
|
|
660
|
+
type: string; message: string; stack?: string; screenName?: string;
|
|
661
|
+
platform?: string;
|
|
662
|
+
appVersion?: string;
|
|
663
|
+
isFatal?: boolean;
|
|
664
|
+
metadata?: Record<string, unknown>;
|
|
665
|
+
/** Target session. Set ONLY by a recovered native crash; absent means the current session. */
|
|
666
|
+
sessionId?: string;
|
|
667
|
+
/** Stable idempotency key. Set ONLY by a recovered crash; the backend dedupes on it. */
|
|
668
|
+
clientId?: string;
|
|
669
|
+
}): void {
|
|
670
|
+
if (this.destroyed || !this.config.clientKey) return;
|
|
671
|
+
this.pendingErrors.push({
|
|
672
|
+
...data,
|
|
673
|
+
// The session already knows the app version — never make a crash
|
|
674
|
+
// reporter's callers supply what the transport can fill itself.
|
|
675
|
+
appVersion: data.appVersion ?? this._appVersion(),
|
|
676
|
+
// A recovered crash brings its OWN clientId — the stable id written when the crash was
|
|
677
|
+
// first persisted. Generating a fresh one here would mint a new identity on every retry
|
|
678
|
+
// and defeat the unique constraint the backend dedupes with.
|
|
679
|
+
clientId: data.clientId ?? this._clientId(),
|
|
680
|
+
timestamp: new Date().toISOString(),
|
|
681
|
+
});
|
|
682
|
+
if (this.pendingErrors.length >= 10) {
|
|
683
|
+
this._flushErrors().catch(() => {});
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Public: force-flush queued errors immediately (handled-error delivery).
|
|
689
|
+
*
|
|
690
|
+
* @returns whether the batch was DURABLY accepted. Crash recovery deletes its on-disk record on
|
|
691
|
+
* this answer, so it must reflect the backend and not merely that the call returned.
|
|
692
|
+
*/
|
|
693
|
+
flushErrors(): Promise<boolean> {
|
|
694
|
+
return this._flushErrors();
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Public: flush ALL recording-lane queues immediately. Called on APP_BACKGROUND
|
|
699
|
+
* so the server-side reaper computes endedAt from the freshest data even when
|
|
700
|
+
* the OS suspends the flush timer right after backgrounding.
|
|
701
|
+
*/
|
|
702
|
+
async flushAll(): Promise<void> {
|
|
703
|
+
await Promise.all([
|
|
704
|
+
this._flushFrames(),
|
|
705
|
+
this._flushEvents(),
|
|
706
|
+
this._flushNetwork(),
|
|
707
|
+
this._flushErrors(),
|
|
708
|
+
this._flushPerformance(),
|
|
709
|
+
this._flushLogs(),
|
|
710
|
+
]);
|
|
711
|
+
// Background trigger: close native segments + drain the native uploader so a
|
|
712
|
+
// suspended JS context doesn't strand durably-stored telemetry.
|
|
713
|
+
this._triggerNativeFlush();
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
queuePerformanceMetric(data: {
|
|
717
|
+
type: string; screenName?: string; duration?: number; value?: number;
|
|
718
|
+
metadata?: Record<string, unknown>;
|
|
719
|
+
}): void {
|
|
720
|
+
if (this.destroyed || !this.config.clientKey) return;
|
|
721
|
+
this.pendingPerformanceMetrics.push({ ...data, clientId: this._clientId(), timestamp: new Date().toISOString() });
|
|
722
|
+
if (this.pendingPerformanceMetrics.length >= 20) {
|
|
723
|
+
this._flushPerformance().catch(() => {});
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Queue one log line onto the platform-agnostic logs lane. Mirrors
|
|
729
|
+
* queueNetworkRequest: drop when not in SaaS mode (no clientKey) or destroyed,
|
|
730
|
+
* batch-flush at LOGS_BATCH_SIZE. The producer supplies source/platform/level —
|
|
731
|
+
* this method makes NO assumptions about them, so a native producer reuses it as-is.
|
|
732
|
+
*/
|
|
733
|
+
queueLog(data: {
|
|
734
|
+
level: string; message: string; source: string; platform: string;
|
|
735
|
+
timestamp?: string; metadata?: Record<string, unknown>;
|
|
736
|
+
}): void {
|
|
737
|
+
if (this.destroyed || !this.config.clientKey) return;
|
|
738
|
+
this.pendingLogs.push({
|
|
739
|
+
level: data.level,
|
|
740
|
+
message: data.message,
|
|
741
|
+
source: data.source,
|
|
742
|
+
platform: data.platform,
|
|
743
|
+
timestamp: data.timestamp ?? new Date().toISOString(),
|
|
744
|
+
...(data.metadata ? { metadata: data.metadata } : {}),
|
|
745
|
+
});
|
|
746
|
+
if (this.pendingLogs.length >= BackendSessionAdapter.LOGS_BATCH_SIZE) {
|
|
747
|
+
this._flushLogs().catch(() => {});
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/** Stable client-generated idempotency id (matches journeyManager id scheme). */
|
|
752
|
+
private _clientId(): string {
|
|
753
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 10)}`;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// ─── Native outbox routing ──────────────────────────────────────────
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Hand a telemetry batch to the durable native outbox. Returns true if native
|
|
760
|
+
* accepted it (native uploader now owns delivery — caller must NOT also POST).
|
|
761
|
+
* Returns false on any miss (flag off, no session, old binary, native error) so
|
|
762
|
+
* the caller falls back to the JS HTTP path with the batch intact.
|
|
763
|
+
*/
|
|
764
|
+
private async _enqueueNative(
|
|
765
|
+
lane: 'events' | 'network' | 'errors' | 'performance' | 'logs',
|
|
766
|
+
records: Array<Record<string, unknown>>,
|
|
767
|
+
/**
|
|
768
|
+
* Session to enqueue UNDER. Defaults to the current one, which is right for every live lane.
|
|
769
|
+
*
|
|
770
|
+
* A recovered native crash must override it. Without this parameter the outbox stamped
|
|
771
|
+
* `currentSessionId` on everything, so with the outbox enabled a recovered crash was filed
|
|
772
|
+
* against the session created after the restart — the exact defect the routing above exists
|
|
773
|
+
* to prevent, reappearing through a path that routing never touched.
|
|
774
|
+
*/
|
|
775
|
+
targetSessionId?: string,
|
|
776
|
+
): Promise<boolean> {
|
|
777
|
+
const sessionId = targetSessionId || this.currentSessionId;
|
|
778
|
+
if (!this.nativeOutboxEnabled || !sessionId) return false;
|
|
779
|
+
const native = getReplaySdkNative();
|
|
780
|
+
if (!native?.enqueueOutboxRecords) return false;
|
|
781
|
+
if (!(await this._ensureNativeOutbox(native))) return false;
|
|
782
|
+
try {
|
|
783
|
+
return await native.enqueueOutboxRecords(lane, sessionId, records);
|
|
784
|
+
} catch {
|
|
785
|
+
return false;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Bootstrap the native outbox once. In SaaS mode the native module's full
|
|
791
|
+
* `initialize()` (which builds a SessionManager) is never called, so the
|
|
792
|
+
* NativeOutbox/uploader would not exist. `initOutbox` constructs only the
|
|
793
|
+
* durable outbox from clientKey/apiBaseUrl/flags. Idempotent + cached so it
|
|
794
|
+
* runs at most once; resolves false on old binaries (caller falls back to JS).
|
|
795
|
+
*/
|
|
796
|
+
private _ensureNativeOutbox(native: ReplaySdkNativeModule): Promise<boolean> {
|
|
797
|
+
if (this._nativeOutboxReady) return this._nativeOutboxReady;
|
|
798
|
+
if (!native.initOutbox) return Promise.resolve(false);
|
|
799
|
+
this._nativeOutboxReady = native
|
|
800
|
+
.initOutbox({
|
|
801
|
+
...this.config.nativeOutboxTuning,
|
|
802
|
+
clientKey: this.config.clientKey,
|
|
803
|
+
apiBaseUrl: this.config.endpoint,
|
|
804
|
+
enableNativeFileOutbox: true,
|
|
805
|
+
nativeOutboxUploadEnabled: true,
|
|
806
|
+
useObjectStorageForFrames: this.config.useObjectStorage === true,
|
|
807
|
+
})
|
|
808
|
+
.catch(() => false);
|
|
809
|
+
return this._nativeOutboxReady;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* Public readiness gate for the native frame outbox path (used by the frame
|
|
814
|
+
* capture adapter). Resolves true only when both outbox flags are on, a session
|
|
815
|
+
* exists, the native binary exposes the bridge, and `initOutbox` succeeded.
|
|
816
|
+
* Resolves false otherwise so the frame pipeline falls back to `captureScreenshot`.
|
|
817
|
+
*/
|
|
818
|
+
ensureNativeOutboxReady(): Promise<boolean> {
|
|
819
|
+
if (!this.nativeOutboxEnabled || !this.currentSessionId) return Promise.resolve(false);
|
|
820
|
+
const native = getReplaySdkNative();
|
|
821
|
+
if (!native?.captureScreenshotToFile) return Promise.resolve(false);
|
|
822
|
+
return this._ensureNativeOutbox(native);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/** Best-effort: close native segments and drain the native uploader. Never throws. */
|
|
826
|
+
private _triggerNativeFlush(): void {
|
|
827
|
+
if (!this.nativeOutboxEnabled) return;
|
|
828
|
+
try {
|
|
829
|
+
getReplaySdkNative()?.flushNativeOutbox?.().catch(() => { });
|
|
830
|
+
} catch {
|
|
831
|
+
/* old binary / unavailable — ignore */
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// ─── Lifecycle ──────────────────────────────────────────────────────
|
|
836
|
+
|
|
837
|
+
destroy(): void {
|
|
838
|
+
this.destroyed = true;
|
|
839
|
+
this._stopFlushTimer();
|
|
840
|
+
this._stopAnalyticsFlushTimer();
|
|
841
|
+
this.pendingFrames = [];
|
|
842
|
+
this.pendingEvents = [];
|
|
843
|
+
this.pendingAnalyticsEvents = [];
|
|
844
|
+
this.pendingNetworkRequests = [];
|
|
845
|
+
this.pendingErrors = [];
|
|
846
|
+
this.pendingPerformanceMetrics = [];
|
|
847
|
+
this.currentSessionId = null;
|
|
848
|
+
this._analyticsSessionId = null;
|
|
849
|
+
this._pendingFinalizeId = null;
|
|
850
|
+
this._startedSessionIds.clear();
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// ─── Internal: Flush ────────────────────────────────────────────────
|
|
854
|
+
|
|
855
|
+
/** Wire metadata for a frame — real format/sizeBytes from native (no hardcoded literals). */
|
|
856
|
+
private _frameMeta(b: { frame: ReplayFrame; imageData: string }) {
|
|
857
|
+
const f = b.frame;
|
|
858
|
+
const format = f.format ?? 'jpeg';
|
|
859
|
+
// P2-5: a JSON frame-delta carries an application content type, not an image MIME.
|
|
860
|
+
const isJsonDelta = f.frameType === 'delta' && format === 'scalebun-framedelta';
|
|
861
|
+
const contentType = isJsonDelta
|
|
862
|
+
? 'application/x-scalebun-framedelta+json'
|
|
863
|
+
: `image/${format}`;
|
|
864
|
+
return {
|
|
865
|
+
frameId: f.frameId,
|
|
866
|
+
sessionId: f.sessionId,
|
|
867
|
+
timestamp: f.ts,
|
|
868
|
+
// P2-0: real monotonic per-session sequence (was hardcoded 0 server-side).
|
|
869
|
+
sequenceNumber: f.sequenceNumber,
|
|
870
|
+
// P2-5: keyframe|delta + base reference for dashboard reconstruction.
|
|
871
|
+
frameType: f.frameType,
|
|
872
|
+
baseFrameId: f.baseFrameId,
|
|
873
|
+
screenName: f.screen ?? '',
|
|
874
|
+
trigger: f.captureReason ?? '',
|
|
875
|
+
format,
|
|
876
|
+
contentType,
|
|
877
|
+
width: f.width,
|
|
878
|
+
height: f.height,
|
|
879
|
+
sizeBytes: f.byteSize ?? 0,
|
|
880
|
+
masked: f.redactionState === 'full',
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* P2-4: build the lean (v2) wire payload for one event. Drops redundant/empty
|
|
886
|
+
* fields at the source while NEVER dropping fields the dashboard/analytics depend
|
|
887
|
+
* on (eventId, type, timestamp, sessionId). `label` is omitted when it equals
|
|
888
|
+
* `type` (the server defaults it back). `screenName` omitted when empty. `data`
|
|
889
|
+
* is pruned of null/''/undefined leaves (one level). The `v:2` marker lets the
|
|
890
|
+
* backend/dashboard pick the lean decoder; legacy (v1/no-marker) events still
|
|
891
|
+
* decode unchanged. See P2_CONTRACT.md §4.
|
|
892
|
+
*/
|
|
893
|
+
private _leanEvent(e: JourneyEvent, sessionId: string): Record<string, unknown> {
|
|
894
|
+
const out: Record<string, unknown> = {
|
|
895
|
+
v: 2,
|
|
896
|
+
eventId: e.eventId,
|
|
897
|
+
sessionId,
|
|
898
|
+
type: e.type,
|
|
899
|
+
timestamp: e.ts,
|
|
900
|
+
};
|
|
901
|
+
const screen = e.screen ?? '';
|
|
902
|
+
if (screen) out.screenName = screen;
|
|
903
|
+
const label = e.subtype ?? e.type;
|
|
904
|
+
if (label && label !== e.type) out.label = label;
|
|
905
|
+
/**
|
|
906
|
+
* THIS MAPPER ENUMERATES. Every field the wire carries has to be named here, so a field
|
|
907
|
+
* added to JourneyEvent and not added here is dropped silently — no error, no warning, and
|
|
908
|
+
* nothing downstream can tell the difference between "the SDK did not send it" and "the
|
|
909
|
+
* user never produced it". `frameId` was exactly that case: the column, the DTO field and
|
|
910
|
+
* the ingest write all existed already, and the value died on this line.
|
|
911
|
+
*
|
|
912
|
+
* Omitted when absent rather than sent as null, matching how screenName and label behave
|
|
913
|
+
* above — the v2 lean shape drops empty fields and the server reconstructs them.
|
|
914
|
+
*/
|
|
915
|
+
if (e.frameId) out.frameId = e.frameId;
|
|
916
|
+
const data = this._pruneEmpty(e.payload);
|
|
917
|
+
if (data && Object.keys(data).length > 0) out.data = data;
|
|
918
|
+
return out;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/** Shallow-prune null/undefined/'' leaves from a payload object. */
|
|
922
|
+
private _pruneEmpty(payload: unknown): Record<string, unknown> | undefined {
|
|
923
|
+
if (!payload || typeof payload !== 'object') return undefined;
|
|
924
|
+
const src = payload as Record<string, unknown>;
|
|
925
|
+
const out: Record<string, unknown> = {};
|
|
926
|
+
for (const k of Object.keys(src)) {
|
|
927
|
+
const v = src[k];
|
|
928
|
+
if (v === null || v === undefined || v === '') continue;
|
|
929
|
+
out[k] = v;
|
|
930
|
+
}
|
|
931
|
+
return out;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
private async _flushFrames(): Promise<void> {
|
|
935
|
+
if (this.pendingFrames.length === 0 || !this.currentSessionId) return;
|
|
936
|
+
// §11: hold frames until the session_start row is confirmed (else 404). Data stays
|
|
937
|
+
// buffered; the flush timer retries once the row lands.
|
|
938
|
+
if (!this._sessionRowReady()) return;
|
|
939
|
+
const sessionId = this.currentSessionId;
|
|
940
|
+
|
|
941
|
+
const batch = this.pendingFrames.splice(0, this.config.batchSize);
|
|
942
|
+
/**
|
|
943
|
+
* Chunked, because `config.batchSize` is HOST-CONFIGURABLE and the server's 100-frame cap is
|
|
944
|
+
* not. A host raising it past 100 previously turned every frame flush into a permanent 4xx —
|
|
945
|
+
* silent, total replay loss for that app, from a config value that looks like a tuning knob.
|
|
946
|
+
*
|
|
947
|
+
* A permanent rejection is reported and abandoned inside `_postFramesChunked`; what comes
|
|
948
|
+
* back is only what is still worth another attempt.
|
|
949
|
+
*/
|
|
950
|
+
const remaining = await this._postFramesChunked(sessionId, batch);
|
|
951
|
+
if (remaining.length) {
|
|
952
|
+
logger.warn(`[replay.sdk.error] backend frame upload failure`, { count: remaining.length });
|
|
953
|
+
this.pendingFrames.unshift(...remaining);
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
logger.debug(`[BackendSessionAdapter] Flushed ${batch.length} frame(s)`);
|
|
957
|
+
// Delivered — the durable snapshot (if any) is now redundant. Clear it once
|
|
958
|
+
// the in-memory buffer is fully drained so a later kill can't replay
|
|
959
|
+
// already-uploaded frames.
|
|
960
|
+
if (this.pendingFrames.length === 0) this._clearPersistedFrames();
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Report frames the SDK gave up on, on the analytics lane.
|
|
965
|
+
*
|
|
966
|
+
* SAME EVENT NAME AS THE WEB SDK (`sdk_replay_capture_failed`) with platform-specific `reason`
|
|
967
|
+
* values, so one dashboard breakdown reads both platforms without a concept-map alias — the two
|
|
968
|
+
* SDKs share no event vocabulary otherwise (`$pageview` vs `screen_viewed`), and adding a second
|
|
969
|
+
* name here would need an entry in `event-concepts.ts` for no benefit.
|
|
970
|
+
*
|
|
971
|
+
* Latched to once per session: a session whose row was never created rejects every batch, and an
|
|
972
|
+
* unlatched report would emit one event per flush for as long as the app is open.
|
|
973
|
+
*
|
|
974
|
+
* Best-effort and never throws — a diagnostic must not be able to break the capture path it
|
|
975
|
+
* describes.
|
|
976
|
+
*/
|
|
977
|
+
private _reportCaptureFailure(stage: string, err: unknown, frameCount: number): void {
|
|
978
|
+
if (this._captureFailureReported) return;
|
|
979
|
+
this._captureFailureReported = true;
|
|
980
|
+
try {
|
|
981
|
+
if (!this._analyticsSessionId) return; // no lane open — nothing to attach it to
|
|
982
|
+
const status = (err as { status?: number })?.status;
|
|
983
|
+
this.trackEvent({
|
|
984
|
+
eventId: this._clientId(),
|
|
985
|
+
sessionId: this._analyticsSessionId,
|
|
986
|
+
ts: Date.now(),
|
|
987
|
+
type: 'sdk_replay_capture_failed',
|
|
988
|
+
source: 'sdk',
|
|
989
|
+
payload: {
|
|
990
|
+
stage,
|
|
991
|
+
// Platform-specific vocabulary. The HTTP status is the honest reason on this path:
|
|
992
|
+
// RN posts to the per-lane endpoints, which surface a real status — unlike the web
|
|
993
|
+
// batch fan-out, whose 200 says nothing about what it stored.
|
|
994
|
+
reason: status ? `http_${status}` : 'upload_failed',
|
|
995
|
+
frames: frameCount,
|
|
996
|
+
platform: 'react-native',
|
|
997
|
+
},
|
|
998
|
+
} as unknown as JourneyEvent);
|
|
999
|
+
} catch {
|
|
1000
|
+
// Diagnostics must never break the capture path.
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Post frames in BACKEND-SAFE CHUNKS, and return the ones that were not durably accepted.
|
|
1006
|
+
*
|
|
1007
|
+
* WHY THIS EXISTS. `_postFrameBatch` issues exactly one request for whatever array it is handed,
|
|
1008
|
+
* and both callers could hand it more than the server's 100-frame cap — the live flush via
|
|
1009
|
+
* `config.batchSize`, and cross-kill recovery via the 2 MB persistence budget (~128 frames at the
|
|
1010
|
+
* measured 16 KB average). The result was a 4xx, classified permanent, and on the recovery path
|
|
1011
|
+
* that meant `_clearPersistedFrames()` — the ENTIRE cross-kill snapshot deleted because it was
|
|
1012
|
+
* one frame too big to send in a single request it never needed to be sent in.
|
|
1013
|
+
*
|
|
1014
|
+
* THE RETURN VALUE IS THE POINT. The caller must be able to delete exactly what landed and keep
|
|
1015
|
+
* exactly what did not, so this reports the survivors rather than throwing:
|
|
1016
|
+
* - chunk accepted → dropped from the result (it is durably stored)
|
|
1017
|
+
* - chunk PERMANENTLY refused → dropped, and reported once. Re-sending identical bytes cannot
|
|
1018
|
+
* succeed, and holding it would wedge every future launch on the
|
|
1019
|
+
* same poison chunk. Only that chunk is abandoned; the rest still
|
|
1020
|
+
* gets its chance, which is the whole difference from before.
|
|
1021
|
+
* - chunk TRANSIENTLY failed → that chunk AND every chunk after it are kept, in order. We stop
|
|
1022
|
+
* on the first transient failure rather than pressing on, because
|
|
1023
|
+
* the usual cause is the network being gone and the rest would
|
|
1024
|
+
* fail identically.
|
|
1025
|
+
*/
|
|
1026
|
+
private async _postFramesChunked(
|
|
1027
|
+
sessionId: string,
|
|
1028
|
+
items: Array<{ frame: ReplayFrame; imageData: string }>,
|
|
1029
|
+
): Promise<Array<{ frame: ReplayFrame; imageData: string }>> {
|
|
1030
|
+
const chunks = chunkEvents(items, BackendSessionAdapter.MAX_FRAMES_PER_BATCH);
|
|
1031
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
1032
|
+
try {
|
|
1033
|
+
await this._postFrameBatch(sessionId, chunks[i]);
|
|
1034
|
+
} catch (err) {
|
|
1035
|
+
if (BackendSessionAdapter._isPermanentHttpError(err)) {
|
|
1036
|
+
this._reportCaptureFailure('upload-rejected', err, chunks[i].length);
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1039
|
+
return chunks.slice(i).flat();
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
return [];
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* POST one frame batch under an EXPLICIT sessionId (object-storage path when
|
|
1047
|
+
* active, else legacy inline base64). Used by both the live flush and cross-kill
|
|
1048
|
+
* recovery — recovery passes the PRIOR session's id so orphaned frames relink to
|
|
1049
|
+
* it. Throws on transient error so the caller can re-queue; frame writes are
|
|
1050
|
+
* idempotent server-side (upsert by frameId), so a double-send is harmless.
|
|
1051
|
+
*/
|
|
1052
|
+
private async _postFrameBatch(
|
|
1053
|
+
sessionId: string,
|
|
1054
|
+
batch: Array<{ frame: ReplayFrame; imageData: string }>,
|
|
1055
|
+
): Promise<void> {
|
|
1056
|
+
if (batch.length === 0) return;
|
|
1057
|
+
logger.info(`[replay.sdk.frame] backend frame upload started`, { count: batch.length });
|
|
1058
|
+
|
|
1059
|
+
// Object-storage path: presign → PUT bytes → post key-only metadata.
|
|
1060
|
+
if (this.objectStorageActive && this.config.clientKey) {
|
|
1061
|
+
const result = await this._uploadFramesViaStorage(sessionId, batch);
|
|
1062
|
+
if (result === 'sent') {
|
|
1063
|
+
logger.info(`[replay.sdk.frame] backend frame upload success (object storage)`);
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
// 'disabled' → storage not configured server-side; fall through to inline.
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
// Legacy inline path: base64 in JSON body.
|
|
1070
|
+
const frames = batch.map(b => ({ ...this._frameMeta(b), imageData: b.imageData }));
|
|
1071
|
+
const framesEndpoint = this.config.clientKey
|
|
1072
|
+
? ENDPOINTS.INGESTION_FRAMES(sessionId)
|
|
1073
|
+
: `/replay/sessions/${sessionId}/frames`;
|
|
1074
|
+
await this._post(framesEndpoint, { frames });
|
|
1075
|
+
logger.info(`[replay.sdk.frame] backend frame upload success`);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// ─── Cross-kill frame recovery ──────────────────────────────────────
|
|
1079
|
+
//
|
|
1080
|
+
// Frames buffer in-memory (pendingFrames) and only reach the backend on flush.
|
|
1081
|
+
// A process kill (swipe-away, OOM) between captures loses the last frames the
|
|
1082
|
+
// user saw — the iOS/Android background flush may be suspended before its POST
|
|
1083
|
+
// resolves. To close that gap we snapshot the unflushed buffer to the durable
|
|
1084
|
+
// KV store on background (survives kill), then re-upload it on the NEXT launch
|
|
1085
|
+
// linked to the PRIOR session id. Best-effort and never throws.
|
|
1086
|
+
|
|
1087
|
+
/**
|
|
1088
|
+
* Snapshot the current unflushed frame buffer to durable storage so it survives
|
|
1089
|
+
* a process kill. Called on APP_BACKGROUND before the (possibly-suspended)
|
|
1090
|
+
* network flush. Synchronous mirror write — reaches disk on the native store's
|
|
1091
|
+
* next coalesced flush. No-op if recovery storage is absent or nothing pending.
|
|
1092
|
+
*/
|
|
1093
|
+
persistPendingFrames(): void {
|
|
1094
|
+
if (!this._frameStore || this.destroyed || !this.currentSessionId) return;
|
|
1095
|
+
if (this.pendingFrames.length === 0) return;
|
|
1096
|
+
try {
|
|
1097
|
+
const items = BackendSessionAdapter._selectFramesToPersist(this.pendingFrames);
|
|
1098
|
+
if (items.length === 0) return;
|
|
1099
|
+
this._frameStore.set(
|
|
1100
|
+
BackendSessionAdapter.PENDING_FRAMES_KEY,
|
|
1101
|
+
JSON.stringify({ sessionId: this.currentSessionId, items }),
|
|
1102
|
+
);
|
|
1103
|
+
} catch {
|
|
1104
|
+
// Serialization/storage failure must never break backgrounding.
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
/**
|
|
1109
|
+
* Choose which unflushed frames survive a process kill.
|
|
1110
|
+
*
|
|
1111
|
+
* WHY THIS IS NOT `slice(-10)`.
|
|
1112
|
+
*
|
|
1113
|
+
* The old rule kept the ten most RECENT frames, which is the wrong end of the buffer for replay.
|
|
1114
|
+
* A delta reconstructs against its base keyframe, so ten trailing deltas whose keyframe was
|
|
1115
|
+
* dropped are unplayable on their own — they arrive as `orphaned`, the state the dashboard flags
|
|
1116
|
+
* as a capture defect. Keeping the keyframe and fewer deltas yields a SHORTER replay; keeping the
|
|
1117
|
+
* deltas and no keyframe yields NO replay. That asymmetry is the whole decision.
|
|
1118
|
+
*
|
|
1119
|
+
* So: every keyframe is kept, then the most recent deltas fill whatever byte budget is left. This
|
|
1120
|
+
* mirrors the web SDK's `capBytes` policy (which sheds deltas first and never the keyframe), so
|
|
1121
|
+
* the two platforms lose the same thing under pressure instead of two different things.
|
|
1122
|
+
*
|
|
1123
|
+
* BYTES, not a frame count. A count is a poor proxy here: these carry base64 screenshots, so ten
|
|
1124
|
+
* frames may be 200 KB or 4 MB depending on device resolution — and this write goes to a KV store
|
|
1125
|
+
* on the background transition, where an oversized value is the thing most likely to fail and
|
|
1126
|
+
* lose the snapshot entirely. `imageData.length` is the base64 length, which is within ~1% of the
|
|
1127
|
+
* serialized cost and needs no extra pass.
|
|
1128
|
+
*/
|
|
1129
|
+
private static _selectFramesToPersist(
|
|
1130
|
+
pending: Array<{ frame: ReplayFrame; imageData: string }>,
|
|
1131
|
+
): Array<{ frame: ReplayFrame; imageData: string }> {
|
|
1132
|
+
const isKeyframe = (b: { frame: ReplayFrame }) => b.frame.frameType !== 'delta';
|
|
1133
|
+
const size = (b: { imageData: string }) => b.imageData?.length ?? 0;
|
|
1134
|
+
|
|
1135
|
+
const keep: Array<{ frame: ReplayFrame; imageData: string }> = [];
|
|
1136
|
+
let budget = BackendSessionAdapter.MAX_PERSIST_BYTES;
|
|
1137
|
+
/**
|
|
1138
|
+
* A COUNT cap as well as a byte budget.
|
|
1139
|
+
*
|
|
1140
|
+
* The byte budget is the right bound for the KV write; it is the wrong bound for the upload,
|
|
1141
|
+
* because the server checks a count. Recovery now chunks, so exceeding this is no longer
|
|
1142
|
+
* destructive — but persisting more than can ever be sent in one pass just guarantees leftover
|
|
1143
|
+
* work on every launch, and the frames past this point are the least valuable ones anyway.
|
|
1144
|
+
*/
|
|
1145
|
+
const maxCount = BackendSessionAdapter.MAX_FRAMES_PER_BATCH;
|
|
1146
|
+
|
|
1147
|
+
// Keyframes first, newest back to oldest — a later keyframe supersedes an earlier one, so if
|
|
1148
|
+
// only one fits it should be the one closest to what the user last saw.
|
|
1149
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
1150
|
+
const b = pending[i];
|
|
1151
|
+
if (!isKeyframe(b)) continue;
|
|
1152
|
+
const cost = size(b);
|
|
1153
|
+
if (cost > budget || keep.length >= maxCount) continue;
|
|
1154
|
+
budget -= cost;
|
|
1155
|
+
keep.push(b);
|
|
1156
|
+
}
|
|
1157
|
+
// Then the most recent deltas with what remains.
|
|
1158
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
1159
|
+
const b = pending[i];
|
|
1160
|
+
if (isKeyframe(b)) continue;
|
|
1161
|
+
const cost = size(b);
|
|
1162
|
+
if (cost > budget || keep.length >= maxCount) continue;
|
|
1163
|
+
budget -= cost;
|
|
1164
|
+
keep.push(b);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// Restore capture order: the backend orders frames by `sequenceNumber`, and the recovery POST
|
|
1168
|
+
// re-sends this array as-is.
|
|
1169
|
+
return keep.sort((a, b) => (a.frame.sequenceNumber ?? 0) - (b.frame.sequenceNumber ?? 0));
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/** Drop the persisted frame snapshot (after successful delivery). Never throws. */
|
|
1173
|
+
private _clearPersistedFrames(): void {
|
|
1174
|
+
if (!this._frameStore) return;
|
|
1175
|
+
try {
|
|
1176
|
+
this._frameStore.delete(BackendSessionAdapter.PENDING_FRAMES_KEY);
|
|
1177
|
+
} catch {
|
|
1178
|
+
/* non-fatal */
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* On cold launch: if a prior run left an unflushed frame snapshot, re-upload it
|
|
1184
|
+
* linked to that PRIOR session, then clear it. Runs independently of the new
|
|
1185
|
+
* session (uses the stored id + a direct POST, bypassing the row-ready gate —
|
|
1186
|
+
* the prior session row already exists server-side). Best-effort; on transient
|
|
1187
|
+
* failure the snapshot is kept for the next launch.
|
|
1188
|
+
*/
|
|
1189
|
+
async recoverPersistedFrames(): Promise<void> {
|
|
1190
|
+
if (!this._frameStore) return;
|
|
1191
|
+
let raw: string | undefined;
|
|
1192
|
+
try {
|
|
1193
|
+
raw = this._frameStore.get(BackendSessionAdapter.PENDING_FRAMES_KEY);
|
|
1194
|
+
} catch {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
if (!raw) return;
|
|
1198
|
+
|
|
1199
|
+
let parsed: { sessionId?: string; items?: Array<{ frame: ReplayFrame; imageData: string }> };
|
|
1200
|
+
try {
|
|
1201
|
+
parsed = JSON.parse(raw);
|
|
1202
|
+
} catch {
|
|
1203
|
+
// Corrupt snapshot — discard so it can't wedge every launch.
|
|
1204
|
+
this._clearPersistedFrames();
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
const sessionId = parsed.sessionId;
|
|
1209
|
+
const items = parsed.items;
|
|
1210
|
+
if (!sessionId || !Array.isArray(items) || items.length === 0) {
|
|
1211
|
+
this._clearPersistedFrames();
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
logger.info(`[replay.sdk.frame] recovering ${items.length} frame(s) for prior session ${sessionId}`);
|
|
1216
|
+
/**
|
|
1217
|
+
* DELETE ONLY WHAT WAS ACCEPTED.
|
|
1218
|
+
*
|
|
1219
|
+
* This posted every recovered frame in ONE request and, on any permanent rejection, deleted
|
|
1220
|
+
* the whole snapshot. Since the persistence budget is 2 MB of ~16 KB frames, that request was
|
|
1221
|
+
* routinely over the server's 100-frame cap — so the common outcome was a 4xx followed by the
|
|
1222
|
+
* deletion of a cross-kill recovery snapshot in which every frame was individually fine. The
|
|
1223
|
+
* one thing a recovery buffer must never do.
|
|
1224
|
+
*
|
|
1225
|
+
* Now the send is chunked and only the unaccepted remainder survives. A chunk the server will
|
|
1226
|
+
* never take is abandoned inside `_postFramesChunked` (and reported), so a single poison chunk
|
|
1227
|
+
* cannot wedge every future launch — but a transient failure keeps its frames for next time.
|
|
1228
|
+
*/
|
|
1229
|
+
const remaining = await this._postFramesChunked(sessionId, items);
|
|
1230
|
+
if (remaining.length === 0) {
|
|
1231
|
+
this._clearPersistedFrames();
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
logger.warn(`[replay.sdk.frame] prior-session frame recovery deferred`, { kept: remaining.length });
|
|
1235
|
+
try {
|
|
1236
|
+
this._frameStore.set(
|
|
1237
|
+
BackendSessionAdapter.PENDING_FRAMES_KEY,
|
|
1238
|
+
JSON.stringify({ sessionId, items: remaining }),
|
|
1239
|
+
);
|
|
1240
|
+
} catch {
|
|
1241
|
+
// Re-writing the trimmed snapshot is best-effort; the original is still on disk.
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* Upload a batch via object storage. Returns 'sent' on success, 'disabled' if
|
|
1247
|
+
* the backend reports storage is not configured (caller falls back to inline).
|
|
1248
|
+
* Throws on transient error so the caller re-queues the batch.
|
|
1249
|
+
*/
|
|
1250
|
+
private async _uploadFramesViaStorage(
|
|
1251
|
+
sessionId: string,
|
|
1252
|
+
batch: Array<{ frame: ReplayFrame; imageData: string }>,
|
|
1253
|
+
): Promise<'sent' | 'disabled'> {
|
|
1254
|
+
const presignReq = batch.map(b => {
|
|
1255
|
+
const m = this._frameMeta(b);
|
|
1256
|
+
return { frameId: m.frameId, contentType: m.contentType, format: m.format };
|
|
1257
|
+
});
|
|
1258
|
+
const resp = await this._postReturning<{ enabled: boolean; frames: Array<{ frameId: string; uploadUrl: string; storageKey: string; bucket: string; contentType: string }> }>(
|
|
1259
|
+
ENDPOINTS.INGESTION_FRAMES_PRESIGN(sessionId),
|
|
1260
|
+
{ frames: presignReq },
|
|
1261
|
+
);
|
|
1262
|
+
|
|
1263
|
+
if (!resp || resp.enabled === false) {
|
|
1264
|
+
// Latch off for the rest of the session so we don't presign every batch.
|
|
1265
|
+
this.objectStorageActive = false;
|
|
1266
|
+
return 'disabled';
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
const byFrameId = new Map(resp.frames.map(p => [p.frameId, p]));
|
|
1270
|
+
|
|
1271
|
+
// Upload bytes directly to storage (backend never sees image bytes here).
|
|
1272
|
+
await Promise.all(batch.map(async b => {
|
|
1273
|
+
const p = byFrameId.get(b.frame.frameId);
|
|
1274
|
+
if (!p) throw new Error(`No presign URL for frame ${b.frame.frameId}`);
|
|
1275
|
+
await this._putBytes(p.uploadUrl, b.imageData, p.contentType);
|
|
1276
|
+
}));
|
|
1277
|
+
|
|
1278
|
+
// Persist key-only metadata (no base64 in the body).
|
|
1279
|
+
const frames = batch.map(b => {
|
|
1280
|
+
const p = byFrameId.get(b.frame.frameId)!;
|
|
1281
|
+
return { ...this._frameMeta(b), storageKey: p.storageKey, contentType: p.contentType };
|
|
1282
|
+
});
|
|
1283
|
+
await this._post(ENDPOINTS.INGESTION_FRAMES(sessionId), { frames });
|
|
1284
|
+
return 'sent';
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
private async _flushEvents(): Promise<void> {
|
|
1288
|
+
if (this.pendingEvents.length === 0 || !this.currentSessionId) return;
|
|
1289
|
+
|
|
1290
|
+
const batch = this.pendingEvents.splice(0, 20);
|
|
1291
|
+
const events = batch.map(e => this._leanEvent(e, e.sessionId));
|
|
1292
|
+
|
|
1293
|
+
try {
|
|
1294
|
+
logger.info(`[replay.sdk.event] backend event upload started`, { count: batch.length });
|
|
1295
|
+
// Durable native outbox owns delivery when active (no duplicate JS POST).
|
|
1296
|
+
// The native enqueue is NOT gated on row-readiness: it writes to disk and its
|
|
1297
|
+
// uploader handles ordering/retry, so it must accept data even while offline.
|
|
1298
|
+
if (await this._enqueueNative('events', events)) return;
|
|
1299
|
+
// §11: JS-direct POST only after the session_start row exists; else re-buffer.
|
|
1300
|
+
if (!this._sessionRowReady()) { this.pendingEvents.unshift(...batch); return; }
|
|
1301
|
+
const eventsEndpoint = this.config.clientKey
|
|
1302
|
+
? ENDPOINTS.INGESTION_EVENTS(this.currentSessionId)
|
|
1303
|
+
: `/replay/sessions/${this.currentSessionId}/events`;
|
|
1304
|
+
await this._post(
|
|
1305
|
+
eventsEndpoint,
|
|
1306
|
+
{ events },
|
|
1307
|
+
);
|
|
1308
|
+
logger.info(`[replay.sdk.event] backend event upload success`);
|
|
1309
|
+
logger.debug(`[BackendSessionAdapter] Flushed ${batch.length} event(s)`);
|
|
1310
|
+
} catch (err) {
|
|
1311
|
+
if (BackendSessionAdapter._isPermanentHttpError(err)) return;
|
|
1312
|
+
logger.warn(`[replay.sdk.error] backend event upload failure`, { count: batch.length });
|
|
1313
|
+
this.pendingEvents.unshift(...batch);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
private async _flushNetwork(): Promise<void> {
|
|
1318
|
+
if (this.pendingNetworkRequests.length === 0 || !this.currentSessionId || !this.config.clientKey) return;
|
|
1319
|
+
const batch = this.pendingNetworkRequests.splice(0, 50);
|
|
1320
|
+
try {
|
|
1321
|
+
if (await this._enqueueNative('network', batch)) return;
|
|
1322
|
+
if (!this._sessionRowReady()) { this.pendingNetworkRequests.unshift(...batch); return; }
|
|
1323
|
+
await this._post(ENDPOINTS.INGESTION_NETWORK(this.currentSessionId), { requests: batch });
|
|
1324
|
+
} catch (err) {
|
|
1325
|
+
if (!BackendSessionAdapter._isPermanentHttpError(err)) this.pendingNetworkRequests.unshift(...batch);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
/**
|
|
1330
|
+
* D11: deliver a bug report to the SAME ingest the web SDK uses
|
|
1331
|
+
* (`POST /ingestion/sessions/:id/bug-reports`). Fire-and-forget with one
|
|
1332
|
+
* retry deferral: RN previously had NO path to this endpoint at all —
|
|
1333
|
+
* `reportBug()` emitted an analytics event no handler consumed, so the
|
|
1334
|
+
* bug-reports page was empty forever for every RN app.
|
|
1335
|
+
*/
|
|
1336
|
+
submitBugReport(report: { message: string; title?: string; email?: string }): void {
|
|
1337
|
+
if (this.destroyed || !this.config.clientKey || !this.currentSessionId) return;
|
|
1338
|
+
void this._post(
|
|
1339
|
+
`/ingestion/sessions/${this.currentSessionId}/bug-reports`,
|
|
1340
|
+
{ ...report, timestamp: Date.now() },
|
|
1341
|
+
).catch(() => {
|
|
1342
|
+
/* best-effort; the $bug_report analytics breadcrumb still records intent */
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
/**
|
|
1347
|
+
* @returns TRUE only when every group in this batch was DURABLY accepted — an HTTP 2xx, or a
|
|
1348
|
+
* handoff to the native outbox, which is itself a persistent retrying queue.
|
|
1349
|
+
*
|
|
1350
|
+
* The return value is not cosmetic: `drainNativeCrash` deletes the on-disk crash record on the
|
|
1351
|
+
* strength of it. This method used to return `void` and swallow its own errors in the catch
|
|
1352
|
+
* below, so "the promise resolved" meant nothing at all — a failed POST looked exactly like a
|
|
1353
|
+
* successful one, and the caller would have deleted the only durable copy of a crash that never
|
|
1354
|
+
* arrived. Anything less than a real acknowledgement here reintroduces the loss this whole
|
|
1355
|
+
* change exists to prevent.
|
|
1356
|
+
*/
|
|
1357
|
+
private async _flushErrors(): Promise<boolean> {
|
|
1358
|
+
if (this.pendingErrors.length === 0 || !this.currentSessionId || !this.config.clientKey) return false;
|
|
1359
|
+
const batch = this.pendingErrors.splice(0, 20);
|
|
1360
|
+
try {
|
|
1361
|
+
if (!this._sessionRowReady()) { this.pendingErrors.unshift(...batch); return false; }
|
|
1362
|
+
/**
|
|
1363
|
+
* ROUTED BY THE ERROR'S OWN SESSION, not by whichever session is current.
|
|
1364
|
+
*
|
|
1365
|
+
* A recovered native crash carries the id of the session it actually happened in — that
|
|
1366
|
+
* process is gone, so the current session is the wrong owner. Sending it under
|
|
1367
|
+
* `currentSessionId` is what marked a healthy session crashed and left the crashed one
|
|
1368
|
+
* looking clean.
|
|
1369
|
+
*
|
|
1370
|
+
* The URL still carries a session because that is the established ingest shape; the
|
|
1371
|
+
* error's own `sessionId` simply chooses WHICH one. Errors are grouped by their target
|
|
1372
|
+
* so a batch mixing a recovered crash with live errors cannot drag the live ones onto
|
|
1373
|
+
* the dead session.
|
|
1374
|
+
*/
|
|
1375
|
+
const byTarget = new Map<string, typeof batch>();
|
|
1376
|
+
for (const e of batch) {
|
|
1377
|
+
const target = (e as { sessionId?: string }).sessionId || this.currentSessionId;
|
|
1378
|
+
byTarget.set(target, [...(byTarget.get(target) ?? []), e]);
|
|
1379
|
+
}
|
|
1380
|
+
let allAccepted = true;
|
|
1381
|
+
for (const [target, errors] of byTarget) {
|
|
1382
|
+
// `sessionId` is a routing instruction, not payload — strip it so the stored row is
|
|
1383
|
+
// byte-identical to one sent the ordinary way.
|
|
1384
|
+
const cleaned = errors.map(({ sessionId: _s, ...rest }: any) => rest);
|
|
1385
|
+
|
|
1386
|
+
// The outbox is enqueued PER TARGET, so a recovered crash keeps its own session.
|
|
1387
|
+
if (await this._enqueueNative('errors', cleaned, target)) continue;
|
|
1388
|
+
|
|
1389
|
+
try {
|
|
1390
|
+
await this._post(ENDPOINTS.INGESTION_ERRORS(target), { errors: cleaned });
|
|
1391
|
+
} catch (err) {
|
|
1392
|
+
allAccepted = false;
|
|
1393
|
+
// A permanent error (4xx) will never succeed, so re-queuing it would spin
|
|
1394
|
+
// forever; anything else is worth another attempt.
|
|
1395
|
+
if (!BackendSessionAdapter._isPermanentHttpError(err)) {
|
|
1396
|
+
this.pendingErrors.unshift(...errors);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
return allAccepted;
|
|
1401
|
+
} catch (err) {
|
|
1402
|
+
if (!BackendSessionAdapter._isPermanentHttpError(err)) this.pendingErrors.unshift(...batch);
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
private async _flushPerformance(): Promise<void> {
|
|
1408
|
+
if (this.pendingPerformanceMetrics.length === 0 || !this.currentSessionId || !this.config.clientKey) return;
|
|
1409
|
+
const batch = this.pendingPerformanceMetrics.splice(0, 50);
|
|
1410
|
+
try {
|
|
1411
|
+
if (await this._enqueueNative('performance', batch)) return;
|
|
1412
|
+
if (!this._sessionRowReady()) { this.pendingPerformanceMetrics.unshift(...batch); return; }
|
|
1413
|
+
await this._post(ENDPOINTS.INGESTION_PERFORMANCE(this.currentSessionId), { metrics: batch });
|
|
1414
|
+
} catch (err) {
|
|
1415
|
+
if (!BackendSessionAdapter._isPermanentHttpError(err)) this.pendingPerformanceMetrics.unshift(...batch);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
private async _flushLogs(): Promise<void> {
|
|
1420
|
+
if (this.pendingLogs.length === 0 || !this.currentSessionId || !this.config.clientKey) return;
|
|
1421
|
+
const batch = this.pendingLogs.splice(0, BackendSessionAdapter.LOGS_FLUSH_MAX);
|
|
1422
|
+
try {
|
|
1423
|
+
if (await this._enqueueNative('logs', batch as unknown as Array<Record<string, unknown>>)) return;
|
|
1424
|
+
if (!this._sessionRowReady()) { this.pendingLogs.unshift(...batch); return; }
|
|
1425
|
+
await this._post(ENDPOINTS.INGESTION_LOGS(this.currentSessionId), { logs: batch });
|
|
1426
|
+
} catch (err) {
|
|
1427
|
+
if (!BackendSessionAdapter._isPermanentHttpError(err)) this.pendingLogs.unshift(...batch);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
// ─── Internal: Timer ────────────────────────────────────────────────
|
|
1432
|
+
|
|
1433
|
+
private _startFlushTimer(): void {
|
|
1434
|
+
this._stopFlushTimer();
|
|
1435
|
+
this.flushTimer = setInterval(() => {
|
|
1436
|
+
this._flushFrames().catch(() => { });
|
|
1437
|
+
this._flushEvents().catch(() => { });
|
|
1438
|
+
this._flushNetwork().catch(() => { });
|
|
1439
|
+
this._flushErrors().catch(() => { });
|
|
1440
|
+
this._flushPerformance().catch(() => { });
|
|
1441
|
+
this._flushLogs().catch(() => { });
|
|
1442
|
+
this._triggerNativeFlush();
|
|
1443
|
+
}, this.config.flushIntervalMs);
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
private _stopFlushTimer(): void {
|
|
1447
|
+
if (this.flushTimer) {
|
|
1448
|
+
clearInterval(this.flushTimer);
|
|
1449
|
+
this.flushTimer = null;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
// ─── Internal: HTTP ─────────────────────────────────────────────────
|
|
1454
|
+
|
|
1455
|
+
// A 4xx (except 408 Request Timeout / 429 Too Many Requests) is permanent:
|
|
1456
|
+
// the same payload will never succeed, so requeuing it retries forever and
|
|
1457
|
+
// floods the logs (e.g. a rejected clientKey → HTTP 403 on every flush tick).
|
|
1458
|
+
// Drop the batch on these; keep retrying 5xx / timeouts / network errors.
|
|
1459
|
+
private static _isPermanentHttpError(err: unknown): boolean {
|
|
1460
|
+
const status = (err as { status?: number })?.status;
|
|
1461
|
+
return typeof status === 'number' && status >= 400 && status < 500 && status !== 408 && status !== 429;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
private async _post(path: string, body: unknown): Promise<void> {
|
|
1465
|
+
const url = `${this.config.endpoint}${path}`;
|
|
1466
|
+
|
|
1467
|
+
try {
|
|
1468
|
+
const controller = new AbortController();
|
|
1469
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
1470
|
+
|
|
1471
|
+
try {
|
|
1472
|
+
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
|
1473
|
+
if (this.config.clientKey) {
|
|
1474
|
+
headers['x-scalebun-client-key'] = this.config.clientKey;
|
|
1475
|
+
}
|
|
1476
|
+
const response = await fetch(url, {
|
|
1477
|
+
method: 'POST',
|
|
1478
|
+
headers,
|
|
1479
|
+
body: JSON.stringify(body),
|
|
1480
|
+
signal: controller.signal,
|
|
1481
|
+
});
|
|
1482
|
+
|
|
1483
|
+
if (!response.ok) {
|
|
1484
|
+
logger.warn(`[BackendSessionAdapter] HTTP ${response.status} from ${path}`);
|
|
1485
|
+
const httpErr = new Error(`HTTP ${response.status}`) as Error & { status?: number };
|
|
1486
|
+
httpErr.status = response.status;
|
|
1487
|
+
throw httpErr;
|
|
1488
|
+
}
|
|
1489
|
+
} finally {
|
|
1490
|
+
clearTimeout(timeout);
|
|
1491
|
+
}
|
|
1492
|
+
} catch (err: any) {
|
|
1493
|
+
if (err?.name === 'AbortError') {
|
|
1494
|
+
logger.warn(`[BackendSessionAdapter] Timeout on ${path}`);
|
|
1495
|
+
} else {
|
|
1496
|
+
logger.warn(`[BackendSessionAdapter] Failed ${path}: ${err?.message}`);
|
|
1497
|
+
}
|
|
1498
|
+
throw err;
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
/**
|
|
1503
|
+
* POST that parses and returns the JSON response body. Mirrors _post's headers
|
|
1504
|
+
* and timeout handling; used by the object-storage presign request, which needs
|
|
1505
|
+
* the returned upload URLs (the void _post discards the body).
|
|
1506
|
+
*/
|
|
1507
|
+
private async _postReturning<T>(path: string, body: unknown): Promise<T> {
|
|
1508
|
+
const url = `${this.config.endpoint}${path}`;
|
|
1509
|
+
|
|
1510
|
+
const controller = new AbortController();
|
|
1511
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
1512
|
+
try {
|
|
1513
|
+
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
|
1514
|
+
if (this.config.clientKey) {
|
|
1515
|
+
headers['x-scalebun-client-key'] = this.config.clientKey;
|
|
1516
|
+
}
|
|
1517
|
+
const response = await fetch(url, {
|
|
1518
|
+
method: 'POST',
|
|
1519
|
+
headers,
|
|
1520
|
+
body: JSON.stringify(body),
|
|
1521
|
+
signal: controller.signal,
|
|
1522
|
+
});
|
|
1523
|
+
if (!response.ok) {
|
|
1524
|
+
logger.warn(`[BackendSessionAdapter] HTTP ${response.status} from ${path}`);
|
|
1525
|
+
const httpErr = new Error(`HTTP ${response.status}`) as Error & { status?: number };
|
|
1526
|
+
httpErr.status = response.status;
|
|
1527
|
+
throw httpErr;
|
|
1528
|
+
}
|
|
1529
|
+
return (await response.json()) as T;
|
|
1530
|
+
} finally {
|
|
1531
|
+
clearTimeout(timeout);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* PUT raw image bytes directly to a presigned storage URL. Decodes the base64
|
|
1537
|
+
* frame payload to a binary Blob so the wire body is bytes, not a base64 string.
|
|
1538
|
+
* No client key header — the presigned URL carries its own auth.
|
|
1539
|
+
*/
|
|
1540
|
+
private async _putBytes(uploadUrl: string, base64: string, contentType: string): Promise<void> {
|
|
1541
|
+
// RN-safe base64→binary: decode to a Uint8Array and send that as the body.
|
|
1542
|
+
// The `fetch('data:…').blob()` round-trip fails under the new architecture
|
|
1543
|
+
// ("Network request failed"); RN's XHR sends a typed array as real binary.
|
|
1544
|
+
const bytes = base64ToBytes(this._stripDataUri(base64));
|
|
1545
|
+
|
|
1546
|
+
const controller = new AbortController();
|
|
1547
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
1548
|
+
try {
|
|
1549
|
+
const response = await fetch(uploadUrl, {
|
|
1550
|
+
method: 'PUT',
|
|
1551
|
+
headers: { 'Content-Type': contentType },
|
|
1552
|
+
body: bytes,
|
|
1553
|
+
signal: controller.signal,
|
|
1554
|
+
});
|
|
1555
|
+
if (!response.ok) {
|
|
1556
|
+
throw new Error(`HTTP ${response.status}`);
|
|
1557
|
+
}
|
|
1558
|
+
} finally {
|
|
1559
|
+
clearTimeout(timeout);
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/** Strip a leading `data:<mime>;base64,` prefix if the native layer included one. */
|
|
1564
|
+
private _stripDataUri(s: string): string {
|
|
1565
|
+
const comma = s.indexOf(',');
|
|
1566
|
+
return s.startsWith('data:') && comma !== -1 ? s.slice(comma + 1) : s;
|
|
1567
|
+
}
|
|
1568
|
+
}
|