@v-tilt/browser 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/all-external-dependencies.js +1 -1
  2. package/dist/all-external-dependencies.js.map +1 -1
  3. package/dist/array.full.js +1 -1
  4. package/dist/array.full.js.map +1 -1
  5. package/dist/array.js +1 -1
  6. package/dist/array.js.map +1 -1
  7. package/dist/array.no-external.js +1 -1
  8. package/dist/array.no-external.js.map +1 -1
  9. package/dist/autocapture-types.d.ts +17 -0
  10. package/dist/autocapture-utils.d.ts +24 -1
  11. package/dist/autocapture.d.ts +94 -5
  12. package/dist/chat.js +1 -1
  13. package/dist/chat.js.map +1 -1
  14. package/dist/config.d.ts +8 -1
  15. package/dist/constants.d.ts +19 -13
  16. package/dist/core/capture.d.ts +15 -5
  17. package/dist/core/config-utils.d.ts +15 -0
  18. package/dist/core/consent.d.ts +62 -0
  19. package/dist/core/event-buffer.d.ts +60 -0
  20. package/dist/core/fb-cookies.d.ts +32 -0
  21. package/dist/core/feature-manager.d.ts +61 -69
  22. package/dist/core/fifo-queue.d.ts +23 -0
  23. package/dist/core/identity.d.ts +23 -33
  24. package/dist/core/index.d.ts +7 -1
  25. package/dist/core/page-lifecycle.d.ts +41 -0
  26. package/dist/core/remote-config.d.ts +14 -17
  27. package/dist/extensions/chat/bubble-drag.d.ts +30 -0
  28. package/dist/extensions/chat/chat-api.d.ts +15 -0
  29. package/dist/extensions/chat/chat-styles.d.ts +27 -0
  30. package/dist/extensions/chat/chat-wrapper.d.ts +20 -145
  31. package/dist/extensions/chat/chat.d.ts +261 -14
  32. package/dist/extensions/chat/message-content-styles.d.ts +1 -0
  33. package/dist/extensions/chat/message-html.d.ts +6 -0
  34. package/dist/extensions/chat/message-markdown.d.ts +8 -0
  35. package/dist/extensions/chat/normalize-send-content.d.ts +24 -0
  36. package/dist/extensions/chat/types.d.ts +19 -57
  37. package/dist/extensions/chat/widget-registry.d.ts +53 -0
  38. package/dist/extensions/chat/widgets/collect-email.d.ts +6 -0
  39. package/dist/extensions/chat/widgets/escalate-to-human.d.ts +6 -0
  40. package/dist/extensions/ga4-proxy.d.ts +59 -0
  41. package/dist/extensions/google-tag-gateway/consent-bridge.d.ts +27 -0
  42. package/dist/extensions/google-tag-gateway/enhanced-conversions.d.ts +35 -0
  43. package/dist/extensions/google-tag-gateway/event-bridge.d.ts +74 -0
  44. package/dist/extensions/google-tag-gateway/google-tag-gateway.d.ts +95 -0
  45. package/dist/extensions/google-tag-gateway/gtag-loader.d.ts +85 -0
  46. package/dist/extensions/google-tag-gateway/index.d.ts +7 -0
  47. package/dist/extensions/google-tag-gateway/normalize.d.ts +28 -0
  48. package/dist/extensions/google-tag-gateway/public-api.d.ts +23 -0
  49. package/dist/extensions/history-autocapture.d.ts +2 -2
  50. package/dist/extensions/replay/index.d.ts +1 -1
  51. package/dist/extensions/replay/session-recording-utils.d.ts +13 -43
  52. package/dist/extensions/replay/session-recording-wrapper.d.ts +10 -66
  53. package/dist/extensions/replay/session-recording.d.ts +53 -1
  54. package/dist/extensions/replay/types.d.ts +6 -1
  55. package/dist/extensions/web-vitals/web-vitals-manager.d.ts +14 -43
  56. package/dist/external-scripts-loader.js +1 -1
  57. package/dist/external-scripts-loader.js.map +1 -1
  58. package/dist/feature.d.ts +54 -172
  59. package/dist/main.js +1 -1
  60. package/dist/main.js.map +1 -1
  61. package/dist/module.d.ts +728 -753
  62. package/dist/module.js +1 -1
  63. package/dist/module.js.map +1 -1
  64. package/dist/module.no-external.d.ts +728 -753
  65. package/dist/module.no-external.js +1 -1
  66. package/dist/module.no-external.js.map +1 -1
  67. package/dist/rate-limiter.d.ts +0 -1
  68. package/dist/recorder.js +1 -1
  69. package/dist/recorder.js.map +1 -1
  70. package/dist/request.d.ts +34 -20
  71. package/dist/scroll-depth-tracker.d.ts +42 -0
  72. package/dist/server.d.ts +114 -0
  73. package/dist/server.js +1 -1
  74. package/dist/server.js.map +1 -1
  75. package/dist/session.d.ts +12 -0
  76. package/dist/types.d.ts +204 -9
  77. package/dist/user-manager.d.ts +26 -52
  78. package/dist/utils/base64.d.ts +30 -0
  79. package/dist/utils/bot-detection.d.ts +28 -0
  80. package/dist/utils/endpoint-url.d.ts +36 -0
  81. package/dist/utils/event-emitter.d.ts +1 -0
  82. package/dist/utils/globals.d.ts +71 -2
  83. package/dist/utils/index.d.ts +20 -5
  84. package/dist/utils/logger.d.ts +66 -0
  85. package/dist/utils/request-utils.d.ts +5 -0
  86. package/dist/utils/safewrap.d.ts +6 -1
  87. package/dist/utils/transport-health.d.ts +55 -0
  88. package/dist/vtilt.d.ts +85 -25
  89. package/dist/web-vitals.js.map +1 -1
  90. package/package.json +71 -66
@@ -102,6 +102,23 @@ export interface AutocaptureConfig {
102
102
  * @default false
103
103
  */
104
104
  capture_element_values?: boolean;
105
+ /**
106
+ * Scroll depth autocapture — two independently opt-in modes (both default off).
107
+ */
108
+ scroll_depth?: ScrollDepthConfig;
109
+ }
110
+ /**
111
+ * Scroll depth autocapture configuration.
112
+ */
113
+ export interface ScrollDepthConfig {
114
+ /** Fire `$scroll_depth` when the user crosses depth thresholds while scrolling. */
115
+ milestones?: boolean | {
116
+ thresholds?: number[];
117
+ };
118
+ /** Add max scroll depth to `$pageleave` as `$prev_pageview_scroll_depth_pct`. */
119
+ pageleave?: boolean;
120
+ /** CSS selector(s) for the scroll container; falls back to `window`. */
121
+ scroll_root_selector?: string | string[];
105
122
  }
106
123
  /**
107
124
  * Properties extracted from a DOM element
@@ -33,6 +33,10 @@ export declare function getDirectAndNestedSpanText(target: Element): string;
33
33
  export declare function getEventTarget(e: Event): Element | null;
34
34
  export declare function previousElementSibling(el: Element): Element | null;
35
35
  export declare function getParentElement(curEl: Element): Element | false;
36
+ /**
37
+ * Whether the current page URL passes autocapture url allow/ignore lists.
38
+ */
39
+ export declare function isAutocaptureUrlAllowed(autocaptureConfig: AutocaptureConfig | undefined): boolean;
36
40
  /**
37
41
  * Check whether a string value should be captured or if it may contain sensitive data
38
42
  */
@@ -76,7 +80,26 @@ export interface InputValueResult {
76
80
  */
77
81
  export declare function getInputValue(el: Element): InputValueResult | null;
78
82
  /**
79
- * Check whether a DOM event should be "captured" or if it may contain sensitive data
83
+ * Why a DOM event was rejected by `shouldCaptureDomEvent`. Surfaced through
84
+ * the rich variant `evaluateDomEventCapture` so the caller can produce a
85
+ * useful debug log instead of a silent skip.
86
+ */
87
+ export type DomEventRejectReason = "no_window" | "no_element" | "html_element" | "url_allowlist_miss" | "url_ignorelist_hit" | "dom_event_not_allowed" | "element_allowlist_miss" | "css_selector_allowlist_miss" | "css_selector_ignorelist_hit" | "tag_html" | "form_event_not_allowed" | "input_event_not_allowed" | "tag_not_capturable";
88
+ export interface DomEventEvaluation {
89
+ /** True when the event passes every filter and should be captured. */
90
+ capture: boolean;
91
+ /** Why we rejected the event. Undefined when `capture` is true. */
92
+ reason?: DomEventRejectReason;
93
+ }
94
+ /**
95
+ * Rich variant of {@link shouldCaptureDomEvent} that also returns the
96
+ * rejection reason. Use this from places that want to debug-log why an
97
+ * event was skipped (e.g. the Autocapture trace log).
98
+ */
99
+ export declare function evaluateDomEventCapture(el: Element, event: Event, autocaptureConfig?: AutocaptureConfig | undefined, captureOnAnyElement?: boolean, allowedEventTypes?: string[]): DomEventEvaluation;
100
+ /**
101
+ * Boolean wrapper around {@link evaluateDomEventCapture} kept for any
102
+ * callers that don't need the rejection reason.
80
103
  */
81
104
  export declare function shouldCaptureDomEvent(el: Element, event: Event, autocaptureConfig?: AutocaptureConfig | undefined, captureOnAnyElement?: boolean, allowedEventTypes?: string[]): boolean;
82
105
  export declare function getPropertiesFromElement(elem: Element, maskAllAttributes: boolean, maskText: boolean, elementAttributeIgnorelist: string[] | undefined): Properties;
@@ -3,10 +3,49 @@
3
3
  *
4
4
  * Automatic DOM event capture for clicks, form submissions, and input changes.
5
5
  * Privacy-first approach with element chain tracking and sensitive data filtering.
6
+ *
7
+ * Lifecycle (see docs/patterns/tracker-feature-lifecycle.md):
8
+ * - Construction: created by FeatureManager when not hard-disabled.
9
+ * - startIfEnabled: attaches DOM listeners when isEnabled becomes true.
10
+ * - stop: detaches DOM listeners. Subsequent startIfEnabled re-attaches.
11
+ * - onConfigUpdate: re-evaluates isEnabled on every config change and starts or
12
+ * stops accordingly. This is what flips autocapture on when the
13
+ * /decide endpoint returns `analytics.autocapture: true`.
14
+ *
15
+ * Enabled state precedence (highest first):
16
+ * 1. _userOverride === false → off (set by vt.stopAutocapture())
17
+ * 2. _isDisabledServerSide === true → off (set by remote autocapture_opt_out)
18
+ * 3. _userOverride === true → on (set by vt.startAutocapture())
19
+ * 4. config.autocapture truthy → on
20
+ * 5. otherwise → off
6
21
  */
7
22
  import type { VTilt } from "./vtilt";
8
- import type { VTiltConfig, RemoteConfig } from "./types";
23
+ import type { VTiltConfig } from "./types";
9
24
  import type { Feature } from "./feature";
25
+ /**
26
+ * Reasons isEnabled may evaluate to false. Surfaced by getDiagnostics() so that
27
+ * integrators can pinpoint why no `$autocapture` events are flowing.
28
+ */
29
+ export type AutocaptureDisabledReason = "user_stop_called" | "server_opt_out" | "config_autocapture_false" | "config_autocapture_undefined";
30
+ export interface AutocaptureDiagnostics {
31
+ /** Whether the feature is enabled given current config and overrides. */
32
+ isEnabled: boolean;
33
+ /** Whether DOM listeners are currently attached. */
34
+ isStarted: boolean;
35
+ /** Why the feature is disabled (if any). */
36
+ disabledReason: AutocaptureDisabledReason | null;
37
+ /** Snapshot of inputs that drove the decision. */
38
+ inputs: {
39
+ configAutocapture: unknown;
40
+ isDisabledServerSide: boolean;
41
+ userOverride: boolean | null;
42
+ elementsChainAsString: boolean;
43
+ captureCopiedText: boolean;
44
+ scrollDepthMilestones: boolean;
45
+ scrollDepthPageleave: boolean;
46
+ scrollDepthListenerAttached: boolean;
47
+ };
48
+ }
10
49
  /**
11
50
  * Autocapture class for automatic DOM event tracking.
12
51
  * Implements the Feature interface for consistent lifecycle management.
@@ -16,26 +55,76 @@ export declare class Autocapture implements Feature {
16
55
  private _instance;
17
56
  private _initialized;
18
57
  private _isDisabledServerSide;
58
+ /** Explicit user override via vt.startAutocapture() / vt.stopAutocapture(). */
59
+ private _userOverride;
19
60
  private _elementSelectors;
20
61
  private _rageclicks;
62
+ /**
63
+ * Compact-payload mode for `$autocapture`. When true (the default), the SDK
64
+ * only sends the `$elements_chain` string and omits the verbose `$elements`
65
+ * array — the array is duplicate information for the ingestion side and is
66
+ * what pushes payloads past the client size cap on apps with deep DOM
67
+ * trees / Tailwind / Material class soup. Integrators that still need
68
+ * `$elements` (legacy filters / external pipelines) can opt out with
69
+ * `vt.init({ elementsChainAsString: false })` or via `/decide`.
70
+ */
21
71
  private _elementsChainAsString;
22
- constructor(instance: VTilt);
72
+ private _cachedConfig;
73
+ private _cachedConfigSource;
74
+ /**
75
+ * Bound DOM handlers. Stored so stop() can detach them — passing the same
76
+ * function reference is required by removeEventListener().
77
+ */
78
+ private _domHandler;
79
+ private _copyHandler;
80
+ private _copyHandlerAttached;
81
+ private _scrollDepthTracker;
82
+ private _pageviewUnsubscribe;
83
+ static extractConfig(config: VTiltConfig): {
84
+ enabled: boolean;
85
+ };
86
+ constructor(instance: VTilt, _config?: {
87
+ enabled: boolean;
88
+ });
23
89
  private get _config();
24
90
  get isEnabled(): boolean;
25
91
  get isStarted(): boolean;
26
92
  startIfEnabled(): void;
27
93
  stop(): void;
28
- onConfigUpdate(_config: VTiltConfig): void;
29
- onRemoteConfig(response: RemoteConfig): void;
30
94
  /**
31
- * Update autocapture configuration (for programmatic control)
95
+ * Max scroll depth % for the current page when pageleave mode is enabled.
96
+ * Used to enrich `$pageleave` payloads.
97
+ */
98
+ getMaxScrollDepthPctForPageleave(): number | null;
99
+ onConfigUpdate(config: VTiltConfig): void;
100
+ /**
101
+ * Update autocapture configuration (for programmatic control).
102
+ * Called from vt.startAutocapture() / vt.stopAutocapture().
32
103
  */
33
104
  updateConfig(config: Partial<{
34
105
  enabled: boolean;
35
106
  }>): void;
107
+ getDiagnostics(): AutocaptureDiagnostics;
36
108
  setElementSelectors(selectors: Set<string>): void;
37
109
  getElementSelectors(element: Element | null): string[] | null;
110
+ /**
111
+ * Single-source-of-truth for whether autocapture should be active.
112
+ * Returns the disabled reason so diagnostics and logging can be precise.
113
+ */
114
+ private _evaluateEnabled;
38
115
  private _addDomEventHandlers;
116
+ private _removeDomEventHandlers;
117
+ /**
118
+ * Scroll depth listener — opt-in via `autocapture.scroll_depth` milestones and/or pageleave.
119
+ */
120
+ private _syncScrollDepthHandler;
121
+ private _teardownScrollDepth;
122
+ /**
123
+ * The copy/cut listener is opt-in via `autocapture.capture_copied_text`.
124
+ * Callable from both startIfEnabled and onConfigUpdate so toggling the flag
125
+ * mid-session correctly attaches or detaches the listener.
126
+ */
127
+ private _syncCopyHandler;
39
128
  private _captureEvent;
40
129
  private _isBrowserSupported;
41
130
  }