@scalebun/react-native 1.1.0 → 1.2.1
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/dist/scalebun.full.js +33218 -0
- package/dist/scalebun.full.js.map +1 -0
- package/dist/scalebun.slim.js +30016 -0
- package/dist/scalebun.slim.js.map +1 -0
- package/lib/commonjs/bootstrap/FeatureRegistry.js +4 -4
- package/lib/commonjs/bootstrap/FeatureRegistry.js.map +1 -1
- package/lib/commonjs/bootstrap/SDKBootstrapper.js +8 -8
- package/lib/commonjs/bootstrap/SDKBootstrapper.js.map +1 -1
- package/lib/commonjs/core/config/schema.js +412 -232
- package/lib/commonjs/core/config/schema.js.map +1 -1
- package/lib/commonjs/core/constants/protocol.js +31 -0
- package/lib/commonjs/core/constants/protocol.js.map +1 -0
- package/lib/commonjs/core/constants/timings.js +4 -1
- package/lib/commonjs/core/constants/timings.js.map +1 -1
- package/lib/commonjs/core/lifecycle/appLifecycle.js +1 -1
- package/lib/commonjs/core/lifecycle/appLifecycle.js.map +1 -1
- package/lib/commonjs/debug/bootstrap.js +30 -10
- package/lib/commonjs/debug/bootstrap.js.map +1 -1
- package/lib/commonjs/debug/exportBridge.js +5 -3
- package/lib/commonjs/debug/exportBridge.js.map +1 -1
- package/lib/commonjs/debug/hostResolver.js +2 -2
- package/lib/commonjs/debug/hostResolver.js.map +1 -1
- package/lib/commonjs/debug/perfWiring.js +4 -4
- package/lib/commonjs/debug/perfWiring.js.map +1 -1
- package/lib/commonjs/debug/replayWiring.js +5 -5
- package/lib/commonjs/debug/replayWiring.js.map +1 -1
- package/lib/commonjs/debug/screenTracking.js +2 -2
- package/lib/commonjs/debug/screenTracking.js.map +1 -1
- package/lib/commonjs/debug/sessionWiring.js +2 -2
- package/lib/commonjs/debug/sessionWiring.js.map +1 -1
- package/lib/commonjs/features/crash/NativeCrashFeature.js +1 -1
- package/lib/commonjs/features/crash/NativeCrashFeature.js.map +1 -1
- package/lib/commonjs/features/crash/globalHandler.js +3 -3
- package/lib/commonjs/features/crash/globalHandler.js.map +1 -1
- package/lib/commonjs/features/crash/nativeCrashBridge.js +7 -7
- package/lib/commonjs/features/crash/nativeCrashBridge.js.map +1 -1
- package/lib/commonjs/features/crash/rejectionHandler.js +2 -2
- package/lib/commonjs/features/crash/rejectionHandler.js.map +1 -1
- package/lib/commonjs/features/engage/EngageArchetypeRenderers.js +0 -9
- package/lib/commonjs/features/engage/EngageArchetypeRenderers.js.map +1 -1
- package/lib/commonjs/features/engage/EngageInAppView.js +1 -1
- package/lib/commonjs/features/engage/EngageInAppView.js.map +1 -1
- package/lib/commonjs/features/engage/EngagePromptProvider.js +17 -17
- package/lib/commonjs/features/engage/EngagePromptProvider.js.map +1 -1
- package/lib/commonjs/features/engage/EngageTransport.js +5 -5
- package/lib/commonjs/features/engage/EngageTransport.js.map +1 -1
- package/lib/commonjs/features/engage/engagePushTokenBridge.js +4 -4
- package/lib/commonjs/features/engage/engagePushTokenBridge.js.map +1 -1
- package/lib/commonjs/features/engage/engageShakeBridge.js +2 -2
- package/lib/commonjs/features/engage/engageShakeBridge.js.map +1 -1
- package/lib/commonjs/features/engage/engageSignals.js +1 -1
- package/lib/commonjs/features/engage/engageSignals.js.map +1 -1
- package/lib/commonjs/features/engage/engageStoreReviewBridge.js +2 -2
- package/lib/commonjs/features/engage/engageStoreReviewBridge.js.map +1 -1
- package/lib/commonjs/features/engage/engageTestSeenStore.js +1 -1
- package/lib/commonjs/features/engage/engageTestSeenStore.js.map +1 -1
- package/lib/commonjs/features/engage/engageThrottle.js +4 -4
- package/lib/commonjs/features/engage/engageThrottle.js.map +1 -1
- package/lib/commonjs/features/engage/engageTriggerEngine.js +4 -4
- package/lib/commonjs/features/engage/engageTriggerEngine.js.map +1 -1
- package/lib/commonjs/features/engage/engageWindowInsets.js +1 -1
- package/lib/commonjs/features/engage/engageWindowInsets.js.map +1 -1
- package/lib/commonjs/features/install-referrer/installReferrer.js +3 -3
- package/lib/commonjs/features/install-referrer/installReferrer.js.map +1 -1
- package/lib/commonjs/features/journey/calibrationContext.js +0 -9
- package/lib/commonjs/features/journey/calibrationContext.js.map +1 -1
- package/lib/commonjs/features/journey/journeyManager.js +4 -1
- package/lib/commonjs/features/journey/journeyManager.js.map +1 -1
- package/lib/commonjs/features/navigation/AutoScreenDetector.js +4 -4
- package/lib/commonjs/features/navigation/AutoScreenDetector.js.map +1 -1
- package/lib/commonjs/features/ota/OtaOrchestrator.js +18 -18
- package/lib/commonjs/features/ota/OtaOrchestrator.js.map +1 -1
- package/lib/commonjs/features/ota/geoCountry.js +2 -2
- package/lib/commonjs/features/ota/geoCountry.js.map +1 -1
- package/lib/commonjs/features/ota/retry.js +2 -2
- package/lib/commonjs/features/ota/retry.js.map +1 -1
- package/lib/commonjs/features/performance/PerformanceFeature.js +121 -23
- package/lib/commonjs/features/performance/PerformanceFeature.js.map +1 -1
- package/lib/commonjs/features/replay/core/logger/logger.js +0 -4
- package/lib/commonjs/features/replay/core/logger/logger.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/network/networkAdapter.js +1 -54
- package/lib/commonjs/features/replay/integrations/network/networkAdapter.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js +1 -1
- package/lib/commonjs/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
- package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js +1 -1
- package/lib/commonjs/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
- package/lib/commonjs/features/replay/pipeline/batching/batchManager.js +1 -1
- package/lib/commonjs/features/replay/pipeline/batching/batchManager.js.map +1 -1
- package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js +1 -1
- package/lib/commonjs/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
- package/lib/commonjs/features/replay/public/api.js +7 -7
- package/lib/commonjs/features/replay/public/api.js.map +1 -1
- package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js +9 -9
- package/lib/commonjs/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
- package/lib/commonjs/features/session/BackendSessionAdapter.js +41 -41
- package/lib/commonjs/features/session/BackendSessionAdapter.js.map +1 -1
- package/lib/commonjs/features/session/DesktopSessionTransport.js +5 -2
- package/lib/commonjs/features/session/DesktopSessionTransport.js.map +1 -1
- package/lib/commonjs/features/session/JourneyEventPipeline.js +1 -1
- package/lib/commonjs/features/session/JourneyEventPipeline.js.map +1 -1
- package/lib/commonjs/features/session/ReplayCaptureManager.js +14 -14
- package/lib/commonjs/features/session/ReplayCaptureManager.js.map +1 -1
- package/lib/commonjs/features/session/SessionManager.js +9 -9
- package/lib/commonjs/features/session/SessionManager.js.map +1 -1
- package/lib/commonjs/features/session/SyncDecisionEngine.js +1 -1
- package/lib/commonjs/features/session/SyncDecisionEngine.js.map +1 -1
- package/lib/commonjs/features/skan/skanBridge.js +6 -15
- package/lib/commonjs/features/skan/skanBridge.js.map +1 -1
- package/lib/commonjs/features/skan/skanConversionManager.js +5 -5
- package/lib/commonjs/features/skan/skanConversionManager.js.map +1 -1
- package/lib/commonjs/integrations/fetch/fetchInterceptor.js +1 -1
- package/lib/commonjs/integrations/fetch/fetchInterceptor.js.map +1 -1
- package/lib/commonjs/integrations/xhr/xhrInterceptor.js +1 -1
- package/lib/commonjs/integrations/xhr/xhrInterceptor.js.map +1 -1
- package/lib/commonjs/metro/composeSourceMap.js +105 -0
- package/lib/commonjs/metro/composeSourceMap.js.map +1 -0
- package/lib/commonjs/metro/featureModules.js +131 -0
- package/lib/commonjs/metro/featureModules.js.map +1 -0
- package/lib/commonjs/metro/index.js +123 -2
- package/lib/commonjs/metro/index.js.map +1 -1
- package/lib/commonjs/metro/serializerCompose.js +129 -0
- package/lib/commonjs/metro/serializerCompose.js.map +1 -0
- package/lib/commonjs/pipeline/dispatcher/dispatcher.js +1 -1
- package/lib/commonjs/pipeline/dispatcher/dispatcher.js.map +1 -1
- package/lib/commonjs/pipeline/queue/flushQueue.js +2 -2
- package/lib/commonjs/pipeline/queue/flushQueue.js.map +1 -1
- package/lib/commonjs/pipeline/queue/persistentQueue.js +6 -37
- package/lib/commonjs/pipeline/queue/persistentQueue.js.map +1 -1
- package/lib/commonjs/pipeline/scheduler/flushScheduler.js +1 -1
- package/lib/commonjs/pipeline/scheduler/flushScheduler.js.map +1 -1
- package/lib/commonjs/public/ScaleBunFacade.js +15 -15
- package/lib/commonjs/public/ScaleBunFacade.js.map +1 -1
- package/lib/commonjs/push/PushManager.js +3 -3
- package/lib/commonjs/push/PushManager.js.map +1 -1
- package/lib/commonjs/push/adapters/NativeBridgeAdapter.js +1 -1
- package/lib/commonjs/push/adapters/NativeBridgeAdapter.js.map +1 -1
- package/lib/commonjs/push/native/nativeNotifications.js +7 -18
- package/lib/commonjs/push/native/nativeNotifications.js.map +1 -1
- package/lib/commonjs/storage/StorageBackend.js +1 -1
- package/lib/commonjs/storage/StorageBackend.js.map +1 -1
- package/lib/module/bootstrap/FeatureRegistry.js +4 -4
- package/lib/module/bootstrap/FeatureRegistry.js.map +1 -1
- package/lib/module/bootstrap/SDKBootstrapper.js +8 -8
- package/lib/module/bootstrap/SDKBootstrapper.js.map +1 -1
- package/lib/module/core/config/schema.js +411 -231
- package/lib/module/core/config/schema.js.map +1 -1
- package/lib/module/core/constants/protocol.js +25 -0
- package/lib/module/core/constants/protocol.js.map +1 -0
- package/lib/module/core/constants/timings.js +3 -1
- package/lib/module/core/constants/timings.js.map +1 -1
- package/lib/module/core/lifecycle/appLifecycle.js +1 -1
- package/lib/module/core/lifecycle/appLifecycle.js.map +1 -1
- package/lib/module/debug/bootstrap.js +30 -9
- package/lib/module/debug/bootstrap.js.map +1 -1
- package/lib/module/debug/exportBridge.js +5 -3
- package/lib/module/debug/exportBridge.js.map +1 -1
- package/lib/module/debug/hostResolver.js +2 -2
- package/lib/module/debug/hostResolver.js.map +1 -1
- package/lib/module/debug/perfWiring.js +4 -4
- package/lib/module/debug/perfWiring.js.map +1 -1
- package/lib/module/debug/replayWiring.js +5 -5
- package/lib/module/debug/replayWiring.js.map +1 -1
- package/lib/module/debug/screenTracking.js +2 -2
- package/lib/module/debug/screenTracking.js.map +1 -1
- package/lib/module/debug/sessionWiring.js +2 -2
- package/lib/module/debug/sessionWiring.js.map +1 -1
- package/lib/module/features/crash/NativeCrashFeature.js +1 -1
- package/lib/module/features/crash/NativeCrashFeature.js.map +1 -1
- package/lib/module/features/crash/globalHandler.js +3 -3
- package/lib/module/features/crash/globalHandler.js.map +1 -1
- package/lib/module/features/crash/nativeCrashBridge.js +7 -7
- package/lib/module/features/crash/nativeCrashBridge.js.map +1 -1
- package/lib/module/features/crash/rejectionHandler.js +2 -2
- package/lib/module/features/crash/rejectionHandler.js.map +1 -1
- package/lib/module/features/engage/EngageArchetypeRenderers.js +0 -8
- package/lib/module/features/engage/EngageArchetypeRenderers.js.map +1 -1
- package/lib/module/features/engage/EngageInAppView.js +1 -1
- package/lib/module/features/engage/EngageInAppView.js.map +1 -1
- package/lib/module/features/engage/EngagePromptProvider.js +17 -17
- package/lib/module/features/engage/EngagePromptProvider.js.map +1 -1
- package/lib/module/features/engage/EngageTransport.js +5 -5
- package/lib/module/features/engage/EngageTransport.js.map +1 -1
- package/lib/module/features/engage/engagePushTokenBridge.js +4 -4
- package/lib/module/features/engage/engagePushTokenBridge.js.map +1 -1
- package/lib/module/features/engage/engageShakeBridge.js +2 -2
- package/lib/module/features/engage/engageShakeBridge.js.map +1 -1
- package/lib/module/features/engage/engageSignals.js +1 -1
- package/lib/module/features/engage/engageSignals.js.map +1 -1
- package/lib/module/features/engage/engageStoreReviewBridge.js +2 -2
- package/lib/module/features/engage/engageStoreReviewBridge.js.map +1 -1
- package/lib/module/features/engage/engageTestSeenStore.js +1 -1
- package/lib/module/features/engage/engageTestSeenStore.js.map +1 -1
- package/lib/module/features/engage/engageThrottle.js +4 -4
- package/lib/module/features/engage/engageThrottle.js.map +1 -1
- package/lib/module/features/engage/engageTriggerEngine.js +4 -4
- package/lib/module/features/engage/engageTriggerEngine.js.map +1 -1
- package/lib/module/features/engage/engageWindowInsets.js +1 -1
- package/lib/module/features/engage/engageWindowInsets.js.map +1 -1
- package/lib/module/features/install-referrer/installReferrer.js +3 -3
- package/lib/module/features/install-referrer/installReferrer.js.map +1 -1
- package/lib/module/features/journey/calibrationContext.js +0 -8
- package/lib/module/features/journey/calibrationContext.js.map +1 -1
- package/lib/module/features/journey/journeyManager.js +3 -1
- package/lib/module/features/journey/journeyManager.js.map +1 -1
- package/lib/module/features/navigation/AutoScreenDetector.js +4 -4
- package/lib/module/features/navigation/AutoScreenDetector.js.map +1 -1
- package/lib/module/features/ota/OtaOrchestrator.js +18 -18
- package/lib/module/features/ota/OtaOrchestrator.js.map +1 -1
- package/lib/module/features/ota/geoCountry.js +2 -2
- package/lib/module/features/ota/geoCountry.js.map +1 -1
- package/lib/module/features/ota/retry.js +2 -2
- package/lib/module/features/ota/retry.js.map +1 -1
- package/lib/module/features/performance/PerformanceFeature.js +122 -23
- package/lib/module/features/performance/PerformanceFeature.js.map +1 -1
- package/lib/module/features/replay/core/logger/logger.js +0 -3
- package/lib/module/features/replay/core/logger/logger.js.map +1 -1
- package/lib/module/features/replay/integrations/network/networkAdapter.js +1 -52
- package/lib/module/features/replay/integrations/network/networkAdapter.js.map +1 -1
- package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js +1 -1
- package/lib/module/features/replay/integrations/react-navigation/navigationIntegration.js.map +1 -1
- package/lib/module/features/replay/integrations/touch/ReplayRoot.js +1 -1
- package/lib/module/features/replay/integrations/touch/ReplayRoot.js.map +1 -1
- package/lib/module/features/replay/pipeline/batching/batchManager.js +1 -1
- package/lib/module/features/replay/pipeline/batching/batchManager.js.map +1 -1
- package/lib/module/features/replay/pipeline/retry/retryPolicy.js +1 -1
- package/lib/module/features/replay/pipeline/retry/retryPolicy.js.map +1 -1
- package/lib/module/features/replay/public/api.js +7 -7
- package/lib/module/features/replay/public/api.js.map +1 -1
- package/lib/module/features/replay/replay/session/sessionOrchestrator.js +9 -9
- package/lib/module/features/replay/replay/session/sessionOrchestrator.js.map +1 -1
- package/lib/module/features/session/BackendSessionAdapter.js +41 -41
- package/lib/module/features/session/BackendSessionAdapter.js.map +1 -1
- package/lib/module/features/session/DesktopSessionTransport.js +4 -2
- package/lib/module/features/session/DesktopSessionTransport.js.map +1 -1
- package/lib/module/features/session/JourneyEventPipeline.js +1 -1
- package/lib/module/features/session/JourneyEventPipeline.js.map +1 -1
- package/lib/module/features/session/ReplayCaptureManager.js +14 -14
- package/lib/module/features/session/ReplayCaptureManager.js.map +1 -1
- package/lib/module/features/session/SessionManager.js +9 -9
- package/lib/module/features/session/SessionManager.js.map +1 -1
- package/lib/module/features/session/SyncDecisionEngine.js +1 -1
- package/lib/module/features/session/SyncDecisionEngine.js.map +1 -1
- package/lib/module/features/skan/skanBridge.js +6 -14
- package/lib/module/features/skan/skanBridge.js.map +1 -1
- package/lib/module/features/skan/skanConversionManager.js +5 -5
- package/lib/module/features/skan/skanConversionManager.js.map +1 -1
- package/lib/module/integrations/fetch/fetchInterceptor.js +1 -1
- package/lib/module/integrations/fetch/fetchInterceptor.js.map +1 -1
- package/lib/module/integrations/xhr/xhrInterceptor.js +1 -1
- package/lib/module/integrations/xhr/xhrInterceptor.js.map +1 -1
- package/lib/module/metro/composeSourceMap.js +97 -0
- package/lib/module/metro/composeSourceMap.js.map +1 -0
- package/lib/module/metro/featureModules.js +123 -0
- package/lib/module/metro/featureModules.js.map +1 -0
- package/lib/module/metro/index.js +122 -2
- package/lib/module/metro/index.js.map +1 -1
- package/lib/module/metro/serializerCompose.js +120 -0
- package/lib/module/metro/serializerCompose.js.map +1 -0
- package/lib/module/pipeline/dispatcher/dispatcher.js +1 -1
- package/lib/module/pipeline/dispatcher/dispatcher.js.map +1 -1
- package/lib/module/pipeline/queue/flushQueue.js +2 -2
- package/lib/module/pipeline/queue/flushQueue.js.map +1 -1
- package/lib/module/pipeline/queue/persistentQueue.js +6 -36
- package/lib/module/pipeline/queue/persistentQueue.js.map +1 -1
- package/lib/module/pipeline/scheduler/flushScheduler.js +1 -1
- package/lib/module/pipeline/scheduler/flushScheduler.js.map +1 -1
- package/lib/module/public/ScaleBunFacade.js +15 -15
- package/lib/module/public/ScaleBunFacade.js.map +1 -1
- package/lib/module/push/PushManager.js +3 -3
- package/lib/module/push/PushManager.js.map +1 -1
- package/lib/module/push/adapters/NativeBridgeAdapter.js +1 -1
- package/lib/module/push/adapters/NativeBridgeAdapter.js.map +1 -1
- package/lib/module/push/native/nativeNotifications.js +7 -17
- package/lib/module/push/native/nativeNotifications.js.map +1 -1
- package/lib/module/storage/StorageBackend.js +1 -1
- package/lib/module/storage/StorageBackend.js.map +1 -1
- package/lib/typescript/core/config/schema.d.ts +61 -40
- package/lib/typescript/core/config/schema.d.ts.map +1 -1
- package/lib/typescript/core/constants/protocol.d.ts +23 -0
- package/lib/typescript/core/constants/protocol.d.ts.map +1 -0
- package/lib/typescript/core/constants/timings.d.ts +1 -1
- package/lib/typescript/core/constants/timings.d.ts.map +1 -1
- package/lib/typescript/debug/bootstrap.d.ts +0 -1
- package/lib/typescript/debug/bootstrap.d.ts.map +1 -1
- package/lib/typescript/debug/exportBridge.d.ts.map +1 -1
- package/lib/typescript/features/engage/EngageArchetypeRenderers.d.ts +0 -2
- package/lib/typescript/features/engage/EngageArchetypeRenderers.d.ts.map +1 -1
- package/lib/typescript/features/journey/calibrationContext.d.ts +0 -1
- package/lib/typescript/features/journey/calibrationContext.d.ts.map +1 -1
- package/lib/typescript/features/journey/journeyManager.d.ts.map +1 -1
- package/lib/typescript/features/performance/PerformanceFeature.d.ts +31 -0
- package/lib/typescript/features/performance/PerformanceFeature.d.ts.map +1 -1
- package/lib/typescript/features/replay/core/logger/logger.d.ts +0 -1
- package/lib/typescript/features/replay/core/logger/logger.d.ts.map +1 -1
- package/lib/typescript/features/replay/integrations/network/networkAdapter.d.ts +0 -10
- package/lib/typescript/features/replay/integrations/network/networkAdapter.d.ts.map +1 -1
- package/lib/typescript/features/session/DesktopSessionTransport.d.ts.map +1 -1
- package/lib/typescript/features/skan/skanBridge.d.ts +0 -2
- package/lib/typescript/features/skan/skanBridge.d.ts.map +1 -1
- package/lib/typescript/metro/composeSourceMap.d.ts +26 -0
- package/lib/typescript/metro/composeSourceMap.d.ts.map +1 -0
- package/lib/typescript/metro/featureModules.d.ts +49 -0
- package/lib/typescript/metro/featureModules.d.ts.map +1 -0
- package/lib/typescript/metro/index.d.ts +22 -0
- package/lib/typescript/metro/index.d.ts.map +1 -1
- package/lib/typescript/metro/serializerCompose.d.ts +46 -0
- package/lib/typescript/metro/serializerCompose.d.ts.map +1 -0
- package/lib/typescript/pipeline/queue/persistentQueue.d.ts +0 -10
- package/lib/typescript/pipeline/queue/persistentQueue.d.ts.map +1 -1
- package/lib/typescript/push/native/nativeNotifications.d.ts +0 -6
- package/lib/typescript/push/native/nativeNotifications.d.ts.map +1 -1
- package/package.json +15 -11
- package/src/bootstrap/FeatureRegistry.ts +4 -4
- package/src/bootstrap/SDKBootstrapper.ts +8 -8
- package/src/core/config/schema.ts +353 -235
- package/src/core/constants/protocol.ts +24 -0
- package/src/core/constants/timings.ts +3 -1
- package/src/core/lifecycle/appLifecycle.ts +1 -1
- package/src/debug/bootstrap.ts +40 -7
- package/src/debug/exportBridge.ts +5 -3
- package/src/debug/hostResolver.ts +2 -2
- package/src/debug/perfWiring.ts +4 -4
- package/src/debug/replayWiring.ts +5 -5
- package/src/debug/screenTracking.ts +2 -2
- package/src/debug/sessionWiring.ts +2 -2
- package/src/features/crash/NativeCrashFeature.ts +1 -1
- package/src/features/crash/globalHandler.ts +3 -3
- package/src/features/crash/nativeCrashBridge.ts +7 -7
- package/src/features/crash/rejectionHandler.ts +2 -2
- package/src/features/engage/EngageArchetypeRenderers.tsx +0 -11
- package/src/features/engage/EngageInAppView.tsx +1 -1
- package/src/features/engage/EngagePromptProvider.tsx +17 -17
- package/src/features/engage/EngageTransport.ts +5 -5
- package/src/features/engage/engagePushTokenBridge.ts +4 -4
- package/src/features/engage/engageShakeBridge.ts +2 -2
- package/src/features/engage/engageSignals.ts +1 -1
- package/src/features/engage/engageStoreReviewBridge.ts +2 -2
- package/src/features/engage/engageTestSeenStore.ts +1 -1
- package/src/features/engage/engageThrottle.ts +4 -4
- package/src/features/engage/engageTriggerEngine.ts +4 -4
- package/src/features/engage/engageWindowInsets.ts +1 -1
- package/src/features/install-referrer/installReferrer.ts +3 -3
- package/src/features/journey/calibrationContext.ts +0 -9
- package/src/features/journey/journeyManager.ts +3 -1
- package/src/features/navigation/AutoScreenDetector.ts +4 -4
- package/src/features/ota/OtaOrchestrator.ts +18 -18
- package/src/features/ota/geoCountry.ts +2 -2
- package/src/features/ota/retry.ts +2 -2
- package/src/features/performance/PerformanceFeature.ts +130 -20
- package/src/features/replay/core/logger/logger.ts +0 -4
- package/src/features/replay/integrations/network/networkAdapter.ts +1 -56
- package/src/features/replay/integrations/react-navigation/navigationIntegration.ts +1 -1
- package/src/features/replay/integrations/touch/ReplayRoot.tsx +1 -1
- package/src/features/replay/pipeline/batching/batchManager.ts +1 -1
- package/src/features/replay/pipeline/retry/retryPolicy.ts +1 -1
- package/src/features/replay/public/api.ts +7 -7
- package/src/features/replay/replay/session/sessionOrchestrator.ts +9 -9
- package/src/features/session/BackendSessionAdapter.ts +41 -41
- package/src/features/session/DesktopSessionTransport.ts +4 -2
- package/src/features/session/JourneyEventPipeline.ts +1 -1
- package/src/features/session/ReplayCaptureManager.ts +14 -14
- package/src/features/session/SessionManager.ts +9 -9
- package/src/features/session/SyncDecisionEngine.ts +1 -1
- package/src/features/skan/skanBridge.ts +6 -14
- package/src/features/skan/skanConversionManager.ts +5 -5
- package/src/integrations/fetch/fetchInterceptor.ts +1 -1
- package/src/integrations/xhr/xhrInterceptor.ts +1 -1
- package/src/metro/composeSourceMap.ts +104 -0
- package/src/metro/featureModules.ts +143 -0
- package/src/metro/index.ts +173 -1
- package/src/metro/serializerCompose.ts +157 -0
- package/src/pipeline/dispatcher/dispatcher.ts +1 -1
- package/src/pipeline/queue/flushQueue.ts +2 -2
- package/src/pipeline/queue/persistentQueue.ts +6 -35
- package/src/pipeline/scheduler/flushScheduler.ts +1 -1
- package/src/public/ScaleBunFacade.ts +15 -15
- package/src/push/PushManager.ts +3 -3
- package/src/push/adapters/NativeBridgeAdapter.ts +1 -1
- package/src/push/native/nativeNotifications.ts +7 -16
- package/src/storage/StorageBackend.ts +1 -1
|
@@ -44,14 +44,14 @@ export async function getNativePushToken(): Promise<NativePushToken | null> {
|
|
|
44
44
|
try {
|
|
45
45
|
const mod = getEngageModule();
|
|
46
46
|
if (!mod?.getPushToken) {
|
|
47
|
-
logger.debug('[Engage] ScaleBunEngage native module unavailable — skipping push token');
|
|
47
|
+
__DEV__ && logger.debug('[Engage] ScaleBunEngage native module unavailable — skipping push token');
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
50
|
const result = await mod.getPushToken();
|
|
51
51
|
if (!result?.token || !result?.platform) return null;
|
|
52
52
|
return result;
|
|
53
53
|
} catch (err: any) {
|
|
54
|
-
logger.debug(`[Engage] getPushToken failed (fail-soft): ${err?.message}`);
|
|
54
|
+
__DEV__ && logger.debug(`[Engage] getPushToken failed (fail-soft): ${err?.message}`);
|
|
55
55
|
return null;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -66,7 +66,7 @@ export function subscribeNativePushTokenRefresh(
|
|
|
66
66
|
try {
|
|
67
67
|
const nativeModule = NativeModules?.ScaleBunEngage;
|
|
68
68
|
if (!nativeModule) {
|
|
69
|
-
logger.debug('[Engage] ScaleBunEngage native module unavailable — no token-refresh listener');
|
|
69
|
+
__DEV__ && logger.debug('[Engage] ScaleBunEngage native module unavailable — no token-refresh listener');
|
|
70
70
|
return () => {};
|
|
71
71
|
}
|
|
72
72
|
const emitter = new NativeEventEmitter(nativeModule);
|
|
@@ -78,7 +78,7 @@ export function subscribeNativePushTokenRefresh(
|
|
|
78
78
|
);
|
|
79
79
|
return () => subscription.remove();
|
|
80
80
|
} catch (err: any) {
|
|
81
|
-
logger.debug(`[Engage] token-refresh subscription failed (fail-soft): ${err?.message}`);
|
|
81
|
+
__DEV__ && logger.debug(`[Engage] token-refresh subscription failed (fail-soft): ${err?.message}`);
|
|
82
82
|
return () => {};
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -39,7 +39,7 @@ export function installEngageShakeBridge(): () => void {
|
|
|
39
39
|
try {
|
|
40
40
|
const mod = getModule();
|
|
41
41
|
if (!mod?.startShakeDetection) {
|
|
42
|
-
logger.debug('[Engage] ScaleBunEngage shake detection unavailable — skipping');
|
|
42
|
+
__DEV__ && logger.debug('[Engage] ScaleBunEngage shake detection unavailable — skipping');
|
|
43
43
|
return () => {};
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -61,7 +61,7 @@ export function installEngageShakeBridge(): () => void {
|
|
|
61
61
|
} catch { /* no-throw */ }
|
|
62
62
|
};
|
|
63
63
|
} catch (err: any) {
|
|
64
|
-
logger.debug(`[Engage] shake bridge install failed (fail-soft): ${err?.message}`);
|
|
64
|
+
__DEV__ && logger.debug(`[Engage] shake bridge install failed (fail-soft): ${err?.message}`);
|
|
65
65
|
return () => {};
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -36,13 +36,13 @@ export async function requestNativeStoreReview(): Promise<boolean> {
|
|
|
36
36
|
try {
|
|
37
37
|
const mod = getEngageModule();
|
|
38
38
|
if (!mod?.requestReview) {
|
|
39
|
-
logger.debug('[Engage] ScaleBunEngage native module unavailable — skipping store review');
|
|
39
|
+
__DEV__ && logger.debug('[Engage] ScaleBunEngage native module unavailable — skipping store review');
|
|
40
40
|
return false;
|
|
41
41
|
}
|
|
42
42
|
const ran = await mod.requestReview();
|
|
43
43
|
return ran === true;
|
|
44
44
|
} catch (err: any) {
|
|
45
|
-
logger.debug(`[Engage] requestReview failed (fail-soft): ${err?.message}`);
|
|
45
|
+
__DEV__ && logger.debug(`[Engage] requestReview failed (fail-soft): ${err?.message}`);
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -61,7 +61,7 @@ export class EngageTestSeenStore {
|
|
|
61
61
|
markSeen(testRunId: string): void {
|
|
62
62
|
if (!testRunId) return;
|
|
63
63
|
this.backend.set(this.keyFor(testRunId), String(Date.now()));
|
|
64
|
-
logger.debug(`[Engage] test ${testRunId} marked displayed (persisted)`);
|
|
64
|
+
__DEV__ && logger.debug(`[Engage] test ${testRunId} marked displayed (persisted)`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/**
|
|
@@ -85,7 +85,7 @@ export class EngageThrottleStore {
|
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
} catch (err) {
|
|
88
|
-
logger.debug('[Engage] throttle state read failed:', (err as Error)?.message);
|
|
88
|
+
__DEV__ && logger.debug('[Engage] throttle state read failed:', (err as Error)?.message);
|
|
89
89
|
}
|
|
90
90
|
return { impressions: 0, lastShownAt: 0, completed: false };
|
|
91
91
|
}
|
|
@@ -95,7 +95,7 @@ export class EngageThrottleStore {
|
|
|
95
95
|
try {
|
|
96
96
|
this.backend.delete(this.keyFor(campaignId));
|
|
97
97
|
} catch (err) {
|
|
98
|
-
logger.debug('[Engage] throttle clearOne failed:', (err as Error)?.message);
|
|
98
|
+
__DEV__ && logger.debug('[Engage] throttle clearOne failed:', (err as Error)?.message);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -115,7 +115,7 @@ export class EngageThrottleStore {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
} catch (err) {
|
|
118
|
-
logger.debug('[Engage] throttle clearAll failed:', (err as Error)?.message);
|
|
118
|
+
__DEV__ && logger.debug('[Engage] throttle clearAll failed:', (err as Error)?.message);
|
|
119
119
|
}
|
|
120
120
|
return n;
|
|
121
121
|
}
|
|
@@ -124,7 +124,7 @@ export class EngageThrottleStore {
|
|
|
124
124
|
try {
|
|
125
125
|
this.backend.set(this.keyFor(campaignId), JSON.stringify(state));
|
|
126
126
|
} catch (err) {
|
|
127
|
-
logger.debug('[Engage] throttle state write failed:', (err as Error)?.message);
|
|
127
|
+
__DEV__ && logger.debug('[Engage] throttle state write failed:', (err as Error)?.message);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -112,18 +112,18 @@ export function installEngageTriggerEngine(deps: EngageTriggerEngineDeps): () =>
|
|
|
112
112
|
// Found live: a cold start with the screen off burned both a survey
|
|
113
113
|
// and an in-app message before the phone was ever unlocked.
|
|
114
114
|
if (appLifecycle.getCurrentState() !== 'active') {
|
|
115
|
-
logger.debug(
|
|
115
|
+
__DEV__ && logger.debug(
|
|
116
116
|
`[Engage] trigger suppressed (app ${appLifecycle.getCurrentState()}): ${options.trigger ?? 'manual'}`,
|
|
117
117
|
);
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
logger.debug(
|
|
120
|
+
__DEV__ && logger.debug(
|
|
121
121
|
`[Engage] trigger fire: ${options.trigger ?? 'manual'}` +
|
|
122
122
|
(options.screen ? ` screen=${options.screen}` : ''),
|
|
123
123
|
);
|
|
124
124
|
deps.fire(options);
|
|
125
125
|
} catch (err) {
|
|
126
|
-
logger.debug('[Engage] trigger fire failed:', (err as Error)?.message);
|
|
126
|
+
__DEV__ && logger.debug('[Engage] trigger fire failed:', (err as Error)?.message);
|
|
127
127
|
}
|
|
128
128
|
};
|
|
129
129
|
|
|
@@ -297,7 +297,7 @@ export function installEngageTriggerEngine(deps: EngageTriggerEngineDeps): () =>
|
|
|
297
297
|
.filter((s): s is number => typeof s === 'number');
|
|
298
298
|
if (targets.includes(next)) fire({ trigger: 'n_sessions' });
|
|
299
299
|
} catch (err) {
|
|
300
|
-
logger.debug('[Engage] n_sessions check failed:', (err as Error)?.message);
|
|
300
|
+
__DEV__ && logger.debug('[Engage] n_sessions check failed:', (err as Error)?.message);
|
|
301
301
|
}
|
|
302
302
|
})();
|
|
303
303
|
|
|
@@ -64,7 +64,7 @@ export async function readNativeWindowInsets(
|
|
|
64
64
|
return normalizeWindowInsets(await module.getWindowInsets());
|
|
65
65
|
} catch (error: unknown) {
|
|
66
66
|
const reason = error instanceof Error ? error.message : String(error);
|
|
67
|
-
logger.debug(`[Engage] getWindowInsets failed (fail-soft): ${reason}`);
|
|
67
|
+
__DEV__ && logger.debug(`[Engage] getWindowInsets failed (fail-soft): ${reason}`);
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -40,7 +40,7 @@ export async function getInstallReferrer(): Promise<string | null> {
|
|
|
40
40
|
const raw = await mod.getInstallReferrer();
|
|
41
41
|
return typeof raw === 'string' ? raw : null;
|
|
42
42
|
} catch (err) {
|
|
43
|
-
logger.debug(`[InstallReferrer] fetch failed: ${(err as Error)?.message}`);
|
|
43
|
+
__DEV__ && logger.debug(`[InstallReferrer] fetch failed: ${(err as Error)?.message}`);
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -102,11 +102,11 @@ export async function captureInstallReferrerOnce(sink: InstallReferrerSink): Pro
|
|
|
102
102
|
if (!parsed) return;
|
|
103
103
|
if (parsed.clickId) sink.setClickId(parsed.clickId);
|
|
104
104
|
sink.emit('install_referrer', { referrer: parsed.raw, ...parsed.params });
|
|
105
|
-
logger.debug(
|
|
105
|
+
__DEV__ && logger.debug(
|
|
106
106
|
`[InstallReferrer] captured (clickId=${parsed.clickId ?? '-'}, ` +
|
|
107
107
|
`${Object.keys(parsed.params).length} params)`,
|
|
108
108
|
);
|
|
109
109
|
} catch (err) {
|
|
110
|
-
logger.debug(`[InstallReferrer] capture failed: ${(err as Error)?.message}`);
|
|
110
|
+
__DEV__ && logger.debug(`[InstallReferrer] capture failed: ${(err as Error)?.message}`);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
@@ -42,12 +42,3 @@ export function consumeCalibrationTarget(): CalibrationTarget | null {
|
|
|
42
42
|
pending = null;
|
|
43
43
|
return out;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
export function peekCalibrationTarget(): CalibrationTarget | null {
|
|
47
|
-
if (!pending) return null;
|
|
48
|
-
if (Date.now() - pending.setAt > TTL_MS) {
|
|
49
|
-
pending = null;
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return pending;
|
|
53
|
-
}
|
|
@@ -21,7 +21,9 @@ import { GestureDetector } from './gestureDetector';
|
|
|
21
21
|
import { NavDetector } from './navDetector';
|
|
22
22
|
import { ScreenshotHelper } from './screenshotHelper';
|
|
23
23
|
import { findTarget } from './targetRegistry';
|
|
24
|
-
|
|
24
|
+
// The SDK-owned constant, not the debug/protocol shim — the shim re-exports from the vendored
|
|
25
|
+
// schema module, which would pull every desktop wire-message schema into production bundles.
|
|
26
|
+
import { PROTOCOL_VERSION } from '../../core/constants/protocol';
|
|
25
27
|
|
|
26
28
|
// ─── Journey Event Names ────────────────────────────────────────────────────
|
|
27
29
|
|
|
@@ -142,7 +142,7 @@ export class AutoScreenDetector {
|
|
|
142
142
|
if (!ref) return;
|
|
143
143
|
this._navigationRef = ref;
|
|
144
144
|
this._wireNavigationListener();
|
|
145
|
-
logger.debug('[AutoScreenDetector] Navigation ref set');
|
|
145
|
+
__DEV__ && logger.debug('[AutoScreenDetector] Navigation ref set');
|
|
146
146
|
} catch (err: any) {
|
|
147
147
|
logger.warn('[AutoScreenDetector] setNavigationRef failed:', err?.message);
|
|
148
148
|
}
|
|
@@ -310,7 +310,7 @@ export class AutoScreenDetector {
|
|
|
310
310
|
this._started = true;
|
|
311
311
|
this._autoHookReactNavigation();
|
|
312
312
|
this._startHeuristicPolling();
|
|
313
|
-
logger.debug('[AutoScreenDetector] Started');
|
|
313
|
+
__DEV__ && logger.debug('[AutoScreenDetector] Started');
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
/**
|
|
@@ -432,7 +432,7 @@ export class AutoScreenDetector {
|
|
|
432
432
|
'ScaleBun.setNavigationRef(ref) to restore screen names.',
|
|
433
433
|
);
|
|
434
434
|
} else {
|
|
435
|
-
logger.debug(`[AutoScreenDetector] React Navigation auto-hook installed (${installed}/3 entry points)`);
|
|
435
|
+
__DEV__ && logger.debug(`[AutoScreenDetector] React Navigation auto-hook installed (${installed}/3 entry points)`);
|
|
436
436
|
}
|
|
437
437
|
} catch { /* @react-navigation/native not installed — heuristic remains fallback */ }
|
|
438
438
|
}
|
|
@@ -464,7 +464,7 @@ export class AutoScreenDetector {
|
|
|
464
464
|
this._navListenerWired = false;
|
|
465
465
|
this._started = false;
|
|
466
466
|
this._lastEmittedScreen = null;
|
|
467
|
-
logger.debug('[AutoScreenDetector] Stopped');
|
|
467
|
+
__DEV__ && logger.debug('[AutoScreenDetector] Stopped');
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
/** Teardown completely (reset singleton) */
|
|
@@ -162,12 +162,12 @@ async function deliverOtaEvents(params: {
|
|
|
162
162
|
},
|
|
163
163
|
);
|
|
164
164
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
165
|
-
logger.debug(`[OTA] Delivered ${items.length} telemetry event(s)`);
|
|
165
|
+
__DEV__ && logger.debug(`[OTA] Delivered ${items.length} telemetry event(s)`);
|
|
166
166
|
} catch (err: any) {
|
|
167
167
|
// Failed delivery must not fail the update — but the events must not be
|
|
168
168
|
// lost either: requeue so the next sync retries them.
|
|
169
169
|
for (const e of events) otaEventEmitter.emit(e);
|
|
170
|
-
logger.debug(`[OTA] Telemetry delivery failed (will retry next sync): ${err?.message}`);
|
|
170
|
+
__DEV__ && logger.debug(`[OTA] Telemetry delivery failed (will retry next sync): ${err?.message}`);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
@@ -269,7 +269,7 @@ export class OtaOrchestrator {
|
|
|
269
269
|
// We cannot see which form the host used — the identity check after
|
|
270
270
|
// restart is what proves it — but naming the right fix up front turns
|
|
271
271
|
// a confusing silent failure into a one-line correction.
|
|
272
|
-
logger.debug(
|
|
272
|
+
__DEV__ && logger.debug(
|
|
273
273
|
'[OTA] React Native >= 0.82 detected. The only valid Android integration is ' +
|
|
274
274
|
'getDefaultReactHost(..., jsBundleFilePath = ScaleBunOtaModule.getJSBundleFile(ctx)) — ' +
|
|
275
275
|
'ReactNativeHost and its getJSBundleFile() override no longer exist.',
|
|
@@ -280,7 +280,7 @@ export class OtaOrchestrator {
|
|
|
280
280
|
this.enabled = true;
|
|
281
281
|
this.bootGuardConfig = config ?? {};
|
|
282
282
|
this.signatureConfig = config?.signature;
|
|
283
|
-
logger.debug(
|
|
283
|
+
__DEV__ && logger.debug(
|
|
284
284
|
`[OTA] Orchestrator initialized (RN ${this.environment.rnVersionString ?? 'unknown'}` +
|
|
285
285
|
`${this.environment.bridgeless ? ', bridgeless' : ''}` +
|
|
286
286
|
`${this.environment.hermes ? `, Hermes HBC v${this.environment.hermesBytecodeVersion ?? '?'}` : ''})`,
|
|
@@ -329,7 +329,7 @@ export class OtaOrchestrator {
|
|
|
329
329
|
version: record.version,
|
|
330
330
|
sha256: record.sha256,
|
|
331
331
|
} as OtaBundlePayload;
|
|
332
|
-
logger.debug(`[OTA] Running bundle v${record.version} (${record.bundleId})`);
|
|
332
|
+
__DEV__ && logger.debug(`[OTA] Running bundle v${record.version} (${record.bundleId})`);
|
|
333
333
|
return;
|
|
334
334
|
}
|
|
335
335
|
|
|
@@ -337,7 +337,7 @@ export class OtaOrchestrator {
|
|
|
337
337
|
// a reinstall of the app, cleared storage, or a bundle staged by an
|
|
338
338
|
// older SDK. Report the hash so the server can still recognise it.
|
|
339
339
|
this.currentBundle = { sha256: current.sha256 } as OtaBundlePayload;
|
|
340
|
-
logger.debug(
|
|
340
|
+
__DEV__ && logger.debug(
|
|
341
341
|
`[OTA] Running an OTA bundle (sha ${String(current.sha256).slice(0, 12)}…) with no local install record.`,
|
|
342
342
|
);
|
|
343
343
|
} catch {
|
|
@@ -375,7 +375,7 @@ export class OtaOrchestrator {
|
|
|
375
375
|
if (expected) {
|
|
376
376
|
if (running === expected.identityToken) {
|
|
377
377
|
// Proven: the bundle we installed is the bundle executing.
|
|
378
|
-
logger.debug('[OTA] Install verified — running bundle matches what was installed.');
|
|
378
|
+
__DEV__ && logger.debug('[OTA] Install verified — running bundle matches what was installed.');
|
|
379
379
|
this.clearInstallExpectation();
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
@@ -619,11 +619,11 @@ export class OtaOrchestrator {
|
|
|
619
619
|
return { status: 'ERROR', error: 'OTA native module disabled or missing' };
|
|
620
620
|
}
|
|
621
621
|
|
|
622
|
-
logger.debug('[OTA] Sync started…');
|
|
622
|
+
__DEV__ && logger.debug('[OTA] Sync started…');
|
|
623
623
|
const checkRes = await this.checkForUpdate(params);
|
|
624
624
|
|
|
625
625
|
if (checkRes.action === 'NONE') {
|
|
626
|
-
logger.debug('[OTA] App is up to date');
|
|
626
|
+
__DEV__ && logger.debug('[OTA] App is up to date');
|
|
627
627
|
// If we booted from an OTA bundle and it's healthy, clear the boot guard
|
|
628
628
|
this.startBootGuardHeartbeat();
|
|
629
629
|
return { status: 'UP_TO_DATE' };
|
|
@@ -676,7 +676,7 @@ export class OtaOrchestrator {
|
|
|
676
676
|
// ── DOWNLOAD ─────────────────────────────────────────────────────────
|
|
677
677
|
otaEventEmitter.emitSimple('DOWNLOAD_STARTED', bundle.id, { version: bundle.version });
|
|
678
678
|
const downloadStart = Date.now();
|
|
679
|
-
logger.debug(`[OTA] Downloading update v${bundle.version}…`);
|
|
679
|
+
__DEV__ && logger.debug(`[OTA] Downloading update v${bundle.version}…`);
|
|
680
680
|
|
|
681
681
|
// Live progress: native tick → DOWNLOAD_PROGRESS (feeds useOtaUpdate) →
|
|
682
682
|
// throttled POST to the live tracker. `bundle.size` is the authoritative
|
|
@@ -727,7 +727,7 @@ export class OtaOrchestrator {
|
|
|
727
727
|
|
|
728
728
|
// Sprint 7: Try patch first if offered, fall back to full bundle
|
|
729
729
|
if (bundle.patch && NativeScaleBunOta.stagePatch) {
|
|
730
|
-
logger.debug(
|
|
730
|
+
__DEV__ && logger.debug(
|
|
731
731
|
`[OTA] Patch available (${(bundle.patch.size / 1024).toFixed(0)} KB vs ` +
|
|
732
732
|
`${(bundle.size / 1024).toFixed(0)} KB full) — trying patch…`,
|
|
733
733
|
);
|
|
@@ -739,7 +739,7 @@ export class OtaOrchestrator {
|
|
|
739
739
|
);
|
|
740
740
|
if (staged) {
|
|
741
741
|
patchUsed = true;
|
|
742
|
-
logger.debug('[OTA] Patch applied successfully');
|
|
742
|
+
__DEV__ && logger.debug('[OTA] Patch applied successfully');
|
|
743
743
|
} else {
|
|
744
744
|
logger.warn('[OTA] Patch staging returned false — falling back to full bundle');
|
|
745
745
|
}
|
|
@@ -821,7 +821,7 @@ export class OtaOrchestrator {
|
|
|
821
821
|
this.recordInstallExpectation(bundle);
|
|
822
822
|
|
|
823
823
|
otaEventEmitter.emitSimple('INSTALLED', bundle.id, { version: bundle.version });
|
|
824
|
-
logger.debug(`[OTA] Update v${bundle.version} installed successfully!`);
|
|
824
|
+
__DEV__ && logger.debug(`[OTA] Update v${bundle.version} installed successfully!`);
|
|
825
825
|
|
|
826
826
|
// Deliver telemetry BEFORE a restart tears the JS runtime down —
|
|
827
827
|
// an INSTALLED event queued but not sent would vanish with the process.
|
|
@@ -885,12 +885,12 @@ export class OtaOrchestrator {
|
|
|
885
885
|
}
|
|
886
886
|
|
|
887
887
|
const healthyMs = this.bootGuardConfig.healthyAfterMs ?? DEFAULT_HEALTHY_AFTER_MS;
|
|
888
|
-
logger.debug(`[OTA] Boot guard active — marking healthy after ${healthyMs}ms`);
|
|
888
|
+
__DEV__ && logger.debug(`[OTA] Boot guard active — marking healthy after ${healthyMs}ms`);
|
|
889
889
|
|
|
890
890
|
this.healthyTimer = setTimeout(() => {
|
|
891
891
|
noThrow(() => {
|
|
892
892
|
NativeScaleBunOta?.markHealthy();
|
|
893
|
-
logger.info('[OTA] Boot guard cleared — bundle marked healthy ✓');
|
|
893
|
+
__DEV__ && logger.info('[OTA] Boot guard cleared — bundle marked healthy ✓');
|
|
894
894
|
this.healthyTimer = null;
|
|
895
895
|
});
|
|
896
896
|
}, healthyMs);
|
|
@@ -933,11 +933,11 @@ export class OtaOrchestrator {
|
|
|
933
933
|
/* the restart below makes cleanup moot */
|
|
934
934
|
}
|
|
935
935
|
this.resumeRestartArmed = false;
|
|
936
|
-
logger.info('[OTA] App resumed — activating the staged update now');
|
|
936
|
+
__DEV__ && logger.info('[OTA] App resumed — activating the staged update now');
|
|
937
937
|
this.restart();
|
|
938
938
|
}
|
|
939
939
|
});
|
|
940
|
-
logger.debug('[OTA] Update staged — will activate on next resume (ON_NEXT_RESUME)');
|
|
940
|
+
__DEV__ && logger.debug('[OTA] Update staged — will activate on next resume (ON_NEXT_RESUME)');
|
|
941
941
|
} catch {
|
|
942
942
|
// AppState unavailable (tests, exotic hosts): the update still activates
|
|
943
943
|
// on the next cold start, which is the documented fallback behaviour.
|
|
@@ -957,7 +957,7 @@ export class OtaOrchestrator {
|
|
|
957
957
|
*/
|
|
958
958
|
restart(): void {
|
|
959
959
|
noThrow(() => {
|
|
960
|
-
logger.info('[OTA] Triggering app restart…');
|
|
960
|
+
__DEV__ && logger.info('[OTA] Triggering app restart…');
|
|
961
961
|
if (NativeScaleBunOta && typeof NativeScaleBunOta.restartApp === 'function') {
|
|
962
962
|
NativeScaleBunOta.restartApp();
|
|
963
963
|
} else if (DevSettings && typeof DevSettings.reload === 'function') {
|
|
@@ -73,9 +73,9 @@ export function prefetchDeviceCountry(): Promise<void> {
|
|
|
73
73
|
memory = raw;
|
|
74
74
|
storage.set(K_COUNTRY, raw);
|
|
75
75
|
storage.set(K_FETCHED_AT, String(Date.now()));
|
|
76
|
-
logger.debug(`[OTA] Device country resolved: ${raw}`);
|
|
76
|
+
__DEV__ && logger.debug(`[OTA] Device country resolved: ${raw}`);
|
|
77
77
|
} catch (err: any) {
|
|
78
|
-
logger.debug(`[OTA] Geo lookup skipped: ${err?.message ?? err}`);
|
|
78
|
+
__DEV__ && logger.debug(`[OTA] Geo lookup skipped: ${err?.message ?? err}`);
|
|
79
79
|
} finally {
|
|
80
80
|
clearTimeout(timer);
|
|
81
81
|
inFlight = null;
|
|
@@ -75,7 +75,7 @@ export async function retryWithBackoff<T>(
|
|
|
75
75
|
lastError = err;
|
|
76
76
|
|
|
77
77
|
if (!isRetryable(err)) {
|
|
78
|
-
logger.debug(`[OTA] ${label} failed with a non-retryable error — not retrying`);
|
|
78
|
+
__DEV__ && logger.debug(`[OTA] ${label} failed with a non-retryable error — not retrying`);
|
|
79
79
|
throw err;
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -83,7 +83,7 @@ export async function retryWithBackoff<T>(
|
|
|
83
83
|
if (isLast) break;
|
|
84
84
|
|
|
85
85
|
const delay = backoffDelay(attempt, baseDelayMs, maxDelayMs);
|
|
86
|
-
logger.debug(
|
|
86
|
+
__DEV__ && logger.debug(
|
|
87
87
|
`[OTA] ${label} failed (attempt ${attempt + 1}/${attempts}) — retrying in ${delay}ms`,
|
|
88
88
|
);
|
|
89
89
|
await sleep(delay);
|
|
@@ -25,6 +25,15 @@ import { PerformanceTransport, type PerfTransportSink } from './transport/Perfor
|
|
|
25
25
|
import { MetricKeys } from './metrics/MetricsEngine';
|
|
26
26
|
import { SessionManager } from '../session/SessionManager';
|
|
27
27
|
|
|
28
|
+
/** Shape accepted by BackendSessionAdapter.queuePerformanceMetric. */
|
|
29
|
+
type BackendPerfMetric = {
|
|
30
|
+
type: string;
|
|
31
|
+
screenName?: string;
|
|
32
|
+
duration?: number;
|
|
33
|
+
value?: number;
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
|
|
28
37
|
export class PerformanceFeature implements IFeature {
|
|
29
38
|
readonly name = 'performance';
|
|
30
39
|
private active = false;
|
|
@@ -70,7 +79,31 @@ export class PerformanceFeature implements IFeature {
|
|
|
70
79
|
/** Delay schedule for each attempt (ms) — escalating to let views settle */
|
|
71
80
|
private static readonly CAPTURE_DELAYS = [300, 600, 1200];
|
|
72
81
|
|
|
73
|
-
//
|
|
82
|
+
// ─── Early-metric buffering (backend) ───────────────────────────────
|
|
83
|
+
//
|
|
84
|
+
// Performance metrics reach the cloud via the SessionManager's backend
|
|
85
|
+
// transport. But the first metrics — most importantly app_launch — fire
|
|
86
|
+
// during PerformanceFeature.initialize() (appLaunchCollector.collect()),
|
|
87
|
+
// which runs from featureRegistry.initializeAll() BEFORE the bootstrap
|
|
88
|
+
// attaches the backend transport (SDKBootstrapper). In that window
|
|
89
|
+
// getBackendTransport() is null, so without buffering the metric is sent
|
|
90
|
+
// only to the desktop debugger and silently dropped from the cloud
|
|
91
|
+
// ("App start = 0" in Insights). We buffer such metrics locally and drain
|
|
92
|
+
// them the moment the transport appears (via subsequent events or a
|
|
93
|
+
// bounded retry). The backend adapter itself buffers again until the
|
|
94
|
+
// session row is ready, so ordering across the session boundary is safe.
|
|
95
|
+
/** Metrics captured before the backend transport was available. */
|
|
96
|
+
private _pendingBackendMetrics: BackendPerfMetric[] = [];
|
|
97
|
+
/** Retry timer that drains the buffer once the transport attaches. */
|
|
98
|
+
private _backendDrainTimer: ReturnType<typeof setTimeout> | null = null;
|
|
99
|
+
/** Number of drain attempts made for the current buffered batch. */
|
|
100
|
+
private _backendDrainAttempts = 0;
|
|
101
|
+
/** Hard cap on buffered metrics — bounds memory if a transport never attaches (non-SaaS). */
|
|
102
|
+
private static readonly BACKEND_BUFFER_MAX = 64;
|
|
103
|
+
/** Max drain retries before giving up (non-SaaS mode never attaches a transport). */
|
|
104
|
+
private static readonly BACKEND_DRAIN_MAX_ATTEMPTS = 6;
|
|
105
|
+
/** Escalating retry delays (ms); last value repeats. Covers the startup attach race. */
|
|
106
|
+
private static readonly BACKEND_DRAIN_DELAYS = [250, 500, 1000, 2000, 4000];
|
|
74
107
|
|
|
75
108
|
constructor(config?: Partial<PerformanceConfig>) {
|
|
76
109
|
this.config = mergePerformanceConfig(config);
|
|
@@ -297,6 +330,11 @@ export class PerformanceFeature implements IFeature {
|
|
|
297
330
|
clearTimeout(this._captureTimer);
|
|
298
331
|
this._captureTimer = null;
|
|
299
332
|
}
|
|
333
|
+
// Stop the backend-drain retry loop (buffered metrics are dropped —
|
|
334
|
+
// the desktop transport already received them via sendEvent/sendMetric).
|
|
335
|
+
this._clearBackendDrainTimer();
|
|
336
|
+
this._backendDrainAttempts = 0;
|
|
337
|
+
this._pendingBackendMetrics = [];
|
|
300
338
|
}
|
|
301
339
|
|
|
302
340
|
get isActive(): boolean {
|
|
@@ -570,28 +608,100 @@ export class PerformanceFeature implements IFeature {
|
|
|
570
608
|
* and it costs a duplicate serialize + upload per sample on every session.
|
|
571
609
|
*/
|
|
572
610
|
|
|
573
|
-
// Queue to SaaS backend dedicated performance endpoint
|
|
611
|
+
// Queue to SaaS backend dedicated performance endpoint. When the backend
|
|
612
|
+
// transport isn't attached yet (startup race — app_launch fires before
|
|
613
|
+
// SDKBootstrapper wires it), buffer locally and drain once it appears so
|
|
614
|
+
// the cloud gets the metric instead of only the desktop debugger.
|
|
615
|
+
this._forwardMetricToBackend(this._toBackendMetric(event));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/** Map a raw perf event onto the backend metric envelope. */
|
|
619
|
+
private _toBackendMetric(event: AnyPerfEvent): BackendPerfMetric {
|
|
620
|
+
const e = event as any;
|
|
621
|
+
// Forward structured launch fields so the backend can group by launch
|
|
622
|
+
// type and reconstruct the startup waterfall. Without this, only the
|
|
623
|
+
// raw duration reaches the analytics table and cold/warm/hot + phase
|
|
624
|
+
// timings are lost. Additive + forward-only: pre-existing rows stay as
|
|
625
|
+
// { id } and historical launch-type windows remain empty.
|
|
626
|
+
const metadata: Record<string, unknown> = { id: event.id };
|
|
627
|
+
if (event.type === 'app_launch') {
|
|
628
|
+
if (e.launchType) metadata.launchType = e.launchType;
|
|
629
|
+
if (e.breakdown) metadata.breakdown = e.breakdown;
|
|
630
|
+
if (e.phaseLabels) metadata.phaseLabels = e.phaseLabels;
|
|
631
|
+
}
|
|
632
|
+
return {
|
|
633
|
+
type: event.type,
|
|
634
|
+
screenName: e.screenName ?? e.context?.screenKey,
|
|
635
|
+
duration: e.durationMs,
|
|
636
|
+
value: e.estimatedFps ?? e.value,
|
|
637
|
+
metadata,
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Hand a metric to the backend transport, or buffer it until one attaches.
|
|
643
|
+
* Every call first drains anything buffered, so a late-arriving transport
|
|
644
|
+
* flushes the backlog in the order the metrics were produced.
|
|
645
|
+
*/
|
|
646
|
+
private _forwardMetricToBackend(metric: BackendPerfMetric): void {
|
|
574
647
|
const backendTransport = SessionManager.getExistingInstance()?.getBackendTransport();
|
|
575
648
|
if (backendTransport) {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
649
|
+
this._drainPendingBackendMetrics(backendTransport);
|
|
650
|
+
backendTransport.queuePerformanceMetric(metric);
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// No transport yet — buffer (bounded, drop-oldest) and schedule a drain.
|
|
655
|
+
this._pendingBackendMetrics.push(metric);
|
|
656
|
+
if (this._pendingBackendMetrics.length > PerformanceFeature.BACKEND_BUFFER_MAX) {
|
|
657
|
+
this._pendingBackendMetrics.shift();
|
|
658
|
+
}
|
|
659
|
+
this._scheduleBackendDrain();
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/** Flush all buffered metrics into the transport, preserving order. */
|
|
663
|
+
private _drainPendingBackendMetrics(
|
|
664
|
+
backendTransport: NonNullable<ReturnType<SessionManager['getBackendTransport']>>,
|
|
665
|
+
): void {
|
|
666
|
+
if (this._pendingBackendMetrics.length === 0) return;
|
|
667
|
+
const buffered = this._pendingBackendMetrics;
|
|
668
|
+
this._pendingBackendMetrics = [];
|
|
669
|
+
for (const metric of buffered) {
|
|
670
|
+
backendTransport.queuePerformanceMetric(metric);
|
|
671
|
+
}
|
|
672
|
+
this._clearBackendDrainTimer();
|
|
673
|
+
this._backendDrainAttempts = 0;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Poll for the backend transport a bounded number of times so the sole
|
|
678
|
+
* early metric (app_launch) still reaches the cloud even when no later
|
|
679
|
+
* event arrives to trigger a drain. Gives up after BACKEND_DRAIN_MAX_ATTEMPTS
|
|
680
|
+
* (non-SaaS mode never attaches a transport — the desktop path already has
|
|
681
|
+
* the data), leaving the bounded buffer to be GC'd on teardown.
|
|
682
|
+
*/
|
|
683
|
+
private _scheduleBackendDrain(): void {
|
|
684
|
+
if (this._backendDrainTimer) return;
|
|
685
|
+
if (this._backendDrainAttempts >= PerformanceFeature.BACKEND_DRAIN_MAX_ATTEMPTS) return;
|
|
686
|
+
|
|
687
|
+
const delays = PerformanceFeature.BACKEND_DRAIN_DELAYS;
|
|
688
|
+
const delay = delays[Math.min(this._backendDrainAttempts, delays.length - 1)];
|
|
689
|
+
this._backendDrainAttempts++;
|
|
690
|
+
this._backendDrainTimer = setTimeout(() => {
|
|
691
|
+
this._backendDrainTimer = null;
|
|
692
|
+
const backendTransport = SessionManager.getExistingInstance()?.getBackendTransport();
|
|
693
|
+
if (backendTransport) {
|
|
694
|
+
this._drainPendingBackendMetrics(backendTransport);
|
|
695
|
+
} else if (this._pendingBackendMetrics.length > 0) {
|
|
696
|
+
this._scheduleBackendDrain();
|
|
587
697
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
698
|
+
}, delay);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
private _clearBackendDrainTimer(): void {
|
|
702
|
+
if (this._backendDrainTimer) {
|
|
703
|
+
clearTimeout(this._backendDrainTimer);
|
|
704
|
+
this._backendDrainTimer = null;
|
|
595
705
|
}
|
|
596
706
|
}
|
|
597
707
|
}
|