@scalebun-release/web 2.2.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 -0
- package/README.md +57 -0
- package/dist/bootstrap/FeatureRegistry.d.ts +44 -0
- package/dist/bootstrap/FeatureRegistry.d.ts.map +1 -0
- package/dist/bootstrap/FeatureRegistry.js +85 -0
- package/dist/bootstrap/FeatureRegistry.js.map +1 -0
- package/dist/bootstrap/SDKBootstrapper.d.ts +37 -0
- package/dist/bootstrap/SDKBootstrapper.d.ts.map +1 -0
- package/dist/bootstrap/SDKBootstrapper.js +346 -0
- package/dist/bootstrap/SDKBootstrapper.js.map +1 -0
- package/dist/browser.d.ts +51 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +86 -0
- package/dist/browser.js.map +1 -0
- package/dist/config/endpoints.d.ts +12 -0
- package/dist/config/endpoints.d.ts.map +1 -0
- package/dist/config/endpoints.js +12 -0
- package/dist/config/endpoints.js.map +1 -0
- package/dist/config/schema.d.ts +120 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +117 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/breadcrumbs.d.ts +56 -0
- package/dist/core/breadcrumbs.d.ts.map +1 -0
- package/dist/core/breadcrumbs.js +141 -0
- package/dist/core/breadcrumbs.js.map +1 -0
- package/dist/core/capabilities.d.ts +38 -0
- package/dist/core/capabilities.d.ts.map +1 -0
- package/dist/core/capabilities.js +78 -0
- package/dist/core/capabilities.js.map +1 -0
- package/dist/core/consent.d.ts +17 -0
- package/dist/core/consent.d.ts.map +1 -0
- package/dist/core/consent.js +38 -0
- package/dist/core/consent.js.map +1 -0
- package/dist/core/csp.d.ts +31 -0
- package/dist/core/csp.d.ts.map +1 -0
- package/dist/core/csp.js +74 -0
- package/dist/core/csp.js.map +1 -0
- package/dist/core/evalContext.d.ts +7 -0
- package/dist/core/evalContext.d.ts.map +1 -0
- package/dist/core/evalContext.js +22 -0
- package/dist/core/evalContext.js.map +1 -0
- package/dist/core/ids.d.ts +6 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +35 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +16 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lifecycle.d.ts +4 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +24 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/logger.d.ts +12 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +14 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/observe.d.ts +3 -0
- package/dist/core/observe.d.ts.map +1 -0
- package/dist/core/observe.js +22 -0
- package/dist/core/observe.js.map +1 -0
- package/dist/core/pageContext.d.ts +13 -0
- package/dist/core/pageContext.d.ts.map +1 -0
- package/dist/core/pageContext.js +90 -0
- package/dist/core/pageContext.js.map +1 -0
- package/dist/core/prune.d.ts +31 -0
- package/dist/core/prune.d.ts.map +1 -0
- package/dist/core/prune.js +112 -0
- package/dist/core/prune.js.map +1 -0
- package/dist/core/redact.d.ts +15 -0
- package/dist/core/redact.d.ts.map +1 -0
- package/dist/core/redact.js +72 -0
- package/dist/core/redact.js.map +1 -0
- package/dist/core/replayCoord.d.ts +22 -0
- package/dist/core/replayCoord.d.ts.map +1 -0
- package/dist/core/replayCoord.js +20 -0
- package/dist/core/replayCoord.js.map +1 -0
- package/dist/core/retry.d.ts +25 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +44 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/runtime.d.ts +28 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +67 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/scrollDepth.d.ts +48 -0
- package/dist/core/scrollDepth.d.ts.map +1 -0
- package/dist/core/scrollDepth.js +63 -0
- package/dist/core/scrollDepth.js.map +1 -0
- package/dist/core/uiStateReader.d.ts +35 -0
- package/dist/core/uiStateReader.d.ts.map +1 -0
- package/dist/core/uiStateReader.js +47 -0
- package/dist/core/uiStateReader.js.map +1 -0
- package/dist/core/version.generated.d.ts +9 -0
- package/dist/core/version.generated.d.ts.map +1 -0
- package/dist/core/version.generated.js +9 -0
- package/dist/core/version.generated.js.map +1 -0
- package/dist/debug/index.d.ts +6 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +2 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/features/analytics/AnalyticsFeature.d.ts +123 -0
- package/dist/features/analytics/AnalyticsFeature.d.ts.map +1 -0
- package/dist/features/analytics/AnalyticsFeature.js +785 -0
- package/dist/features/analytics/AnalyticsFeature.js.map +1 -0
- package/dist/features/analytics/autocapture.d.ts +13 -0
- package/dist/features/analytics/autocapture.d.ts.map +1 -0
- package/dist/features/analytics/autocapture.js +436 -0
- package/dist/features/analytics/autocapture.js.map +1 -0
- package/dist/features/analytics/governance.d.ts +15 -0
- package/dist/features/analytics/governance.d.ts.map +1 -0
- package/dist/features/analytics/governance.js +30 -0
- package/dist/features/analytics/governance.js.map +1 -0
- package/dist/features/analytics/revenue.d.ts +77 -0
- package/dist/features/analytics/revenue.d.ts.map +1 -0
- package/dist/features/analytics/revenue.js +56 -0
- package/dist/features/analytics/revenue.js.map +1 -0
- package/dist/features/analytics/sampler.d.ts +2 -0
- package/dist/features/analytics/sampler.d.ts.map +1 -0
- package/dist/features/analytics/sampler.js +24 -0
- package/dist/features/analytics/sampler.js.map +1 -0
- package/dist/features/analytics/subscription.d.ts +35 -0
- package/dist/features/analytics/subscription.d.ts.map +1 -0
- package/dist/features/analytics/subscription.js +95 -0
- package/dist/features/analytics/subscription.js.map +1 -0
- package/dist/features/attention/index.d.ts +29 -0
- package/dist/features/attention/index.d.ts.map +1 -0
- package/dist/features/attention/index.js +128 -0
- package/dist/features/attention/index.js.map +1 -0
- package/dist/features/bugreport/BugReportFeature.d.ts +37 -0
- package/dist/features/bugreport/BugReportFeature.d.ts.map +1 -0
- package/dist/features/bugreport/BugReportFeature.js +56 -0
- package/dist/features/bugreport/BugReportFeature.js.map +1 -0
- package/dist/features/bugreport/collect.d.ts +33 -0
- package/dist/features/bugreport/collect.d.ts.map +1 -0
- package/dist/features/bugreport/collect.js +30 -0
- package/dist/features/bugreport/collect.js.map +1 -0
- package/dist/features/bugreport/widget.d.ts +40 -0
- package/dist/features/bugreport/widget.d.ts.map +1 -0
- package/dist/features/bugreport/widget.js +145 -0
- package/dist/features/bugreport/widget.js.map +1 -0
- package/dist/features/coach/CoachmarkFeature.d.ts +78 -0
- package/dist/features/coach/CoachmarkFeature.d.ts.map +1 -0
- package/dist/features/coach/CoachmarkFeature.js +161 -0
- package/dist/features/coach/CoachmarkFeature.js.map +1 -0
- package/dist/features/coach/anchor.d.ts +32 -0
- package/dist/features/coach/anchor.d.ts.map +1 -0
- package/dist/features/coach/anchor.js +128 -0
- package/dist/features/coach/anchor.js.map +1 -0
- package/dist/features/coach/observers.d.ts +17 -0
- package/dist/features/coach/observers.d.ts.map +1 -0
- package/dist/features/coach/observers.js +49 -0
- package/dist/features/coach/observers.js.map +1 -0
- package/dist/features/coach/overlay.d.ts +15 -0
- package/dist/features/coach/overlay.d.ts.map +1 -0
- package/dist/features/coach/overlay.js +205 -0
- package/dist/features/coach/overlay.js.map +1 -0
- package/dist/features/coach/position.d.ts +9 -0
- package/dist/features/coach/position.d.ts.map +1 -0
- package/dist/features/coach/position.js +83 -0
- package/dist/features/coach/position.js.map +1 -0
- package/dist/features/coach/predicate.d.ts +10 -0
- package/dist/features/coach/predicate.d.ts.map +1 -0
- package/dist/features/coach/predicate.js +36 -0
- package/dist/features/coach/predicate.js.map +1 -0
- package/dist/features/coach/tour.d.ts +55 -0
- package/dist/features/coach/tour.d.ts.map +1 -0
- package/dist/features/coach/tour.js +181 -0
- package/dist/features/coach/tour.js.map +1 -0
- package/dist/features/coach/types.d.ts +161 -0
- package/dist/features/coach/types.d.ts.map +1 -0
- package/dist/features/coach/types.js +2 -0
- package/dist/features/coach/types.js.map +1 -0
- package/dist/features/coach/wait.d.ts +34 -0
- package/dist/features/coach/wait.d.ts.map +1 -0
- package/dist/features/coach/wait.js +107 -0
- package/dist/features/coach/wait.js.map +1 -0
- package/dist/features/config/ConfigFeature.d.ts +117 -0
- package/dist/features/config/ConfigFeature.d.ts.map +1 -0
- package/dist/features/config/ConfigFeature.js +437 -0
- package/dist/features/config/ConfigFeature.js.map +1 -0
- package/dist/features/config/bucketing.d.ts +20 -0
- package/dist/features/config/bucketing.d.ts.map +1 -0
- package/dist/features/config/bucketing.js +37 -0
- package/dist/features/config/bucketing.js.map +1 -0
- package/dist/features/config/configStore.d.ts +11 -0
- package/dist/features/config/configStore.d.ts.map +1 -0
- package/dist/features/config/configStore.js +66 -0
- package/dist/features/config/configStore.js.map +1 -0
- package/dist/features/config/targeting.d.ts +11 -0
- package/dist/features/config/targeting.d.ts.map +1 -0
- package/dist/features/config/targeting.js +57 -0
- package/dist/features/config/targeting.js.map +1 -0
- package/dist/features/config/types.d.ts +100 -0
- package/dist/features/config/types.d.ts.map +1 -0
- package/dist/features/config/types.js +9 -0
- package/dist/features/config/types.js.map +1 -0
- package/dist/features/console/ConsoleFeature.d.ts +31 -0
- package/dist/features/console/ConsoleFeature.d.ts.map +1 -0
- package/dist/features/console/ConsoleFeature.js +98 -0
- package/dist/features/console/ConsoleFeature.js.map +1 -0
- package/dist/features/console/normalize.d.ts +18 -0
- package/dist/features/console/normalize.d.ts.map +1 -0
- package/dist/features/console/normalize.js +64 -0
- package/dist/features/console/normalize.js.map +1 -0
- package/dist/features/console/serialize.d.ts +24 -0
- package/dist/features/console/serialize.d.ts.map +1 -0
- package/dist/features/console/serialize.js +99 -0
- package/dist/features/console/serialize.js.map +1 -0
- package/dist/features/console/throttle.d.ts +27 -0
- package/dist/features/console/throttle.d.ts.map +1 -0
- package/dist/features/console/throttle.js +37 -0
- package/dist/features/console/throttle.js.map +1 -0
- package/dist/features/crash/CrashFeature.d.ts +46 -0
- package/dist/features/crash/CrashFeature.d.ts.map +1 -0
- package/dist/features/crash/CrashFeature.js +173 -0
- package/dist/features/crash/CrashFeature.js.map +1 -0
- package/dist/features/crash/liveness.d.ts +30 -0
- package/dist/features/crash/liveness.d.ts.map +1 -0
- package/dist/features/crash/liveness.js +131 -0
- package/dist/features/crash/liveness.js.map +1 -0
- package/dist/features/engage/EngageFeature.d.ts +67 -0
- package/dist/features/engage/EngageFeature.d.ts.map +1 -0
- package/dist/features/engage/EngageFeature.js +243 -0
- package/dist/features/engage/EngageFeature.js.map +1 -0
- package/dist/features/engage/attachments.d.ts +24 -0
- package/dist/features/engage/attachments.d.ts.map +1 -0
- package/dist/features/engage/attachments.js +209 -0
- package/dist/features/engage/attachments.js.map +1 -0
- package/dist/features/engage/gameLogic.d.ts +60 -0
- package/dist/features/engage/gameLogic.d.ts.map +1 -0
- package/dist/features/engage/gameLogic.js +213 -0
- package/dist/features/engage/gameLogic.js.map +1 -0
- package/dist/features/engage/gameResolver.d.ts +35 -0
- package/dist/features/engage/gameResolver.d.ts.map +1 -0
- package/dist/features/engage/gameResolver.js +81 -0
- package/dist/features/engage/gameResolver.js.map +1 -0
- package/dist/features/engage/gameTypes.d.ts +76 -0
- package/dist/features/engage/gameTypes.d.ts.map +1 -0
- package/dist/features/engage/gameTypes.js +17 -0
- package/dist/features/engage/gameTypes.js.map +1 -0
- package/dist/features/engage/inappSlots.d.ts +39 -0
- package/dist/features/engage/inappSlots.d.ts.map +1 -0
- package/dist/features/engage/inappSlots.js +50 -0
- package/dist/features/engage/inappSlots.js.map +1 -0
- package/dist/features/engage/normalize.d.ts +11 -0
- package/dist/features/engage/normalize.d.ts.map +1 -0
- package/dist/features/engage/normalize.js +210 -0
- package/dist/features/engage/normalize.js.map +1 -0
- package/dist/features/engage/richInApp.d.ts +64 -0
- package/dist/features/engage/richInApp.d.ts.map +1 -0
- package/dist/features/engage/richInApp.js +1082 -0
- package/dist/features/engage/richInApp.js.map +1 -0
- package/dist/features/engage/runtime.d.ts +89 -0
- package/dist/features/engage/runtime.d.ts.map +1 -0
- package/dist/features/engage/runtime.js +364 -0
- package/dist/features/engage/runtime.js.map +1 -0
- package/dist/features/engage/shakeDetector.d.ts +6 -0
- package/dist/features/engage/shakeDetector.d.ts.map +1 -0
- package/dist/features/engage/shakeDetector.js +105 -0
- package/dist/features/engage/shakeDetector.js.map +1 -0
- package/dist/features/engage/theme.d.ts +129 -0
- package/dist/features/engage/theme.d.ts.map +1 -0
- package/dist/features/engage/theme.js +270 -0
- package/dist/features/engage/theme.js.map +1 -0
- package/dist/features/engage/throttle.d.ts +41 -0
- package/dist/features/engage/throttle.d.ts.map +1 -0
- package/dist/features/engage/throttle.js +220 -0
- package/dist/features/engage/throttle.js.map +1 -0
- package/dist/features/engage/transport.d.ts +62 -0
- package/dist/features/engage/transport.d.ts.map +1 -0
- package/dist/features/engage/transport.js +185 -0
- package/dist/features/engage/transport.js.map +1 -0
- package/dist/features/engage/triggerEngine.d.ts +39 -0
- package/dist/features/engage/triggerEngine.d.ts.map +1 -0
- package/dist/features/engage/triggerEngine.js +105 -0
- package/dist/features/engage/triggerEngine.js.map +1 -0
- package/dist/features/engage/types.d.ts +271 -0
- package/dist/features/engage/types.d.ts.map +1 -0
- package/dist/features/engage/types.js +3 -0
- package/dist/features/engage/types.js.map +1 -0
- package/dist/features/engage/widget/InAppWidget.d.ts +10 -0
- package/dist/features/engage/widget/InAppWidget.d.ts.map +1 -0
- package/dist/features/engage/widget/InAppWidget.js +137 -0
- package/dist/features/engage/widget/InAppWidget.js.map +1 -0
- package/dist/features/engage/widget/SurveyWidget.d.ts +11 -0
- package/dist/features/engage/widget/SurveyWidget.d.ts.map +1 -0
- package/dist/features/engage/widget/SurveyWidget.js +547 -0
- package/dist/features/engage/widget/SurveyWidget.js.map +1 -0
- package/dist/features/errors/ErrorsFeature.d.ts +62 -0
- package/dist/features/errors/ErrorsFeature.d.ts.map +1 -0
- package/dist/features/errors/ErrorsFeature.js +209 -0
- package/dist/features/errors/ErrorsFeature.js.map +1 -0
- package/dist/features/errors/causes.d.ts +15 -0
- package/dist/features/errors/causes.d.ts.map +1 -0
- package/dist/features/errors/causes.js +29 -0
- package/dist/features/errors/causes.js.map +1 -0
- package/dist/features/errors/dedup.d.ts +28 -0
- package/dist/features/errors/dedup.d.ts.map +1 -0
- package/dist/features/errors/dedup.js +42 -0
- package/dist/features/errors/dedup.js.map +1 -0
- package/dist/features/errors/group/fingerprint.d.ts +13 -0
- package/dist/features/errors/group/fingerprint.d.ts.map +1 -0
- package/dist/features/errors/group/fingerprint.js +45 -0
- package/dist/features/errors/group/fingerprint.js.map +1 -0
- package/dist/features/errors/lazy.d.ts +8 -0
- package/dist/features/errors/lazy.d.ts.map +1 -0
- package/dist/features/errors/lazy.js +8 -0
- package/dist/features/errors/lazy.js.map +1 -0
- package/dist/features/errors/normalize.d.ts +26 -0
- package/dist/features/errors/normalize.d.ts.map +1 -0
- package/dist/features/errors/normalize.js +58 -0
- package/dist/features/errors/normalize.js.map +1 -0
- package/dist/features/errors/parse/stacktrace.d.ts +13 -0
- package/dist/features/errors/parse/stacktrace.d.ts.map +1 -0
- package/dist/features/errors/parse/stacktrace.js +85 -0
- package/dist/features/errors/parse/stacktrace.js.map +1 -0
- package/dist/features/errors/redact.d.ts +7 -0
- package/dist/features/errors/redact.d.ts.map +1 -0
- package/dist/features/errors/redact.js +39 -0
- package/dist/features/errors/redact.js.map +1 -0
- package/dist/features/errors/sampling.d.ts +2 -0
- package/dist/features/errors/sampling.d.ts.map +1 -0
- package/dist/features/errors/sampling.js +24 -0
- package/dist/features/errors/sampling.js.map +1 -0
- package/dist/features/errors/scope.d.ts +26 -0
- package/dist/features/errors/scope.d.ts.map +1 -0
- package/dist/features/errors/scope.js +30 -0
- package/dist/features/errors/scope.js.map +1 -0
- package/dist/features/exit-intent/ExitIntentFeature.d.ts +16 -0
- package/dist/features/exit-intent/ExitIntentFeature.d.ts.map +1 -0
- package/dist/features/exit-intent/ExitIntentFeature.js +25 -0
- package/dist/features/exit-intent/ExitIntentFeature.js.map +1 -0
- package/dist/features/exit-intent/engine.d.ts +127 -0
- package/dist/features/exit-intent/engine.d.ts.map +1 -0
- package/dist/features/exit-intent/engine.js +227 -0
- package/dist/features/exit-intent/engine.js.map +1 -0
- package/dist/features/forms/index.d.ts +83 -0
- package/dist/features/forms/index.d.ts.map +1 -0
- package/dist/features/forms/index.js +405 -0
- package/dist/features/forms/index.js.map +1 -0
- package/dist/features/inapp/InApp2Feature.d.ts +24 -0
- package/dist/features/inapp/InApp2Feature.d.ts.map +1 -0
- package/dist/features/inapp/InApp2Feature.js +44 -0
- package/dist/features/inapp/InApp2Feature.js.map +1 -0
- package/dist/features/inapp/a11y/focus.d.ts +24 -0
- package/dist/features/inapp/a11y/focus.d.ts.map +1 -0
- package/dist/features/inapp/a11y/focus.js +112 -0
- package/dist/features/inapp/a11y/focus.js.map +1 -0
- package/dist/features/inapp/anchor/controller.d.ts +64 -0
- package/dist/features/inapp/anchor/controller.d.ts.map +1 -0
- package/dist/features/inapp/anchor/controller.js +155 -0
- package/dist/features/inapp/anchor/controller.js.map +1 -0
- package/dist/features/inapp/api.d.ts +28 -0
- package/dist/features/inapp/api.d.ts.map +1 -0
- package/dist/features/inapp/api.js +41 -0
- package/dist/features/inapp/api.js.map +1 -0
- package/dist/features/inapp/blocks/blocks.d.ts +65 -0
- package/dist/features/inapp/blocks/blocks.d.ts.map +1 -0
- package/dist/features/inapp/blocks/blocks.js +196 -0
- package/dist/features/inapp/blocks/blocks.js.map +1 -0
- package/dist/features/inapp/blocks/feedback.d.ts +13 -0
- package/dist/features/inapp/blocks/feedback.d.ts.map +1 -0
- package/dist/features/inapp/blocks/feedback.js +154 -0
- package/dist/features/inapp/blocks/feedback.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/carousel.d.ts +8 -0
- package/dist/features/inapp/blocks/heavy/carousel.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/carousel.js +67 -0
- package/dist/features/inapp/blocks/heavy/carousel.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/chart.d.ts +9 -0
- package/dist/features/inapp/blocks/heavy/chart.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/chart.js +83 -0
- package/dist/features/inapp/blocks/heavy/chart.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/code.d.ts +8 -0
- package/dist/features/inapp/blocks/heavy/code.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/code.js +47 -0
- package/dist/features/inapp/blocks/heavy/code.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/confetti.d.ts +9 -0
- package/dist/features/inapp/blocks/heavy/confetti.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/confetti.js +76 -0
- package/dist/features/inapp/blocks/heavy/confetti.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/countdown.d.ts +9 -0
- package/dist/features/inapp/blocks/heavy/countdown.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/countdown.js +59 -0
- package/dist/features/inapp/blocks/heavy/countdown.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/index.d.ts +11 -0
- package/dist/features/inapp/blocks/heavy/index.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/index.js +45 -0
- package/dist/features/inapp/blocks/heavy/index.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/markdown.d.ts +9 -0
- package/dist/features/inapp/blocks/heavy/markdown.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/markdown.js +76 -0
- package/dist/features/inapp/blocks/heavy/markdown.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/productgrid.d.ts +8 -0
- package/dist/features/inapp/blocks/heavy/productgrid.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/productgrid.js +46 -0
- package/dist/features/inapp/blocks/heavy/productgrid.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/qr.d.ts +10 -0
- package/dist/features/inapp/blocks/heavy/qr.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/qr.js +69 -0
- package/dist/features/inapp/blocks/heavy/qr.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/scratch.d.ts +8 -0
- package/dist/features/inapp/blocks/heavy/scratch.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/scratch.js +141 -0
- package/dist/features/inapp/blocks/heavy/scratch.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/slot.d.ts +8 -0
- package/dist/features/inapp/blocks/heavy/slot.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/slot.js +96 -0
- package/dist/features/inapp/blocks/heavy/slot.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/spinwheel.d.ts +9 -0
- package/dist/features/inapp/blocks/heavy/spinwheel.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/spinwheel.js +127 -0
- package/dist/features/inapp/blocks/heavy/spinwheel.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/steps.d.ts +27 -0
- package/dist/features/inapp/blocks/heavy/steps.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/steps.js +135 -0
- package/dist/features/inapp/blocks/heavy/steps.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/streak.d.ts +18 -0
- package/dist/features/inapp/blocks/heavy/streak.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/streak.js +52 -0
- package/dist/features/inapp/blocks/heavy/streak.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/table.d.ts +7 -0
- package/dist/features/inapp/blocks/heavy/table.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/table.js +30 -0
- package/dist/features/inapp/blocks/heavy/table.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/unavailable.d.ts +28 -0
- package/dist/features/inapp/blocks/heavy/unavailable.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/unavailable.js +33 -0
- package/dist/features/inapp/blocks/heavy/unavailable.js.map +1 -0
- package/dist/features/inapp/blocks/heavy/video.d.ts +7 -0
- package/dist/features/inapp/blocks/heavy/video.d.ts.map +1 -0
- package/dist/features/inapp/blocks/heavy/video.js +38 -0
- package/dist/features/inapp/blocks/heavy/video.js.map +1 -0
- package/dist/features/inapp/blocks/styles.d.ts +7 -0
- package/dist/features/inapp/blocks/styles.d.ts.map +1 -0
- package/dist/features/inapp/blocks/styles.js +225 -0
- package/dist/features/inapp/blocks/styles.js.map +1 -0
- package/dist/features/inapp/center/bridge.d.ts +12 -0
- package/dist/features/inapp/center/bridge.d.ts.map +1 -0
- package/dist/features/inapp/center/bridge.js +59 -0
- package/dist/features/inapp/center/bridge.js.map +1 -0
- package/dist/features/inapp/center/panel.d.ts +20 -0
- package/dist/features/inapp/center/panel.d.ts.map +1 -0
- package/dist/features/inapp/center/panel.js +228 -0
- package/dist/features/inapp/center/panel.js.map +1 -0
- package/dist/features/inapp/center/store.d.ts +50 -0
- package/dist/features/inapp/center/store.d.ts.map +1 -0
- package/dist/features/inapp/center/store.js +188 -0
- package/dist/features/inapp/center/store.js.map +1 -0
- package/dist/features/inapp/center/sync.d.ts +32 -0
- package/dist/features/inapp/center/sync.d.ts.map +1 -0
- package/dist/features/inapp/center/sync.js +60 -0
- package/dist/features/inapp/center/sync.js.map +1 -0
- package/dist/features/inapp/center/types.d.ts +46 -0
- package/dist/features/inapp/center/types.d.ts.map +1 -0
- package/dist/features/inapp/center/types.js +5 -0
- package/dist/features/inapp/center/types.js.map +1 -0
- package/dist/features/inapp/core/analytics.d.ts +35 -0
- package/dist/features/inapp/core/analytics.d.ts.map +1 -0
- package/dist/features/inapp/core/analytics.js +70 -0
- package/dist/features/inapp/core/analytics.js.map +1 -0
- package/dist/features/inapp/core/compat.d.ts +28 -0
- package/dist/features/inapp/core/compat.d.ts.map +1 -0
- package/dist/features/inapp/core/compat.js +104 -0
- package/dist/features/inapp/core/compat.js.map +1 -0
- package/dist/features/inapp/core/debugOverlay.d.ts +5 -0
- package/dist/features/inapp/core/debugOverlay.d.ts.map +1 -0
- package/dist/features/inapp/core/debugOverlay.js +79 -0
- package/dist/features/inapp/core/debugOverlay.js.map +1 -0
- package/dist/features/inapp/core/engine.d.ts +72 -0
- package/dist/features/inapp/core/engine.d.ts.map +1 -0
- package/dist/features/inapp/core/engine.js +248 -0
- package/dist/features/inapp/core/engine.js.map +1 -0
- package/dist/features/inapp/core/environment.d.ts +21 -0
- package/dist/features/inapp/core/environment.d.ts.map +1 -0
- package/dist/features/inapp/core/environment.js +57 -0
- package/dist/features/inapp/core/environment.js.map +1 -0
- package/dist/features/inapp/core/host.d.ts +53 -0
- package/dist/features/inapp/core/host.d.ts.map +1 -0
- package/dist/features/inapp/core/host.js +243 -0
- package/dist/features/inapp/core/host.js.map +1 -0
- package/dist/features/inapp/core/keyboard.d.ts +27 -0
- package/dist/features/inapp/core/keyboard.d.ts.map +1 -0
- package/dist/features/inapp/core/keyboard.js +69 -0
- package/dist/features/inapp/core/keyboard.js.map +1 -0
- package/dist/features/inapp/core/metrics.d.ts +73 -0
- package/dist/features/inapp/core/metrics.d.ts.map +1 -0
- package/dist/features/inapp/core/metrics.js +125 -0
- package/dist/features/inapp/core/metrics.js.map +1 -0
- package/dist/features/inapp/core/migration.d.ts +32 -0
- package/dist/features/inapp/core/migration.d.ts.map +1 -0
- package/dist/features/inapp/core/migration.js +28 -0
- package/dist/features/inapp/core/migration.js.map +1 -0
- package/dist/features/inapp/core/orchestrator.d.ts +77 -0
- package/dist/features/inapp/core/orchestrator.d.ts.map +1 -0
- package/dist/features/inapp/core/orchestrator.js +144 -0
- package/dist/features/inapp/core/orchestrator.js.map +1 -0
- package/dist/features/inapp/core/respect.d.ts +51 -0
- package/dist/features/inapp/core/respect.d.ts.map +1 -0
- package/dist/features/inapp/core/respect.js +78 -0
- package/dist/features/inapp/core/respect.js.map +1 -0
- package/dist/features/inapp/core/slots.d.ts +19 -0
- package/dist/features/inapp/core/slots.d.ts.map +1 -0
- package/dist/features/inapp/core/slots.js +53 -0
- package/dist/features/inapp/core/slots.js.map +1 -0
- package/dist/features/inapp/core/targeting.d.ts +85 -0
- package/dist/features/inapp/core/targeting.d.ts.map +1 -0
- package/dist/features/inapp/core/targeting.js +255 -0
- package/dist/features/inapp/core/targeting.js.map +1 -0
- package/dist/features/inapp/core/transport.d.ts +66 -0
- package/dist/features/inapp/core/transport.d.ts.map +1 -0
- package/dist/features/inapp/core/transport.js +154 -0
- package/dist/features/inapp/core/transport.js.map +1 -0
- package/dist/features/inapp/core/triggers.d.ts +94 -0
- package/dist/features/inapp/core/triggers.d.ts.map +1 -0
- package/dist/features/inapp/core/triggers.js +368 -0
- package/dist/features/inapp/core/triggers.js.map +1 -0
- package/dist/features/inapp/inappContract.web.d.ts +47 -0
- package/dist/features/inapp/inappContract.web.d.ts.map +1 -0
- package/dist/features/inapp/inappContract.web.js +230 -0
- package/dist/features/inapp/inappContract.web.js.map +1 -0
- package/dist/features/inapp/index.d.ts +23 -0
- package/dist/features/inapp/index.d.ts.map +1 -0
- package/dist/features/inapp/index.js +23 -0
- package/dist/features/inapp/index.js.map +1 -0
- package/dist/features/inapp/registry.canonical.hash.d.ts +7 -0
- package/dist/features/inapp/registry.canonical.hash.d.ts.map +1 -0
- package/dist/features/inapp/registry.canonical.hash.js +7 -0
- package/dist/features/inapp/registry.canonical.hash.js.map +1 -0
- package/dist/features/inapp/registry.web.canonical.d.ts +21 -0
- package/dist/features/inapp/registry.web.canonical.d.ts.map +1 -0
- package/dist/features/inapp/registry.web.canonical.js +136 -0
- package/dist/features/inapp/registry.web.canonical.js.map +1 -0
- package/dist/features/inapp/registry.web.catalog.d.ts +12 -0
- package/dist/features/inapp/registry.web.catalog.d.ts.map +1 -0
- package/dist/features/inapp/registry.web.catalog.js +208 -0
- package/dist/features/inapp/registry.web.catalog.js.map +1 -0
- package/dist/features/inapp/surfaces/banner.d.ts +7 -0
- package/dist/features/inapp/surfaces/banner.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/banner.js +30 -0
- package/dist/features/inapp/surfaces/banner.js.map +1 -0
- package/dist/features/inapp/surfaces/checklist.d.ts +13 -0
- package/dist/features/inapp/surfaces/checklist.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/checklist.js +127 -0
- package/dist/features/inapp/surfaces/checklist.js.map +1 -0
- package/dist/features/inapp/surfaces/coachmark.d.ts +10 -0
- package/dist/features/inapp/surfaces/coachmark.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/coachmark.js +95 -0
- package/dist/features/inapp/surfaces/coachmark.js.map +1 -0
- package/dist/features/inapp/surfaces/hotspot.d.ts +8 -0
- package/dist/features/inapp/surfaces/hotspot.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/hotspot.js +91 -0
- package/dist/features/inapp/surfaces/hotspot.js.map +1 -0
- package/dist/features/inapp/surfaces/inline.d.ts +13 -0
- package/dist/features/inapp/surfaces/inline.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/inline.js +78 -0
- package/dist/features/inapp/surfaces/inline.js.map +1 -0
- package/dist/features/inapp/surfaces/launcher.d.ts +9 -0
- package/dist/features/inapp/surfaces/launcher.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/launcher.js +54 -0
- package/dist/features/inapp/surfaces/launcher.js.map +1 -0
- package/dist/features/inapp/surfaces/modal.d.ts +8 -0
- package/dist/features/inapp/surfaces/modal.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/modal.js +70 -0
- package/dist/features/inapp/surfaces/modal.js.map +1 -0
- package/dist/features/inapp/surfaces/mount.d.ts +19 -0
- package/dist/features/inapp/surfaces/mount.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/mount.js +29 -0
- package/dist/features/inapp/surfaces/mount.js.map +1 -0
- package/dist/features/inapp/surfaces/palette.d.ts +9 -0
- package/dist/features/inapp/surfaces/palette.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/palette.js +127 -0
- package/dist/features/inapp/surfaces/palette.js.map +1 -0
- package/dist/features/inapp/surfaces/panel.d.ts +14 -0
- package/dist/features/inapp/surfaces/panel.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/panel.js +91 -0
- package/dist/features/inapp/surfaces/panel.js.map +1 -0
- package/dist/features/inapp/surfaces/popover.d.ts +10 -0
- package/dist/features/inapp/surfaces/popover.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/popover.js +69 -0
- package/dist/features/inapp/surfaces/popover.js.map +1 -0
- package/dist/features/inapp/surfaces/render.d.ts +34 -0
- package/dist/features/inapp/surfaces/render.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/render.js +56 -0
- package/dist/features/inapp/surfaces/render.js.map +1 -0
- package/dist/features/inapp/surfaces/slideover.d.ts +9 -0
- package/dist/features/inapp/surfaces/slideover.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/slideover.js +144 -0
- package/dist/features/inapp/surfaces/slideover.js.map +1 -0
- package/dist/features/inapp/surfaces/styles.d.ts +7 -0
- package/dist/features/inapp/surfaces/styles.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/styles.js +235 -0
- package/dist/features/inapp/surfaces/styles.js.map +1 -0
- package/dist/features/inapp/surfaces/surface.d.ts +69 -0
- package/dist/features/inapp/surfaces/surface.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/surface.js +80 -0
- package/dist/features/inapp/surfaces/surface.js.map +1 -0
- package/dist/features/inapp/surfaces/takeover.d.ts +9 -0
- package/dist/features/inapp/surfaces/takeover.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/takeover.js +60 -0
- package/dist/features/inapp/surfaces/takeover.js.map +1 -0
- package/dist/features/inapp/surfaces/toast.d.ts +7 -0
- package/dist/features/inapp/surfaces/toast.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/toast.js +48 -0
- package/dist/features/inapp/surfaces/toast.js.map +1 -0
- package/dist/features/inapp/surfaces/toolbar.d.ts +8 -0
- package/dist/features/inapp/surfaces/toolbar.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/toolbar.js +65 -0
- package/dist/features/inapp/surfaces/toolbar.js.map +1 -0
- package/dist/features/inapp/surfaces/tour.d.ts +14 -0
- package/dist/features/inapp/surfaces/tour.d.ts.map +1 -0
- package/dist/features/inapp/surfaces/tour.js +202 -0
- package/dist/features/inapp/surfaces/tour.js.map +1 -0
- package/dist/features/inapp/types.d.ts +165 -0
- package/dist/features/inapp/types.d.ts.map +1 -0
- package/dist/features/inapp/types.js +12 -0
- package/dist/features/inapp/types.js.map +1 -0
- package/dist/features/inbox/InboxFeature.d.ts +57 -0
- package/dist/features/inbox/InboxFeature.d.ts.map +1 -0
- package/dist/features/inbox/InboxFeature.js +225 -0
- package/dist/features/inbox/InboxFeature.js.map +1 -0
- package/dist/features/inbox/runtime.d.ts +67 -0
- package/dist/features/inbox/runtime.d.ts.map +1 -0
- package/dist/features/inbox/runtime.js +376 -0
- package/dist/features/inbox/runtime.js.map +1 -0
- package/dist/features/inbox/store.d.ts +37 -0
- package/dist/features/inbox/store.d.ts.map +1 -0
- package/dist/features/inbox/store.js +149 -0
- package/dist/features/inbox/store.js.map +1 -0
- package/dist/features/inbox/sync.d.ts +49 -0
- package/dist/features/inbox/sync.d.ts.map +1 -0
- package/dist/features/inbox/sync.js +131 -0
- package/dist/features/inbox/sync.js.map +1 -0
- package/dist/features/inbox/types.d.ts +275 -0
- package/dist/features/inbox/types.d.ts.map +1 -0
- package/dist/features/inbox/types.js +42 -0
- package/dist/features/inbox/types.js.map +1 -0
- package/dist/features/inbox/widget/InboxWidget.d.ts +16 -0
- package/dist/features/inbox/widget/InboxWidget.d.ts.map +1 -0
- package/dist/features/inbox/widget/InboxWidget.js +609 -0
- package/dist/features/inbox/widget/InboxWidget.js.map +1 -0
- package/dist/features/index.d.ts +21 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +2 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/journey/InteractionTracker.d.ts +87 -0
- package/dist/features/journey/InteractionTracker.d.ts.map +1 -0
- package/dist/features/journey/InteractionTracker.js +466 -0
- package/dist/features/journey/InteractionTracker.js.map +1 -0
- package/dist/features/journey/JourneyFeature.d.ts +18 -0
- package/dist/features/journey/JourneyFeature.d.ts.map +1 -0
- package/dist/features/journey/JourneyFeature.js +71 -0
- package/dist/features/journey/JourneyFeature.js.map +1 -0
- package/dist/features/journey/NavigationTracker.d.ts +16 -0
- package/dist/features/journey/NavigationTracker.d.ts.map +1 -0
- package/dist/features/journey/NavigationTracker.js +92 -0
- package/dist/features/journey/NavigationTracker.js.map +1 -0
- package/dist/features/journey/friction.d.ts +28 -0
- package/dist/features/journey/friction.d.ts.map +1 -0
- package/dist/features/journey/friction.js +64 -0
- package/dist/features/journey/friction.js.map +1 -0
- package/dist/features/journey/positionContext.d.ts +30 -0
- package/dist/features/journey/positionContext.d.ts.map +1 -0
- package/dist/features/journey/positionContext.js +116 -0
- package/dist/features/journey/positionContext.js.map +1 -0
- package/dist/features/journey/uiState.d.ts +44 -0
- package/dist/features/journey/uiState.d.ts.map +1 -0
- package/dist/features/journey/uiState.js +158 -0
- package/dist/features/journey/uiState.js.map +1 -0
- package/dist/features/manifest.d.ts +41 -0
- package/dist/features/manifest.d.ts.map +1 -0
- package/dist/features/manifest.js +93 -0
- package/dist/features/manifest.js.map +1 -0
- package/dist/features/network/NetworkFeature.d.ts +60 -0
- package/dist/features/network/NetworkFeature.d.ts.map +1 -0
- package/dist/features/network/NetworkFeature.js +260 -0
- package/dist/features/network/NetworkFeature.js.map +1 -0
- package/dist/features/network/capture/body.d.ts +31 -0
- package/dist/features/network/capture/body.d.ts.map +1 -0
- package/dist/features/network/capture/body.js +81 -0
- package/dist/features/network/capture/body.js.map +1 -0
- package/dist/features/network/classify.d.ts +21 -0
- package/dist/features/network/classify.d.ts.map +1 -0
- package/dist/features/network/classify.js +50 -0
- package/dist/features/network/classify.js.map +1 -0
- package/dist/features/network/dedup.d.ts +36 -0
- package/dist/features/network/dedup.d.ts.map +1 -0
- package/dist/features/network/dedup.js +68 -0
- package/dist/features/network/dedup.js.map +1 -0
- package/dist/features/network/fetchInterceptor.d.ts +20 -0
- package/dist/features/network/fetchInterceptor.d.ts.map +1 -0
- package/dist/features/network/fetchInterceptor.js +158 -0
- package/dist/features/network/fetchInterceptor.js.map +1 -0
- package/dist/features/network/intercept/beacon.d.ts +14 -0
- package/dist/features/network/intercept/beacon.d.ts.map +1 -0
- package/dist/features/network/intercept/beacon.js +56 -0
- package/dist/features/network/intercept/beacon.js.map +1 -0
- package/dist/features/network/intercept/sse.d.ts +16 -0
- package/dist/features/network/intercept/sse.d.ts.map +1 -0
- package/dist/features/network/intercept/sse.js +74 -0
- package/dist/features/network/intercept/sse.js.map +1 -0
- package/dist/features/network/intercept/streams.d.ts +23 -0
- package/dist/features/network/intercept/streams.d.ts.map +1 -0
- package/dist/features/network/intercept/streams.js +25 -0
- package/dist/features/network/intercept/streams.js.map +1 -0
- package/dist/features/network/intercept/websocket.d.ts +14 -0
- package/dist/features/network/intercept/websocket.d.ts.map +1 -0
- package/dist/features/network/intercept/websocket.js +97 -0
- package/dist/features/network/intercept/websocket.js.map +1 -0
- package/dist/features/network/lazy.d.ts +23 -0
- package/dist/features/network/lazy.d.ts.map +1 -0
- package/dist/features/network/lazy.js +65 -0
- package/dist/features/network/lazy.js.map +1 -0
- package/dist/features/network/normalize.d.ts +9 -0
- package/dist/features/network/normalize.d.ts.map +1 -0
- package/dist/features/network/normalize.js +49 -0
- package/dist/features/network/normalize.js.map +1 -0
- package/dist/features/network/parse/graphql.d.ts +17 -0
- package/dist/features/network/parse/graphql.d.ts.map +1 -0
- package/dist/features/network/parse/graphql.js +106 -0
- package/dist/features/network/parse/graphql.js.map +1 -0
- package/dist/features/network/parse/url.d.ts +12 -0
- package/dist/features/network/parse/url.d.ts.map +1 -0
- package/dist/features/network/parse/url.js +52 -0
- package/dist/features/network/parse/url.js.map +1 -0
- package/dist/features/network/sampler.d.ts +21 -0
- package/dist/features/network/sampler.d.ts.map +1 -0
- package/dist/features/network/sampler.js +25 -0
- package/dist/features/network/sampler.js.map +1 -0
- package/dist/features/network/size.d.ts +21 -0
- package/dist/features/network/size.d.ts.map +1 -0
- package/dist/features/network/size.js +63 -0
- package/dist/features/network/size.js.map +1 -0
- package/dist/features/network/thirdParty.d.ts +95 -0
- package/dist/features/network/thirdParty.d.ts.map +1 -0
- package/dist/features/network/thirdParty.js +126 -0
- package/dist/features/network/thirdParty.js.map +1 -0
- package/dist/features/network/timing.d.ts +41 -0
- package/dist/features/network/timing.d.ts.map +1 -0
- package/dist/features/network/timing.js +134 -0
- package/dist/features/network/timing.js.map +1 -0
- package/dist/features/network/tracing.d.ts +18 -0
- package/dist/features/network/tracing.d.ts.map +1 -0
- package/dist/features/network/tracing.js +46 -0
- package/dist/features/network/tracing.js.map +1 -0
- package/dist/features/network/types.d.ts +75 -0
- package/dist/features/network/types.d.ts.map +1 -0
- package/dist/features/network/types.js +2 -0
- package/dist/features/network/types.js.map +1 -0
- package/dist/features/network/xhrInterceptor.d.ts +12 -0
- package/dist/features/network/xhrInterceptor.d.ts.map +1 -0
- package/dist/features/network/xhrInterceptor.js +108 -0
- package/dist/features/network/xhrInterceptor.js.map +1 -0
- package/dist/features/performance/PerformanceFeature.d.ts +76 -0
- package/dist/features/performance/PerformanceFeature.d.ts.map +1 -0
- package/dist/features/performance/PerformanceFeature.js +265 -0
- package/dist/features/performance/PerformanceFeature.js.map +1 -0
- package/dist/features/performance/jankTap.d.ts +23 -0
- package/dist/features/performance/jankTap.d.ts.map +1 -0
- package/dist/features/performance/jankTap.js +20 -0
- package/dist/features/performance/jankTap.js.map +1 -0
- package/dist/features/performance/longTasks.d.ts +14 -0
- package/dist/features/performance/longTasks.d.ts.map +1 -0
- package/dist/features/performance/longTasks.js +55 -0
- package/dist/features/performance/longTasks.js.map +1 -0
- package/dist/features/performance/normalize.d.ts +15 -0
- package/dist/features/performance/normalize.d.ts.map +1 -0
- package/dist/features/performance/normalize.js +30 -0
- package/dist/features/performance/normalize.js.map +1 -0
- package/dist/features/performance/resources.d.ts +19 -0
- package/dist/features/performance/resources.d.ts.map +1 -0
- package/dist/features/performance/resources.js +78 -0
- package/dist/features/performance/resources.js.map +1 -0
- package/dist/features/performance/sampler.d.ts +10 -0
- package/dist/features/performance/sampler.d.ts.map +1 -0
- package/dist/features/performance/sampler.js +23 -0
- package/dist/features/performance/sampler.js.map +1 -0
- package/dist/features/performance/spa.d.ts +2 -0
- package/dist/features/performance/spa.d.ts.map +1 -0
- package/dist/features/performance/spa.js +40 -0
- package/dist/features/performance/spa.js.map +1 -0
- package/dist/features/performance/throttle.d.ts +21 -0
- package/dist/features/performance/throttle.d.ts.map +1 -0
- package/dist/features/performance/throttle.js +26 -0
- package/dist/features/performance/throttle.js.map +1 -0
- package/dist/features/performance/trace/context.d.ts +17 -0
- package/dist/features/performance/trace/context.d.ts.map +1 -0
- package/dist/features/performance/trace/context.js +33 -0
- package/dist/features/performance/trace/context.js.map +1 -0
- package/dist/features/performance/trace/index.d.ts +7 -0
- package/dist/features/performance/trace/index.d.ts.map +1 -0
- package/dist/features/performance/trace/index.js +6 -0
- package/dist/features/performance/trace/index.js.map +1 -0
- package/dist/features/performance/trace/pageload.d.ts +3 -0
- package/dist/features/performance/trace/pageload.d.ts.map +1 -0
- package/dist/features/performance/trace/pageload.js +34 -0
- package/dist/features/performance/trace/pageload.js.map +1 -0
- package/dist/features/performance/trace/transaction.d.ts +61 -0
- package/dist/features/performance/trace/transaction.d.ts.map +1 -0
- package/dist/features/performance/trace/transaction.js +90 -0
- package/dist/features/performance/trace/transaction.js.map +1 -0
- package/dist/features/performance/trace/types.d.ts +23 -0
- package/dist/features/performance/trace/types.d.ts.map +1 -0
- package/dist/features/performance/trace/types.js +10 -0
- package/dist/features/performance/trace/types.js.map +1 -0
- package/dist/features/performance/traces.d.ts +36 -0
- package/dist/features/performance/traces.d.ts.map +1 -0
- package/dist/features/performance/traces.js +50 -0
- package/dist/features/performance/traces.js.map +1 -0
- package/dist/features/profiler/ProfilerFeature.d.ts +28 -0
- package/dist/features/profiler/ProfilerFeature.d.ts.map +1 -0
- package/dist/features/profiler/ProfilerFeature.js +82 -0
- package/dist/features/profiler/ProfilerFeature.js.map +1 -0
- package/dist/features/profiler/capture.d.ts +8 -0
- package/dist/features/profiler/capture.d.ts.map +1 -0
- package/dist/features/profiler/capture.js +21 -0
- package/dist/features/profiler/capture.js.map +1 -0
- package/dist/features/push/PushFeature.d.ts +120 -0
- package/dist/features/push/PushFeature.d.ts.map +1 -0
- package/dist/features/push/PushFeature.js +319 -0
- package/dist/features/push/PushFeature.js.map +1 -0
- package/dist/features/push/diagnostics.d.ts +55 -0
- package/dist/features/push/diagnostics.d.ts.map +1 -0
- package/dist/features/push/diagnostics.js +383 -0
- package/dist/features/push/diagnostics.js.map +1 -0
- package/dist/features/push/pushState.d.ts +58 -0
- package/dist/features/push/pushState.d.ts.map +1 -0
- package/dist/features/push/pushState.js +75 -0
- package/dist/features/push/pushState.js.map +1 -0
- package/dist/features/push/softAsk.d.ts +68 -0
- package/dist/features/push/softAsk.d.ts.map +1 -0
- package/dist/features/push/softAsk.js +142 -0
- package/dist/features/push/softAsk.js.map +1 -0
- package/dist/features/replay/ReplayFeature.d.ts +52 -0
- package/dist/features/replay/ReplayFeature.d.ts.map +1 -0
- package/dist/features/replay/ReplayFeature.js +282 -0
- package/dist/features/replay/ReplayFeature.js.map +1 -0
- package/dist/features/replay/engine/canvas.d.ts +45 -0
- package/dist/features/replay/engine/canvas.d.ts.map +1 -0
- package/dist/features/replay/engine/canvas.js +122 -0
- package/dist/features/replay/engine/canvas.js.map +1 -0
- package/dist/features/replay/engine/crossOrigin.d.ts +23 -0
- package/dist/features/replay/engine/crossOrigin.d.ts.map +1 -0
- package/dist/features/replay/engine/crossOrigin.js +108 -0
- package/dist/features/replay/engine/crossOrigin.js.map +1 -0
- package/dist/features/replay/engine/cssom.d.ts +31 -0
- package/dist/features/replay/engine/cssom.d.ts.map +1 -0
- package/dist/features/replay/engine/cssom.js +128 -0
- package/dist/features/replay/engine/cssom.js.map +1 -0
- package/dist/features/replay/engine/iframe.d.ts +65 -0
- package/dist/features/replay/engine/iframe.d.ts.map +1 -0
- package/dist/features/replay/engine/iframe.js +186 -0
- package/dist/features/replay/engine/iframe.js.map +1 -0
- package/dist/features/replay/engine/interactions.d.ts +172 -0
- package/dist/features/replay/engine/interactions.d.ts.map +1 -0
- package/dist/features/replay/engine/interactions.js +437 -0
- package/dist/features/replay/engine/interactions.js.map +1 -0
- package/dist/features/replay/engine/mutations.d.ts +65 -0
- package/dist/features/replay/engine/mutations.d.ts.map +1 -0
- package/dist/features/replay/engine/mutations.js +304 -0
- package/dist/features/replay/engine/mutations.js.map +1 -0
- package/dist/features/replay/engine/nodeRegistry.d.ts +23 -0
- package/dist/features/replay/engine/nodeRegistry.d.ts.map +1 -0
- package/dist/features/replay/engine/nodeRegistry.js +51 -0
- package/dist/features/replay/engine/nodeRegistry.js.map +1 -0
- package/dist/features/replay/engine/player.d.ts +11 -0
- package/dist/features/replay/engine/player.d.ts.map +1 -0
- package/dist/features/replay/engine/player.js +284 -0
- package/dist/features/replay/engine/player.js.map +1 -0
- package/dist/features/replay/engine/rebuild.d.ts +8 -0
- package/dist/features/replay/engine/rebuild.d.ts.map +1 -0
- package/dist/features/replay/engine/rebuild.js +46 -0
- package/dist/features/replay/engine/rebuild.js.map +1 -0
- package/dist/features/replay/engine/replayWorker.d.ts +33 -0
- package/dist/features/replay/engine/replayWorker.d.ts.map +1 -0
- package/dist/features/replay/engine/replayWorker.js +175 -0
- package/dist/features/replay/engine/replayWorker.js.map +1 -0
- package/dist/features/replay/engine/resources.d.ts +52 -0
- package/dist/features/replay/engine/resources.d.ts.map +1 -0
- package/dist/features/replay/engine/resources.js +132 -0
- package/dist/features/replay/engine/resources.js.map +1 -0
- package/dist/features/replay/engine/snapshot.d.ts +103 -0
- package/dist/features/replay/engine/snapshot.d.ts.map +1 -0
- package/dist/features/replay/engine/snapshot.js +459 -0
- package/dist/features/replay/engine/snapshot.js.map +1 -0
- package/dist/features/replay/engine/traverse.d.ts +19 -0
- package/dist/features/replay/engine/traverse.d.ts.map +1 -0
- package/dist/features/replay/engine/traverse.js +39 -0
- package/dist/features/replay/engine/traverse.js.map +1 -0
- package/dist/features/replay/engine/types.d.ts +149 -0
- package/dist/features/replay/engine/types.d.ts.map +1 -0
- package/dist/features/replay/engine/types.js +6 -0
- package/dist/features/replay/engine/types.js.map +1 -0
- package/dist/features/replay/engine/webglPatch.d.ts +26 -0
- package/dist/features/replay/engine/webglPatch.d.ts.map +1 -0
- package/dist/features/replay/engine/webglPatch.js +83 -0
- package/dist/features/replay/engine/webglPatch.js.map +1 -0
- package/dist/features/replay/lifecycle/adaptive.d.ts +38 -0
- package/dist/features/replay/lifecycle/adaptive.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/adaptive.js +90 -0
- package/dist/features/replay/lifecycle/adaptive.js.map +1 -0
- package/dist/features/replay/lifecycle/cadence.d.ts +35 -0
- package/dist/features/replay/lifecycle/cadence.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/cadence.js +149 -0
- package/dist/features/replay/lifecycle/cadence.js.map +1 -0
- package/dist/features/replay/lifecycle/deltaBatcher.d.ts +31 -0
- package/dist/features/replay/lifecycle/deltaBatcher.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/deltaBatcher.js +32 -0
- package/dist/features/replay/lifecycle/deltaBatcher.js.map +1 -0
- package/dist/features/replay/lifecycle/deviceSignals.d.ts +35 -0
- package/dist/features/replay/lifecycle/deviceSignals.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/deviceSignals.js +61 -0
- package/dist/features/replay/lifecycle/deviceSignals.js.map +1 -0
- package/dist/features/replay/lifecycle/offloadDomFrames.d.ts +69 -0
- package/dist/features/replay/lifecycle/offloadDomFrames.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/offloadDomFrames.js +107 -0
- package/dist/features/replay/lifecycle/offloadDomFrames.js.map +1 -0
- package/dist/features/replay/lifecycle/pii.d.ts +14 -0
- package/dist/features/replay/lifecycle/pii.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/pii.js +52 -0
- package/dist/features/replay/lifecycle/pii.js.map +1 -0
- package/dist/features/replay/lifecycle/recorder.d.ts +178 -0
- package/dist/features/replay/lifecycle/recorder.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/recorder.js +644 -0
- package/dist/features/replay/lifecycle/recorder.js.map +1 -0
- package/dist/features/replay/lifecycle/sampling.d.ts +28 -0
- package/dist/features/replay/lifecycle/sampling.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/sampling.js +31 -0
- package/dist/features/replay/lifecycle/sampling.js.map +1 -0
- package/dist/features/replay/lifecycle/segmentBuffer.d.ts +75 -0
- package/dist/features/replay/lifecycle/segmentBuffer.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/segmentBuffer.js +130 -0
- package/dist/features/replay/lifecycle/segmentBuffer.js.map +1 -0
- package/dist/features/replay/lifecycle/viewContext.d.ts +7 -0
- package/dist/features/replay/lifecycle/viewContext.d.ts.map +1 -0
- package/dist/features/replay/lifecycle/viewContext.js +51 -0
- package/dist/features/replay/lifecycle/viewContext.js.map +1 -0
- package/dist/features/scroll/index.d.ts +33 -0
- package/dist/features/scroll/index.d.ts.map +1 -0
- package/dist/features/scroll/index.js +106 -0
- package/dist/features/scroll/index.js.map +1 -0
- package/dist/features/session/sessionManager.d.ts +41 -0
- package/dist/features/session/sessionManager.d.ts.map +1 -0
- package/dist/features/session/sessionManager.js +67 -0
- package/dist/features/session/sessionManager.js.map +1 -0
- package/dist/features/session/sessionStore.d.ts +137 -0
- package/dist/features/session/sessionStore.d.ts.map +1 -0
- package/dist/features/session/sessionStore.js +323 -0
- package/dist/features/session/sessionStore.js.map +1 -0
- package/dist/features/watchdog/WatchdogFeature.d.ts +23 -0
- package/dist/features/watchdog/WatchdogFeature.d.ts.map +1 -0
- package/dist/features/watchdog/WatchdogFeature.js +29 -0
- package/dist/features/watchdog/WatchdogFeature.js.map +1 -0
- package/dist/features/watchdog/collectors.d.ts +18 -0
- package/dist/features/watchdog/collectors.d.ts.map +1 -0
- package/dist/features/watchdog/collectors.js +107 -0
- package/dist/features/watchdog/collectors.js.map +1 -0
- package/dist/features/watchdog/config.d.ts +51 -0
- package/dist/features/watchdog/config.d.ts.map +1 -0
- package/dist/features/watchdog/config.js +28 -0
- package/dist/features/watchdog/config.js.map +1 -0
- package/dist/features/watchdog/engine.d.ts +22 -0
- package/dist/features/watchdog/engine.d.ts.map +1 -0
- package/dist/features/watchdog/engine.js +123 -0
- package/dist/features/watchdog/engine.js.map +1 -0
- package/dist/features/watchdog/incidents.d.ts +79 -0
- package/dist/features/watchdog/incidents.d.ts.map +1 -0
- package/dist/features/watchdog/incidents.js +204 -0
- package/dist/features/watchdog/incidents.js.map +1 -0
- package/dist/features/watchdog/rollup.d.ts +41 -0
- package/dist/features/watchdog/rollup.d.ts.map +1 -0
- package/dist/features/watchdog/rollup.js +76 -0
- package/dist/features/watchdog/rollup.js.map +1 -0
- package/dist/features/webVitals/WebVitalsFeature.d.ts +46 -0
- package/dist/features/webVitals/WebVitalsFeature.d.ts.map +1 -0
- package/dist/features/webVitals/WebVitalsFeature.js +252 -0
- package/dist/features/webVitals/WebVitalsFeature.js.map +1 -0
- package/dist/features/webVitals/attribution.d.ts +50 -0
- package/dist/features/webVitals/attribution.d.ts.map +1 -0
- package/dist/features/webVitals/attribution.js +186 -0
- package/dist/features/webVitals/attribution.js.map +1 -0
- package/dist/features/webVitals/observe.d.ts +6 -0
- package/dist/features/webVitals/observe.d.ts.map +1 -0
- package/dist/features/webVitals/observe.js +6 -0
- package/dist/features/webVitals/observe.js.map +1 -0
- package/dist/features/webVitals/vitals.d.ts +99 -0
- package/dist/features/webVitals/vitals.d.ts.map +1 -0
- package/dist/features/webVitals/vitals.js +166 -0
- package/dist/features/webVitals/vitals.js.map +1 -0
- package/dist/features/webperf/WebPerfFeature.d.ts +19 -0
- package/dist/features/webperf/WebPerfFeature.d.ts.map +1 -0
- package/dist/features/webperf/WebPerfFeature.js +48 -0
- package/dist/features/webperf/WebPerfFeature.js.map +1 -0
- package/dist/features/webperf/collectors.d.ts +3 -0
- package/dist/features/webperf/collectors.d.ts.map +1 -0
- package/dist/features/webperf/collectors.js +118 -0
- package/dist/features/webperf/collectors.js.map +1 -0
- package/dist/features/webperf/math.d.ts +12 -0
- package/dist/features/webperf/math.d.ts.map +1 -0
- package/dist/features/webperf/math.js +26 -0
- package/dist/features/webperf/math.js.map +1 -0
- package/dist/inapp.d.ts +6 -0
- package/dist/inapp.d.ts.map +1 -0
- package/dist/inapp.js +6 -0
- package/dist/inapp.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/index.d.ts +7 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/pipeline/index.d.ts +3 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +3 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/pipeline.d.ts +263 -0
- package/dist/pipeline/pipeline.d.ts.map +1 -0
- package/dist/pipeline/pipeline.js +783 -0
- package/dist/pipeline/pipeline.js.map +1 -0
- package/dist/public/ScaleBunFacade.d.ts +436 -0
- package/dist/public/ScaleBunFacade.d.ts.map +1 -0
- package/dist/public/ScaleBunFacade.js +857 -0
- package/dist/public/ScaleBunFacade.js.map +1 -0
- package/dist/public/index.d.ts +5 -0
- package/dist/public/index.d.ts.map +1 -0
- package/dist/public/index.js +4 -0
- package/dist/public/index.js.map +1 -0
- package/dist/public/typedTracker.d.ts +91 -0
- package/dist/public/typedTracker.d.ts.map +1 -0
- package/dist/public/typedTracker.js +60 -0
- package/dist/public/typedTracker.js.map +1 -0
- package/dist/scalebun-push-sw.js +236 -0
- package/dist/scalebun.min.js +717 -0
- package/dist/scalebun.min.js.map +7 -0
- package/dist/storage/idb.d.ts +16 -0
- package/dist/storage/idb.d.ts.map +1 -0
- package/dist/storage/idb.js +76 -0
- package/dist/storage/idb.js.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/transport/gzip.d.ts +2 -0
- package/dist/transport/gzip.d.ts.map +1 -0
- package/dist/transport/gzip.js +20 -0
- package/dist/transport/gzip.js.map +1 -0
- package/dist/transport/httpClient.d.ts +156 -0
- package/dist/transport/httpClient.d.ts.map +1 -0
- package/dist/transport/httpClient.js +277 -0
- package/dist/transport/httpClient.js.map +1 -0
- package/dist/transport/index.d.ts +3 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +3 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/sign.d.ts +25 -0
- package/dist/transport/sign.d.ts.map +1 -0
- package/dist/transport/sign.js +58 -0
- package/dist/transport/sign.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,783 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE pipeline — the SDK's single egress. Every feature emits Items here; this batches them into
|
|
3
|
+
* SessionEnvelopes and flushes on a timer / on page-hide. At-least-once: a failed batch is
|
|
4
|
+
* re-queued and mirrored to IndexedDB so it survives a reload.
|
|
5
|
+
*/
|
|
6
|
+
import { PersistentBuffer } from '../storage/idb.js';
|
|
7
|
+
import { now } from '../core/index.js';
|
|
8
|
+
import { Backoff, isOnline } from '../core/retry.js';
|
|
9
|
+
import { capBytes, freshOnly } from '../core/prune.js';
|
|
10
|
+
// Inlined (not imported) so the zod-laden `@scalebun/protocol` barrel — and zod itself (~12 KB gz) —
|
|
11
|
+
// stays OUT of the SDK bundle; SCHEMA_VERSION was the only runtime import that pulled it. The type
|
|
12
|
+
// annotation pins this to the contract: a protocol SCHEMA_VERSION bump fails the SDK build. The
|
|
13
|
+
// `import(...)` is type-only (erased), so it adds zero runtime weight.
|
|
14
|
+
const SCHEMA_VERSION = 1;
|
|
15
|
+
/** Replay-frame discriminators, shared by the queue-eviction and byte-cap policies so the two cannot
|
|
16
|
+
* disagree about what a keyframe is. Structural checks — the frame types live in the lazy replay
|
|
17
|
+
* chunk and must not be imported into the eager core. */
|
|
18
|
+
const isFrame = (it) => it.kind === 'frame';
|
|
19
|
+
const isKeyframe = (it) => it.frameType === 'keyframe';
|
|
20
|
+
/** Re-arm attempts for a failed session-create. Small on purpose: this covers a transient 5xx or a
|
|
21
|
+
* boot while offline, not a server that is refusing on principle. */
|
|
22
|
+
const MAX_SESSION_RETRIES = 3;
|
|
23
|
+
/**
|
|
24
|
+
* Serialized-byte budget for an unload (keepalive) batch.
|
|
25
|
+
*
|
|
26
|
+
* Fetch caps the SUM of in-flight keepalive bodies at 64 KiB per agent, so this leaves room for the
|
|
27
|
+
* envelope around the items (client/device/app/context) and for anything else the page may already
|
|
28
|
+
* have in flight. Under the cap the request is delivered; over it, it is refused outright.
|
|
29
|
+
*/
|
|
30
|
+
const KEEPALIVE_BUDGET_B = 48000;
|
|
31
|
+
/** Batches one `drain()` will send before yielding to the next tick. `maxQueueSize` (1,000) over
|
|
32
|
+
* `maxBatchSize` (50) is 20, so this empties a completely full queue and no more. */
|
|
33
|
+
const MAX_DRAIN_BATCHES = 20;
|
|
34
|
+
/** Serialized size of one item, for the keepalive budget. Falls back to a coarse, deliberately
|
|
35
|
+
* PESSIMISTIC charge when an item will not stringify, so an unmeasurable item cannot silently
|
|
36
|
+
* overrun the budget it is supposed to be constrained by. */
|
|
37
|
+
function approxItemBytes(it) {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.stringify(it).length;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return KEEPALIVE_BUDGET_B;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class Pipeline {
|
|
46
|
+
constructor(config, session, transport) {
|
|
47
|
+
this.config = config;
|
|
48
|
+
this.session = session;
|
|
49
|
+
this.transport = transport;
|
|
50
|
+
this.queue = [];
|
|
51
|
+
this.timer = null;
|
|
52
|
+
this.droppedCount = 0;
|
|
53
|
+
/**
|
|
54
|
+
* P6 — the egress ledger. `pending` and `dropped` alone could not answer the question the
|
|
55
|
+
* reliability work kept running into: recovery demonstrably WORKS (frames arrive with a capture-to-
|
|
56
|
+
* storage gap of up to 12.8 hours, which only a durable queue draining on a later visit produces)
|
|
57
|
+
* and its contribution was completely uncountable, so it could never be separated from ordinary
|
|
58
|
+
* delivery or defended when someone asked whether it was worth its bytes.
|
|
59
|
+
*
|
|
60
|
+
* `expired` is split out of `dropped` deliberately. Age-pruning a queue the app sat on for days is
|
|
61
|
+
* correct behaviour; evicting a live item because the queue overflowed is data loss. Counting both
|
|
62
|
+
* as "dropped" made a healthy reload look like a leak, which is how a real signal gets ignored.
|
|
63
|
+
*/
|
|
64
|
+
this.queuedCount = 0;
|
|
65
|
+
this.attemptedCount = 0;
|
|
66
|
+
this.retriedCount = 0;
|
|
67
|
+
this.recoveredCount = 0;
|
|
68
|
+
this.expiredCount = 0;
|
|
69
|
+
this.ackedCount = 0;
|
|
70
|
+
this.started = false;
|
|
71
|
+
// After discard() (consent denied) no-op ALL egress + persistence, so a racing fire-and-forget
|
|
72
|
+
// save() / pagehide can't re-persist denied data (drained on the next load). Reset on start().
|
|
73
|
+
this.dead = false;
|
|
74
|
+
// Lifecycle flush listeners — kept so stop()/discard() can remove them (no leak across re-init).
|
|
75
|
+
this.lifecycle = [];
|
|
76
|
+
this.buffer = new PersistentBuffer();
|
|
77
|
+
this.backoff = new Backoff();
|
|
78
|
+
/** True while a flush is awaiting the network. Prevents two flushes (timer + pagehide/keepalive)
|
|
79
|
+
* from each splicing a different batch out of the queue. Parity with the in-app transport and the
|
|
80
|
+
* RN EventTracker, which both guard; the session lane was the gap. */
|
|
81
|
+
this.flushing = false;
|
|
82
|
+
/** Resolves once the server has a session row for these items to attach to. Every flush awaits it
|
|
83
|
+
* — see start(). Pre-resolved so a flush before start() (or after stop()) is not deadlocked. */
|
|
84
|
+
this.sessionStarted = Promise.resolve();
|
|
85
|
+
/** True once session-create has actually succeeded. See `armSession()`. */
|
|
86
|
+
this.sessionOk = false;
|
|
87
|
+
/** Re-arm attempts spent. Bounded so a permanently-refusing server costs a few extra requests
|
|
88
|
+
* rather than one per flush for the life of the page. */
|
|
89
|
+
this.sessionRetries = 0;
|
|
90
|
+
/** A keyframe wanted the fast path while a batch was in flight — drain again on completion. */
|
|
91
|
+
this.keyframePending = false;
|
|
92
|
+
/** The batch currently being sent. It is NOT in `queue`, so persistence must still see it — if the
|
|
93
|
+
* page dies mid-send, that fetch is cancelled and the re-queue never runs. */
|
|
94
|
+
this.inFlight = [];
|
|
95
|
+
this.consentGranted = !config.consent?.required || config.consent?.initial === 'granted';
|
|
96
|
+
}
|
|
97
|
+
/** Open/close the consent egress gate. Opening alone does not start the flush loop (see start()). */
|
|
98
|
+
setConsentGranted(granted) {
|
|
99
|
+
this.consentGranted = granted;
|
|
100
|
+
}
|
|
101
|
+
/** Whether egress is currently allowed (consent open + not discarded). Direct-send paths that
|
|
102
|
+
* bypass emit() (e.g. reportBug) MUST honor this so they don't leak under consent denial. */
|
|
103
|
+
canEgress() {
|
|
104
|
+
return this.consentGranted && !this.dead;
|
|
105
|
+
}
|
|
106
|
+
async start() {
|
|
107
|
+
if (this.started)
|
|
108
|
+
return;
|
|
109
|
+
this.started = true;
|
|
110
|
+
this.dead = false; // re-grant after a prior discard() revives egress
|
|
111
|
+
/**
|
|
112
|
+
* Session-start is issued FIRST, and synchronously — before this method awaits anything.
|
|
113
|
+
*
|
|
114
|
+
* It used to sit after the IndexedDB drain below. That drain is an await, so a keyframe emitted
|
|
115
|
+
* during it fast-flushed against a `sessionStarted` still holding the pre-resolved default,
|
|
116
|
+
* and went out before the session existed: measured +7252ms batch, +7260ms session-create, and
|
|
117
|
+
* the server answers 200 while dropping every item of an unknown session. Assigning the gate
|
|
118
|
+
* here means there is no window in which a flush can outrun the row it needs.
|
|
119
|
+
*
|
|
120
|
+
* Ordering is also just correct on its own terms: nothing the drain recovers can be ingested
|
|
121
|
+
* until the session exists either.
|
|
122
|
+
*/
|
|
123
|
+
this.armSession();
|
|
124
|
+
// Drain anything persisted from a previous page load (at-least-once across reloads), dropping
|
|
125
|
+
// items older than the max age so a reload doesn't replay data the app sat on for days.
|
|
126
|
+
try {
|
|
127
|
+
const raw = await this.buffer.load();
|
|
128
|
+
// `[sessionId, items]` since the orphan fix; a bare array is a queue persisted by an older
|
|
129
|
+
// build, which carries no session and can only be replayed under the current one.
|
|
130
|
+
const sid = typeof raw[0] === 'string' ? raw[0] : '';
|
|
131
|
+
const prev = (sid ? raw[1] : raw) ?? [];
|
|
132
|
+
const fresh = freshOnly(prev, (it) => it.timestamp, now());
|
|
133
|
+
this.expiredCount += prev.length - fresh.length; // age-pruned, not lost — see the ledger note
|
|
134
|
+
if (fresh.length) {
|
|
135
|
+
// Recovered = survived a page load. Counted here rather than on delivery so the number means
|
|
136
|
+
// "the durable queue did its job", independent of whether the network is up right now.
|
|
137
|
+
this.recoveredCount += fresh.length;
|
|
138
|
+
if (sid && sid !== this.session.sessionId)
|
|
139
|
+
void this.drainOrphans(sid, fresh);
|
|
140
|
+
else
|
|
141
|
+
this.queue.unshift(...fresh);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
/* ignore */
|
|
146
|
+
}
|
|
147
|
+
this.timer = setInterval(() => this.autoFlush(), this.config.flushIntervalMs);
|
|
148
|
+
this.installLifecycleFlush();
|
|
149
|
+
// A keyframe captured before start() could not fast-flush (no gate yet), so do it here — the
|
|
150
|
+
// gate now exists and this is the first moment it is safe. Without this, the session that most
|
|
151
|
+
// needs the fast path (the recorder beat the pipeline) is the one that waits for the timer.
|
|
152
|
+
if (this.queue.some(isKeyframe))
|
|
153
|
+
void this.flush();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Issue session-create and hold the gate on it.
|
|
157
|
+
*
|
|
158
|
+
* Separate from `start()` because it must be RE-ISSUABLE. It ran exactly once, with its rejection
|
|
159
|
+
* swallowed by a bare `.catch(() => {})`, so a session-create that failed — offline at boot, a 5xx,
|
|
160
|
+
* a CORS misconfiguration — left a gate that resolved happily onto a session row the server did not
|
|
161
|
+
* have. Every subsequent batch was then rejected as `unknown_session`, which is retryable, so the
|
|
162
|
+
* pipeline retried the same items against a row that nothing was ever going to create. The one
|
|
163
|
+
* request that could have fixed it was the one request never sent again.
|
|
164
|
+
*
|
|
165
|
+
* `sessionOk` is what flush() reads to decide whether re-arming is worth a try; it is false both
|
|
166
|
+
* before the first attempt resolves and after a failed one.
|
|
167
|
+
*/
|
|
168
|
+
armSession() {
|
|
169
|
+
this.sessionOk = false;
|
|
170
|
+
this.sessionStarted = this.transport
|
|
171
|
+
.startSession({
|
|
172
|
+
sessionId: this.session.sessionId,
|
|
173
|
+
client: this.session.client(),
|
|
174
|
+
device: this.session.device(),
|
|
175
|
+
app: this.session.app(),
|
|
176
|
+
context: this.session.context(),
|
|
177
|
+
})
|
|
178
|
+
.then(() => {
|
|
179
|
+
this.sessionOk = true;
|
|
180
|
+
})
|
|
181
|
+
.catch(() => { });
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Open the session lane again under the SessionManager's CURRENT id, after a rotation.
|
|
185
|
+
*
|
|
186
|
+
* `start()` cannot serve here: it latches on `started` and also drains the persisted buffer, which
|
|
187
|
+
* belongs to a previous page load and not to a session that began a moment ago in this one. All a
|
|
188
|
+
* rotation needs is the row — and it genuinely needs it, because the batch endpoint answers 200
|
|
189
|
+
* while dropping every item of a session it has no row for. `unknown_session` is already the
|
|
190
|
+
* largest rejection reason in production; rotating without this would make every post-rotation
|
|
191
|
+
* item join it.
|
|
192
|
+
*
|
|
193
|
+
* The retry budget resets with the session: a create that failed for the previous id says nothing
|
|
194
|
+
* about this one.
|
|
195
|
+
*/
|
|
196
|
+
async restart() {
|
|
197
|
+
this.sessionRetries = 0;
|
|
198
|
+
this.armSession();
|
|
199
|
+
await this.sessionStarted;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Make room by dropping the OLDEST REPLAY CHAIN whole, instead of one interior delta.
|
|
203
|
+
*
|
|
204
|
+
* THE BUG THIS FIXES. This used to evict the oldest DELTA frame, reasoning that a keyframe costs
|
|
205
|
+
* more to lose and that "the player interpolates across a gap". The player does not interpolate:
|
|
206
|
+
* `applyMutations` looks the node up, finds nothing, increments `NodeRegistry.misses` and skips the
|
|
207
|
+
* operation — so the element that mutation would have created never exists, and every later
|
|
208
|
+
* reference to it misses too. One evicted delta therefore corrupts the rest of the chain, which is
|
|
209
|
+
* why 1.16% frame loss measured on production put a `Partial reconstruction` badge on 13.5% of
|
|
210
|
+
* sessions. Loss was rare; it just was not survivable.
|
|
211
|
+
*
|
|
212
|
+
* So the unit of eviction is the CHAIN, exactly as `SegmentBuffer` already does for the pre-roll:
|
|
213
|
+
* drop every frame from the head up to (not including) the next keyframe, and nothing else. What
|
|
214
|
+
* remains is either intact or is about to be — see the `shed` checkpoint in the recorder, which
|
|
215
|
+
* opens a fresh chain the moment this fires. Non-frame items are stepped over, never dropped: an
|
|
216
|
+
* event or a network record has no chain to belong to and its loss buys no room worth having.
|
|
217
|
+
*
|
|
218
|
+
* Dropping many items at once is deliberate. A single-item eviction ran again on the very next
|
|
219
|
+
* emit, so a full queue shed continuously; freeing a whole chain (bounded by the recorder's
|
|
220
|
+
* 120-frame checkpoint) means this runs once per chain rather than once per frame.
|
|
221
|
+
*/
|
|
222
|
+
evictChain() {
|
|
223
|
+
const q = this.queue;
|
|
224
|
+
let n = 0;
|
|
225
|
+
for (let i = 0; i < q.length;) {
|
|
226
|
+
const it = q[i]; // in range by the loop guard (noUncheckedIndexedAccess widens it anyway)
|
|
227
|
+
if (!isFrame(it)) {
|
|
228
|
+
i++;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (n && isKeyframe(it))
|
|
232
|
+
break; // the next chain starts here — it is intact, keep it
|
|
233
|
+
q.splice(i, 1);
|
|
234
|
+
n++;
|
|
235
|
+
}
|
|
236
|
+
if (!n) {
|
|
237
|
+
q.shift(); // no frames at all (events/perf only) — the old drop-oldest still applies
|
|
238
|
+
n = 1;
|
|
239
|
+
}
|
|
240
|
+
this.droppedCount += n;
|
|
241
|
+
}
|
|
242
|
+
emit(item) {
|
|
243
|
+
// Consent gate (belt-and-suspenders for manual facade emits): drop, don't buffer, while gated.
|
|
244
|
+
if (!this.consentGranted) {
|
|
245
|
+
this.droppedCount++;
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (this.queue.length >= this.config.maxQueueSize)
|
|
249
|
+
this.evictChain();
|
|
250
|
+
this.queuedCount++;
|
|
251
|
+
this.queue.push(item);
|
|
252
|
+
/**
|
|
253
|
+
* A KEYFRAME does not wait for the next tick.
|
|
254
|
+
*
|
|
255
|
+
* MEASURED on a live app: time from navigation to the first frame batch leaving the browser was
|
|
256
|
+
* 5920 / 5959 / 6007 ms across ten sessions — pinned to `flushIntervalMs` (5000), not to how
|
|
257
|
+
* long the snapshot took. The recorder had the keyframe within a few hundred ms; it then sat in
|
|
258
|
+
* this queue waiting for a timer. Any visitor who left inside that window lost the ENTIRE
|
|
259
|
+
* session's replay, because the keyframe is what makes every delta behind it playable.
|
|
260
|
+
*
|
|
261
|
+
* That is the shape of the production defect: of the sessions that arrived complete in every
|
|
262
|
+
* other lane with zero frames stored, 44% lasted 3-10s and 18% lasted 1-3s — i.e. they ended
|
|
263
|
+
* before the first flush tick. `pagehide` is the backstop, but it is not guaranteed to run (a
|
|
264
|
+
* backgrounded tab killed by mobile Safari never fires it), so relying on it is what left a
|
|
265
|
+
* measured 27% of sessions with no replay.
|
|
266
|
+
*
|
|
267
|
+
* Only keyframes. Deltas are small, frequent, and worthless without their base, so they keep
|
|
268
|
+
* batching normally — this costs one extra request per keyframe (~30s apart), not one per frame.
|
|
269
|
+
* `flush()` no-ops while a batch is already in flight, so a keyframe arriving mid-flush is
|
|
270
|
+
* picked up by the next drain rather than racing it.
|
|
271
|
+
*
|
|
272
|
+
* `this.started` is load-bearing, not defensive. Features install and emit before start() has
|
|
273
|
+
* run, and a fast-flush from there would race the very gate that protects it: measured, the
|
|
274
|
+
* keyframe batch left at +1768ms while session-create was issued at +1766ms and only answered at
|
|
275
|
+
* +1792ms — the flush had already begun against the pre-resolved default gate and the frames
|
|
276
|
+
* were dropped with a 200. start() sets `started` and assigns the gate in one synchronous block,
|
|
277
|
+
* so checking it here makes the ordering unconditional. A keyframe that arrives before start()
|
|
278
|
+
* is flushed by start() itself, once the gate exists.
|
|
279
|
+
*/
|
|
280
|
+
if (this.started && isKeyframe(item)) {
|
|
281
|
+
// A flush already in flight would make flush() a no-op here, and the "next drain" is the 5s
|
|
282
|
+
// timer — which a bouncing visitor never reaches. Measured: the keyframe arrived while the
|
|
283
|
+
// first batch was mid-send, the fast path was skipped, and a 3s session stored nothing.
|
|
284
|
+
if (this.flushing)
|
|
285
|
+
this.keyframePending = true;
|
|
286
|
+
else
|
|
287
|
+
void this.flush();
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Say that data was thrown away, on the one lane proven to work.
|
|
292
|
+
*
|
|
293
|
+
* A permanent rejection is real, unrecoverable data loss — an 8 MB keyframe or a closed entitlement
|
|
294
|
+
* will be refused identically forever, so the only correct action is to drop it. Dropping it
|
|
295
|
+
* SILENTLY is what made the `missing` replay bucket undiagnosable: replay produced nothing, and
|
|
296
|
+
* neither the client nor the server had anything to say about why. `dropped` alone cannot carry it
|
|
297
|
+
* either, since it already means "queue overflow".
|
|
298
|
+
*
|
|
299
|
+
* Same event name as the React Native SDK (`sdk_replay_capture_failed`), with platform-specific
|
|
300
|
+
* `reason` values, so one dashboard breakdown reads both platforms without a concept-map alias.
|
|
301
|
+
*
|
|
302
|
+
* Emitted through `emit()` on purpose: it inherits the durable queue, the consent gate and the
|
|
303
|
+
* batching that every other item gets. Latched to once per kind — see `reported`.
|
|
304
|
+
*/
|
|
305
|
+
reportDrop(kind, reason) {
|
|
306
|
+
if (!kind)
|
|
307
|
+
return;
|
|
308
|
+
this.reported ?? (this.reported = new Set());
|
|
309
|
+
if (this.reported.has(kind))
|
|
310
|
+
return;
|
|
311
|
+
this.reported.add(kind);
|
|
312
|
+
this.emit({
|
|
313
|
+
kind: 'event',
|
|
314
|
+
name: 'sdk_replay_capture_failed',
|
|
315
|
+
timestamp: now(),
|
|
316
|
+
// `props`, NOT `properties`. The wire field is `props` — `mappers.ts` reads `data: it.props`,
|
|
317
|
+
// and `EventItemSchema` is `.passthrough()`, so an unknown key is carried to the mapper and
|
|
318
|
+
// then silently dropped with no error anywhere. Sending `properties` cost this event its
|
|
319
|
+
// entire payload: every `sdk_replay_capture_failed` landed with no stage, lane or reason —
|
|
320
|
+
// the one field the whole mechanism exists to deliver. `ack.test.ts` pins the key.
|
|
321
|
+
props: { stage: 'ingest-rejected', lane: kind, reason: reason ?? 'unknown' },
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/** Persist the pending queue to IDB, trimmed to the byte budget (replay frames shed first so a
|
|
325
|
+
* few large keyframes can't blow the IndexedDB quota). */
|
|
326
|
+
persistQueue() {
|
|
327
|
+
// Include the IN-FLIGHT batch. It has been spliced out of `queue` but isn't acknowledged yet, so a
|
|
328
|
+
// snapshot of `queue` alone silently drops it: on pagehide the in-flight (non-keepalive) fetch is
|
|
329
|
+
// cancelled with the page and the re-queue in flush() never runs — the batch existed nowhere.
|
|
330
|
+
const pending = this.inFlight.length ? [...this.inFlight, ...this.queue] : this.queue;
|
|
331
|
+
// Head slot = the session these items were CAPTURED in. buildEnvelope stamps the session at FLUSH
|
|
332
|
+
// time, so without this a queue recovered on a later visit is filed under whatever session is
|
|
333
|
+
// current then — measured: 32 frames captured in one session reappeared inside the next one,
|
|
334
|
+
// truncating the first replay and interleaving foreign seq numbers into the second.
|
|
335
|
+
void this.buffer.save([
|
|
336
|
+
this.session.sessionId,
|
|
337
|
+
capBytes(pending, isFrame, isKeyframe),
|
|
338
|
+
]);
|
|
339
|
+
}
|
|
340
|
+
/** Auto (timer/reconnect-driven) flush: skip while offline or inside the backoff window so a
|
|
341
|
+
* struggling/offline server isn't hit every tick. Explicit/keepalive flushes bypass this. */
|
|
342
|
+
autoFlush() {
|
|
343
|
+
if (this.dead || !isOnline() || !this.backoff.ready(now()))
|
|
344
|
+
return;
|
|
345
|
+
void this.drain();
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Empty the queue, instead of taking one batch and waiting out the next tick.
|
|
349
|
+
*
|
|
350
|
+
* THE CEILING THIS REMOVES. `flush()` takes `maxBatchSize` items (50) and the timer fires every
|
|
351
|
+
* `flushIntervalMs` (5,000 ms), so sustained egress was pinned at TEN ITEMS PER SECOND. Capture
|
|
352
|
+
* runs above that on any active page — the DOM lane packages a frame every 100 ms, scroll and
|
|
353
|
+
* input flush every 100 ms, cursor moves every 300 ms, and clicks flush immediately. Production
|
|
354
|
+
* bears out the pressure: the current SDK records 40 frames per session at the median against the
|
|
355
|
+
* previous version's 13. A queue that fills faster than it drains reaches `maxQueueSize` and starts
|
|
356
|
+
* shedding, which is the upstream cause of most of the frame loss this lane exists to fix.
|
|
357
|
+
*
|
|
358
|
+
* Draining stops the moment the queue stops SHRINKING, so a failing or backing-off transport costs
|
|
359
|
+
* one attempt rather than a spin: `flush()` puts a failed batch back, the length does not fall, and
|
|
360
|
+
* the loop exits. `MAX_DRAIN_BATCHES` bounds the pathological case where items are emitted as fast
|
|
361
|
+
* as they are sent — the queue is capped at 1,000, so 20 batches empties a full one.
|
|
362
|
+
*
|
|
363
|
+
* NOT used for the unload path. Keepalive bodies share a single 64 KiB in-flight budget across the
|
|
364
|
+
* whole agent, so issuing several at once would fail them all; `persistAndFlush` still sends one.
|
|
365
|
+
*/
|
|
366
|
+
async drain() {
|
|
367
|
+
for (let i = 0; i < MAX_DRAIN_BATCHES && this.queue.length; i++) {
|
|
368
|
+
const before = this.queue.length;
|
|
369
|
+
await this.flush();
|
|
370
|
+
if (this.queue.length >= before)
|
|
371
|
+
return; // no progress — the transport is refusing or backing off
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Take as much of the queue as a KEEPALIVE request can actually carry.
|
|
376
|
+
*
|
|
377
|
+
* THE BUG THIS FIXES. The unload flush took `maxBatchSize` items like any other, and `httpClient`
|
|
378
|
+
* skips gzip on the keepalive path — on the stated grounds that "keepalive bodies are small". They
|
|
379
|
+
* are not: this is the same 50-item batch as a normal tick, replay keyframes included, sent as raw
|
|
380
|
+
* JSON. Fetch caps the total in-flight keepalive body at 64 KiB and returns a NETWORK ERROR past
|
|
381
|
+
* it, so an oversized unload flush did not truncate — it failed whole, and the tail of the session
|
|
382
|
+
* only ever arrived if the visitor came back in the same browser. That is the "the replay ends
|
|
383
|
+
* before the session does" report.
|
|
384
|
+
*
|
|
385
|
+
* Sizing by serialized bytes and stopping at the budget delivers what fits and leaves the rest in
|
|
386
|
+
* the queue, where `persistQueue()` — which pagehide already ran before calling us — has it safe
|
|
387
|
+
* for the next load. Partial delivery beats none.
|
|
388
|
+
*
|
|
389
|
+
* ALWAYS AT LEAST ONE ITEM, even one over budget on its own: a head item too large to fit would
|
|
390
|
+
* otherwise block the queue permanently, and sending it costs no more than the failure it replaces.
|
|
391
|
+
*
|
|
392
|
+
* Gzip is deliberately still not the answer here. `CompressionStream` is async, and awaiting it
|
|
393
|
+
* inside a pagehide handler races the document's teardown — the request would be built after the
|
|
394
|
+
* page is gone. A deterministic byte budget needs no such bet.
|
|
395
|
+
*/
|
|
396
|
+
takeKeepalive() {
|
|
397
|
+
const out = [];
|
|
398
|
+
let bytes = 0;
|
|
399
|
+
while (this.queue.length && out.length < this.config.maxBatchSize) {
|
|
400
|
+
const size = approxItemBytes(this.queue[0]);
|
|
401
|
+
if (out.length && bytes + size > KEEPALIVE_BUDGET_B)
|
|
402
|
+
break;
|
|
403
|
+
bytes += size;
|
|
404
|
+
out.push(this.queue.shift());
|
|
405
|
+
}
|
|
406
|
+
return out;
|
|
407
|
+
}
|
|
408
|
+
/** Drain a batch. On failure, re-queue (front) + persist so nothing is lost, and widen the
|
|
409
|
+
* backoff window; on success, collapse the window back to the base interval. */
|
|
410
|
+
async flush(opts) {
|
|
411
|
+
if (this.dead)
|
|
412
|
+
return; // discarded under consent denial — never send or persist
|
|
413
|
+
if (this.flushing)
|
|
414
|
+
return; // a batch is already in flight; its items are persisted, not lost
|
|
415
|
+
if (this.queue.length === 0)
|
|
416
|
+
return;
|
|
417
|
+
this.flushing = true;
|
|
418
|
+
const batch = opts?.keepalive ? this.takeKeepalive() : this.queue.splice(0, this.config.maxBatchSize);
|
|
419
|
+
this.inFlight = batch; // keep it reachable by persistQueue() until it's acknowledged
|
|
420
|
+
try {
|
|
421
|
+
// The server drops items for a session it has no row for, and answers 200 while doing it —
|
|
422
|
+
// so this await is what makes at-least-once actually hold for the first batch of a session.
|
|
423
|
+
await this.sessionStarted;
|
|
424
|
+
/**
|
|
425
|
+
* Re-arm a session that never got created, before spending the batch against a row the server
|
|
426
|
+
* does not have. Bounded — see `sessionRetries`.
|
|
427
|
+
*
|
|
428
|
+
* `this.started` is load-bearing. Before start() (and after stop()) `sessionStarted` is the
|
|
429
|
+
* pre-resolved default and `sessionOk` is false — which is not a failed session-create, it is
|
|
430
|
+
* "there is no session lane yet". Without this guard a flush from either state issues a
|
|
431
|
+
* session-create the caller never asked for, which is both wrong and exactly what the
|
|
432
|
+
* pre-resolved default exists to avoid.
|
|
433
|
+
*/
|
|
434
|
+
if (this.started && !this.sessionOk && this.sessionRetries < MAX_SESSION_RETRIES) {
|
|
435
|
+
this.sessionRetries++;
|
|
436
|
+
this.armSession();
|
|
437
|
+
await this.sessionStarted;
|
|
438
|
+
/**
|
|
439
|
+
* STILL no row: hold the batch back rather than spend it.
|
|
440
|
+
*
|
|
441
|
+
* The batch endpoint answers 200 for a session it has never heard of and drops every item in
|
|
442
|
+
* the request. Those come back as `unknown_session`, which is retryable, so nothing is lost —
|
|
443
|
+
* but the round trip is, and so is a slot in the drain loop. It is the largest rejection
|
|
444
|
+
* reason in production by a wide margin: 13,385 items in one week, 1,711 of them frames.
|
|
445
|
+
*
|
|
446
|
+
* Bounded by the SAME retry budget that guards the re-arm above, so a server that will never
|
|
447
|
+
* create the row cannot mute egress permanently — once the budget is spent, the batch goes
|
|
448
|
+
* out on the old terms and takes its chances. Requeued at the HEAD because nothing else has
|
|
449
|
+
* been sent ahead of it and order is still intact.
|
|
450
|
+
*/
|
|
451
|
+
if (!this.sessionOk) {
|
|
452
|
+
this.queue.unshift(...batch);
|
|
453
|
+
this.inFlight = [];
|
|
454
|
+
this.backoff.fail(now());
|
|
455
|
+
this.persistQueue(); // same durability as every other failure path
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
this.attemptedCount++;
|
|
460
|
+
/**
|
|
461
|
+
* DOM PAYLOADS GO STRAIGHT TO STORAGE, when the flag is on and this is not an unload.
|
|
462
|
+
*
|
|
463
|
+
* Measured on production: 154,235 of 163,644 frames stored in a 32h window are web DOM
|
|
464
|
+
* payloads that arrived inline HERE and were then PUT to object storage by the server, on
|
|
465
|
+
* the request path, at 25-70ms per round trip. Sending the bytes directly turns this
|
|
466
|
+
* envelope from a byte relay into a metadata post.
|
|
467
|
+
*
|
|
468
|
+
* ⚠ NEVER ON THE KEEPALIVE PATH. An unload flush races the document teardown, and this adds
|
|
469
|
+
* a presign round trip plus a PUT per frame before anything can be sent — the batch would
|
|
470
|
+
* lose the race and the tail of the session with it. `takeKeepalive` already exists because
|
|
471
|
+
* that boundary is unforgiving; frames leaving on pagehide go inline, as they always have.
|
|
472
|
+
*
|
|
473
|
+
* Lazily imported so the offload code stays out of the eager core, the same reason `gzip`
|
|
474
|
+
* is imported where it is used. Failure of any kind leaves every frame inline and sendable.
|
|
475
|
+
*/
|
|
476
|
+
if (this.config.replayDirectUpload && !opts?.keepalive) {
|
|
477
|
+
try {
|
|
478
|
+
const { offloadDomFrames } = await import('../features/replay/lifecycle/offloadDomFrames.js');
|
|
479
|
+
await offloadDomFrames(batch, {
|
|
480
|
+
sessionId: this.session.sessionId,
|
|
481
|
+
presign: (sid, frames) => this.transport.presignFrames(sid, frames),
|
|
482
|
+
put: (url, body, ct) => this.transport.putSigned(url, body, ct),
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
/* the offload is an optimisation; a batch must never fail because it could not run */
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
const ack = await this.transport.sendBatch(this.buildEnvelope(batch), opts);
|
|
490
|
+
if (ack) {
|
|
491
|
+
this.inFlight = [];
|
|
492
|
+
// ACKed = the server accepted these items. Set here and corrected below for the per-kind
|
|
493
|
+
// rejections, so `acked` counts what was STORED rather than what was merely 2xx'd — which is
|
|
494
|
+
// the distinction the whole per-kind receipt exists to draw.
|
|
495
|
+
this.ackedCount += batch.length;
|
|
496
|
+
/**
|
|
497
|
+
* A 2xx is NOT proof the items were stored.
|
|
498
|
+
*
|
|
499
|
+
* The backend fans the envelope out by item kind and catches each kind's failures so one bad
|
|
500
|
+
* kind cannot fail the whole batch — then answers 200 regardless. The per-kind verdict in
|
|
501
|
+
* `results` is the real receipt, and until this read it, a rejected `frame` group was cleared
|
|
502
|
+
* from the queue and from IndexedDB while the `event`/`performance` groups beside it landed:
|
|
503
|
+
* the exact fingerprint of the `missing` replay bucket.
|
|
504
|
+
*
|
|
505
|
+
* `retry` distinguishes the two rejections that need opposite handling. An unknown session
|
|
506
|
+
* becomes known as soon as `startSession` lands, so those items go back. An oversized payload
|
|
507
|
+
* or a closed entitlement will be refused identically forever, so re-queueing it would loop
|
|
508
|
+
* on the same bytes until the queue cap evicted something that WOULD have been accepted —
|
|
509
|
+
* those are dropped and counted, so `dropped` stops meaning only "queue overflow".
|
|
510
|
+
*
|
|
511
|
+
* A kind absent from the map was stored. That is what makes this safe against a backend that
|
|
512
|
+
* predates the field: no entries, nothing re-queued, behaviour identical to before.
|
|
513
|
+
*/
|
|
514
|
+
const back = [];
|
|
515
|
+
let dropped = 0;
|
|
516
|
+
for (const it of batch) {
|
|
517
|
+
const kind = it.kind ?? '';
|
|
518
|
+
const r = ack[kind];
|
|
519
|
+
if (!r || r.ok)
|
|
520
|
+
continue;
|
|
521
|
+
this.ackedCount--; // provisionally counted above; this kind was NOT stored
|
|
522
|
+
if (r.retry) {
|
|
523
|
+
back.push(it);
|
|
524
|
+
this.retriedCount++;
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
dropped++;
|
|
528
|
+
this.droppedCount++;
|
|
529
|
+
this.reportDrop(kind, r.reason);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* HOW A RETRYABLE REJECTION IS RE-QUEUED — and why it is not simply `unshift`.
|
|
534
|
+
*
|
|
535
|
+
* `unshift` + an unconditional `backoff.reset()` was an infinite loop that starved every
|
|
536
|
+
* other lane. A session whose row was never created rejects EVERY kind as retryable, so
|
|
537
|
+
* `back` came back the full width of the batch, went to the HEAD, and `flush()` — which
|
|
538
|
+
* takes `splice(0, maxBatchSize)` — selected exactly the same items on the next tick. The
|
|
539
|
+
* backoff had just been reset because the response was a 2xx, so there was no widening
|
|
540
|
+
* window either: the same 50 items re-POSTed every flush interval, forever, while items
|
|
541
|
+
* emitted behind them sat at the tail and were eventually evicted by the queue cap.
|
|
542
|
+
*
|
|
543
|
+
* So the branch turns on whether ANYTHING landed:
|
|
544
|
+
* - Something landed → the server is working and this is an ordinary partial retry. Reset
|
|
545
|
+
* the window and put the items back at the head, where they keep their place in line.
|
|
546
|
+
* - Nothing landed → a 2xx that stored none of the batch is a FAILURE for our purposes,
|
|
547
|
+
* whatever the status code said. Widen the retry window like any other failure, and
|
|
548
|
+
* re-queue at the TAIL so a lane that cannot land stops holding the head hostage. The
|
|
549
|
+
* items are not lost — they are behind the other lanes instead of in front of them.
|
|
550
|
+
*
|
|
551
|
+
* Frame order survives the tail move: the backend orders frames by `sequenceNumber`, not by
|
|
552
|
+
* arrival, and these items keep their relative order among themselves.
|
|
553
|
+
*/
|
|
554
|
+
if (back.length) {
|
|
555
|
+
if (batch.length - back.length - dropped === 0) {
|
|
556
|
+
this.backoff.fail(now());
|
|
557
|
+
this.queue.push(...back);
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
this.backoff.reset();
|
|
561
|
+
this.queue.unshift(...back);
|
|
562
|
+
}
|
|
563
|
+
this.persistQueue();
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
this.backoff.reset();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
// The request itself failed (offline, 5xx, abort). Nothing was stored, so nothing is ACKed;
|
|
571
|
+
// the whole batch goes back and counts as retried.
|
|
572
|
+
this.backoff.fail(now());
|
|
573
|
+
this.retriedCount += batch.length;
|
|
574
|
+
this.queue.unshift(...batch);
|
|
575
|
+
this.inFlight = []; // back in `queue` — persistQueue() sees it there now
|
|
576
|
+
this.persistQueue();
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
catch {
|
|
580
|
+
// A throwing transport must not swallow the batch (and must not throw into the host: every
|
|
581
|
+
// caller invokes flush() as `void flush()`, so a rejection would surface as an unhandled one).
|
|
582
|
+
this.backoff.fail(now());
|
|
583
|
+
this.retriedCount += batch.length;
|
|
584
|
+
this.queue.unshift(...batch);
|
|
585
|
+
this.inFlight = [];
|
|
586
|
+
this.persistQueue();
|
|
587
|
+
}
|
|
588
|
+
finally {
|
|
589
|
+
this.flushing = false;
|
|
590
|
+
}
|
|
591
|
+
// A keyframe that asked for the fast path mid-flush gets it now, rather than waiting out the
|
|
592
|
+
// flush interval. Cleared before recursing, so this drains once per keyframe, not in a loop.
|
|
593
|
+
if (this.keyframePending) {
|
|
594
|
+
this.keyframePending = false;
|
|
595
|
+
void this.flush(opts);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Ship a queue recovered from a PREVIOUS session under that session's own id.
|
|
600
|
+
*
|
|
601
|
+
* The transport derives the URL from `envelope.sessionId`, so overriding it is all that is needed
|
|
602
|
+
* to file the frames where they belong. Sent in its own envelope rather than merged into the
|
|
603
|
+
* current queue, because a batch may only describe one session.
|
|
604
|
+
*
|
|
605
|
+
* On failure the items are written back for one more attempt. That retry window lasts until this
|
|
606
|
+
* page's own `persistQueue()` overwrites the slot (its first page-hide or failed flush) — a single
|
|
607
|
+
* buffer entry cannot hold two sessions, and giving orphans their own key is not worth the eager
|
|
608
|
+
* bytes. Re-persisting under the ORIGINAL id, rather than folding them into the live queue, is the
|
|
609
|
+
* deliberate call: losing a few frames from a session the user already left beats interleaving
|
|
610
|
+
* foreign seq numbers into the replay of the session they are in right now.
|
|
611
|
+
*/
|
|
612
|
+
/**
|
|
613
|
+
* File a single item against another session — the same orphan lane, for a signal rather than a
|
|
614
|
+
* recovered queue. Used by crash recovery to report a dead session's death ON that session
|
|
615
|
+
* instead of on the live one. Fire-and-forget: it must never block the current session's setup.
|
|
616
|
+
*/
|
|
617
|
+
emitFor(sid, item) {
|
|
618
|
+
if (!this.consentGranted || !sid || sid === this.session.sessionId) {
|
|
619
|
+
// No session to redirect to (or consent withheld) — the caller's own fallback decides.
|
|
620
|
+
if (this.consentGranted && sid === this.session.sessionId)
|
|
621
|
+
this.emit(item);
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
void this.drainOrphans(sid, [item]);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Ship a recovered queue under the session it belongs to — IN BATCHES, not as one envelope.
|
|
628
|
+
*
|
|
629
|
+
* THE BUG THIS FIXES. This sent `items` whole, and `items` here is a queue recovered from a
|
|
630
|
+
* previous page load: up to `maxQueueSize`, a thousand items. The frame endpoint accepts 100 per
|
|
631
|
+
* request and answers `batch_too_large` past that, which the backend deliberately classifies as
|
|
632
|
+
* RETRYABLE — "the right data in a request that was too big", to be split and resent. Nothing
|
|
633
|
+
* implemented the split, so the identical oversized envelope went back to the buffer and returned
|
|
634
|
+
* on the next load to fail the same way. Measured in production over one week: 232 frame items
|
|
635
|
+
* across 2 sessions, rejected exactly this way.
|
|
636
|
+
*
|
|
637
|
+
* Chunking at `maxBatchSize` makes the split unnecessary rather than merely handled — the request
|
|
638
|
+
* is never oversized in the first place. Sequential, because these are a dead session's tail and
|
|
639
|
+
* have no claim on the live session's bandwidth.
|
|
640
|
+
*
|
|
641
|
+
* Everything not taken accumulates and is saved ONCE at the end: the orphan buffer is a single
|
|
642
|
+
* slot, so a save per chunk would leave only the last chunk's leftovers in it.
|
|
643
|
+
*/
|
|
644
|
+
async drainOrphans(sid, items) {
|
|
645
|
+
const keep = [];
|
|
646
|
+
for (let i = 0; i < items.length; i += this.config.maxBatchSize) {
|
|
647
|
+
const chunk = items.slice(i, i + this.config.maxBatchSize);
|
|
648
|
+
let ack = null;
|
|
649
|
+
try {
|
|
650
|
+
ack = await this.transport.sendBatch({ ...this.buildEnvelope(chunk), sessionId: sid });
|
|
651
|
+
}
|
|
652
|
+
catch {
|
|
653
|
+
/* treated as a failure */
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Re-persist unless the server took it, applying the SAME per-kind rule as flush(): a permanent
|
|
657
|
+
* rejection is not worth another attempt, and re-saving it here would hold the single buffer
|
|
658
|
+
* slot against a payload that can never land. `null` (request failed) still re-saves the chunk.
|
|
659
|
+
*/
|
|
660
|
+
if (!ack) {
|
|
661
|
+
// The request itself failed, so the chunks BEHIND this one were never attempted either —
|
|
662
|
+
// keeping only the current chunk would silently discard them. Take the whole remaining tail
|
|
663
|
+
// and stop; the next page load will try again.
|
|
664
|
+
keep.push(...items.slice(i));
|
|
665
|
+
break;
|
|
666
|
+
}
|
|
667
|
+
for (const it of chunk) {
|
|
668
|
+
const r = ack[it.kind ?? ''];
|
|
669
|
+
if (r && !r.ok && r.retry)
|
|
670
|
+
keep.push(it);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (keep.length)
|
|
674
|
+
void this.buffer.save([sid, keep]);
|
|
675
|
+
}
|
|
676
|
+
buildEnvelope(items) {
|
|
677
|
+
return {
|
|
678
|
+
schemaVersion: SCHEMA_VERSION,
|
|
679
|
+
sessionId: this.session.sessionId,
|
|
680
|
+
sentAt: now(),
|
|
681
|
+
client: this.session.client(),
|
|
682
|
+
device: this.session.device(),
|
|
683
|
+
app: this.session.app(),
|
|
684
|
+
context: this.session.context(),
|
|
685
|
+
items,
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
installLifecycleFlush() {
|
|
689
|
+
if (typeof document === 'undefined')
|
|
690
|
+
return;
|
|
691
|
+
const persistAndFlush = () => {
|
|
692
|
+
if (this.dead)
|
|
693
|
+
return; // denied → don't re-persist
|
|
694
|
+
this.persistQueue();
|
|
695
|
+
void this.flush({ keepalive: true });
|
|
696
|
+
};
|
|
697
|
+
const onHide = () => {
|
|
698
|
+
if (document.visibilityState === 'hidden')
|
|
699
|
+
persistAndFlush();
|
|
700
|
+
};
|
|
701
|
+
this.addLifecycle(document, 'visibilitychange', onHide);
|
|
702
|
+
if (typeof window !== 'undefined') {
|
|
703
|
+
// pagehide covers bfcache eviction / unload more reliably than 'unload'.
|
|
704
|
+
this.addLifecycle(window, 'pagehide', persistAndFlush);
|
|
705
|
+
// On reconnect: clear the backoff window and flush immediately (don't wait for the next tick).
|
|
706
|
+
this.addLifecycle(window, 'online', () => {
|
|
707
|
+
this.backoff.reset();
|
|
708
|
+
this.autoFlush();
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
addLifecycle(target, type, fn) {
|
|
713
|
+
target.addEventListener(type, fn);
|
|
714
|
+
this.lifecycle.push({ target, type, fn });
|
|
715
|
+
}
|
|
716
|
+
removeLifecycle() {
|
|
717
|
+
for (const l of this.lifecycle) {
|
|
718
|
+
try {
|
|
719
|
+
l.target.removeEventListener(l.type, l.fn);
|
|
720
|
+
}
|
|
721
|
+
catch {
|
|
722
|
+
/* ignore */
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
this.lifecycle = [];
|
|
726
|
+
}
|
|
727
|
+
async stop() {
|
|
728
|
+
if (this.timer)
|
|
729
|
+
clearInterval(this.timer);
|
|
730
|
+
this.timer = null;
|
|
731
|
+
this.removeLifecycle();
|
|
732
|
+
await this.flush({ keepalive: true });
|
|
733
|
+
await this.transport.finalize(this.session.sessionId);
|
|
734
|
+
await this.buffer.clear();
|
|
735
|
+
this.started = false;
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Drop everything without sending — for consent denial. Stops the flush loop, discards the
|
|
739
|
+
* in-memory queue, and purges the persisted buffer (including any data from a prior load). Unlike
|
|
740
|
+
* stop(), it never flushes or finalizes (no network), so nothing leaves the browser.
|
|
741
|
+
*/
|
|
742
|
+
async discard() {
|
|
743
|
+
this.dead = true; // set FIRST so any racing flush()/pagehide save() no-ops
|
|
744
|
+
this.consentGranted = false;
|
|
745
|
+
if (this.timer)
|
|
746
|
+
clearInterval(this.timer);
|
|
747
|
+
this.timer = null;
|
|
748
|
+
this.removeLifecycle();
|
|
749
|
+
this.queue = [];
|
|
750
|
+
this.started = false;
|
|
751
|
+
try {
|
|
752
|
+
await this.buffer.clear();
|
|
753
|
+
}
|
|
754
|
+
catch {
|
|
755
|
+
/* ignore */
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
get pendingCount() {
|
|
759
|
+
return this.queue.length;
|
|
760
|
+
}
|
|
761
|
+
get dropped() {
|
|
762
|
+
return this.droppedCount;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* P6 — the full egress ledger, for `ScaleBun.egressStats()`.
|
|
766
|
+
*
|
|
767
|
+
* Exposed as one object rather than seven getters so a caller reads a CONSISTENT snapshot: the
|
|
768
|
+
* counters move on network callbacks, and seven separate reads could straddle a flush and produce a
|
|
769
|
+
* set that never actually existed.
|
|
770
|
+
*/
|
|
771
|
+
get ledger() {
|
|
772
|
+
return {
|
|
773
|
+
queued: this.queuedCount,
|
|
774
|
+
attempted: this.attemptedCount,
|
|
775
|
+
retried: this.retriedCount,
|
|
776
|
+
recovered: this.recoveredCount,
|
|
777
|
+
dropped: this.droppedCount,
|
|
778
|
+
expired: this.expiredCount,
|
|
779
|
+
acked: this.ackedCount,
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
//# sourceMappingURL=pipeline.js.map
|