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