@v-tilt/browser 1.11.0 → 1.12.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.
- package/dist/all-external-dependencies.js +1 -1
- package/dist/all-external-dependencies.js.map +1 -1
- package/dist/array.full.js +1 -1
- package/dist/array.full.js.map +1 -1
- package/dist/array.js +1 -1
- package/dist/array.js.map +1 -1
- package/dist/array.no-external.js +1 -1
- package/dist/array.no-external.js.map +1 -1
- package/dist/autocapture-types.d.ts +17 -0
- package/dist/autocapture-utils.d.ts +24 -1
- package/dist/autocapture.d.ts +94 -5
- package/dist/chat.js +1 -1
- package/dist/chat.js.map +1 -1
- package/dist/config.d.ts +8 -1
- package/dist/constants.d.ts +19 -13
- package/dist/core/capture.d.ts +15 -5
- package/dist/core/config-utils.d.ts +15 -0
- package/dist/core/consent.d.ts +62 -0
- package/dist/core/event-buffer.d.ts +60 -0
- package/dist/core/fb-cookies.d.ts +32 -0
- package/dist/core/feature-manager.d.ts +61 -69
- package/dist/core/fifo-queue.d.ts +23 -0
- package/dist/core/identity.d.ts +23 -33
- package/dist/core/index.d.ts +7 -1
- package/dist/core/page-lifecycle.d.ts +41 -0
- package/dist/core/remote-config.d.ts +14 -17
- package/dist/extensions/chat/bubble-drag.d.ts +30 -0
- package/dist/extensions/chat/chat-api.d.ts +15 -0
- package/dist/extensions/chat/chat-styles.d.ts +27 -0
- package/dist/extensions/chat/chat-wrapper.d.ts +20 -145
- package/dist/extensions/chat/chat.d.ts +129 -12
- package/dist/extensions/chat/message-content-styles.d.ts +1 -0
- package/dist/extensions/chat/message-html.d.ts +6 -0
- package/dist/extensions/chat/message-markdown.d.ts +8 -0
- package/dist/extensions/chat/normalize-send-content.d.ts +24 -0
- package/dist/extensions/chat/types.d.ts +19 -57
- package/dist/extensions/chat/widget-registry.d.ts +53 -0
- package/dist/extensions/chat/widgets/collect-email.d.ts +6 -0
- package/dist/extensions/chat/widgets/escalate-to-human.d.ts +6 -0
- package/dist/extensions/ga4-proxy.d.ts +59 -0
- package/dist/extensions/google-tag-gateway/consent-bridge.d.ts +27 -0
- package/dist/extensions/google-tag-gateway/enhanced-conversions.d.ts +35 -0
- package/dist/extensions/google-tag-gateway/event-bridge.d.ts +74 -0
- package/dist/extensions/google-tag-gateway/google-tag-gateway.d.ts +95 -0
- package/dist/extensions/google-tag-gateway/gtag-loader.d.ts +85 -0
- package/dist/extensions/google-tag-gateway/index.d.ts +7 -0
- package/dist/extensions/google-tag-gateway/normalize.d.ts +28 -0
- package/dist/extensions/google-tag-gateway/public-api.d.ts +23 -0
- package/dist/extensions/history-autocapture.d.ts +2 -2
- package/dist/extensions/replay/index.d.ts +1 -1
- package/dist/extensions/replay/session-recording-utils.d.ts +13 -43
- package/dist/extensions/replay/session-recording-wrapper.d.ts +10 -66
- package/dist/extensions/replay/session-recording.d.ts +53 -1
- package/dist/extensions/replay/types.d.ts +6 -1
- package/dist/extensions/web-vitals/web-vitals-manager.d.ts +14 -43
- package/dist/external-scripts-loader.js +1 -1
- package/dist/external-scripts-loader.js.map +1 -1
- package/dist/feature.d.ts +54 -172
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.d.ts +728 -753
- package/dist/module.js +1 -1
- package/dist/module.js.map +1 -1
- package/dist/module.no-external.d.ts +728 -753
- package/dist/module.no-external.js +1 -1
- package/dist/module.no-external.js.map +1 -1
- package/dist/rate-limiter.d.ts +0 -1
- package/dist/recorder.js +1 -1
- package/dist/recorder.js.map +1 -1
- package/dist/request.d.ts +34 -20
- package/dist/scroll-depth-tracker.d.ts +42 -0
- package/dist/server.d.ts +114 -0
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +12 -0
- package/dist/types.d.ts +204 -9
- package/dist/user-manager.d.ts +26 -52
- package/dist/utils/base64.d.ts +30 -0
- package/dist/utils/bot-detection.d.ts +28 -0
- package/dist/utils/endpoint-url.d.ts +36 -0
- package/dist/utils/event-emitter.d.ts +1 -0
- package/dist/utils/globals.d.ts +71 -2
- package/dist/utils/index.d.ts +20 -5
- package/dist/utils/logger.d.ts +66 -0
- package/dist/utils/request-utils.d.ts +5 -0
- package/dist/utils/safewrap.d.ts +6 -1
- package/dist/utils/transport-health.d.ts +55 -0
- package/dist/vtilt.d.ts +85 -25
- package/dist/web-vitals.js.map +1 -1
- package/package.json +9 -4
package/dist/module.d.ts
CHANGED
|
@@ -6,6 +6,48 @@
|
|
|
6
6
|
*/
|
|
7
7
|
type PersonProfilesMode = "always" | "identified_only" | "never";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* First argument to `vt.sendChatMessage()` / {@link LazyLoadedChatInterface.sendMessage}.
|
|
11
|
+
*
|
|
12
|
+
* Plain strings stay plain text for backward compatibility. Use `{ markdown: '...' }`,
|
|
13
|
+
* `{ html: '...' }`, or `options.format` for rich content.
|
|
14
|
+
*/
|
|
15
|
+
type SendChatMessageContent = string | {
|
|
16
|
+
text: string;
|
|
17
|
+
} | {
|
|
18
|
+
markdown: string;
|
|
19
|
+
} | {
|
|
20
|
+
html: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Options for `vt.sendChatMessage()` / {@link LazyLoadedChatInterface.sendMessage}.
|
|
24
|
+
*/
|
|
25
|
+
interface SendChatMessageOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Target conversation: `'new'` creates a channel, a UUID selects an existing one,
|
|
28
|
+
* omit to use the active conversation (must already be in conversation view).
|
|
29
|
+
*/
|
|
30
|
+
channel?: "new" | string;
|
|
31
|
+
/**
|
|
32
|
+
* Open the widget panel before sending. Default: true. Pass `open: false` to send without opening.
|
|
33
|
+
*/
|
|
34
|
+
open?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Applies when the first argument is a plain string. Default: `text`.
|
|
37
|
+
* `markdown` and `html` use the same sanitized rendering as AI/agent messages.
|
|
38
|
+
*/
|
|
39
|
+
format?: "text" | "markdown" | "html";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Chat bubble appearance and behavior configuration
|
|
43
|
+
*/
|
|
44
|
+
interface BubbleConfig {
|
|
45
|
+
/** Allow user to drag the bubble to reposition (default: false) */
|
|
46
|
+
draggable?: boolean;
|
|
47
|
+
/** Show the bubble on load (default: true). Set to false to control via vt.chat.show() */
|
|
48
|
+
visible?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
9
51
|
/**
|
|
10
52
|
* VTilt Types
|
|
11
53
|
*
|
|
@@ -16,7 +58,11 @@ type PersonProfilesMode = "always" | "identified_only" | "never";
|
|
|
16
58
|
interface VTiltConfig {
|
|
17
59
|
/** Project identifier (required) */
|
|
18
60
|
token: string;
|
|
19
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* API host for all SDK requests (events, config, recordings, chat).
|
|
63
|
+
* Set this to your own domain when using a reverse proxy.
|
|
64
|
+
* If not set, SDK uses relative URLs (same-origin).
|
|
65
|
+
*/
|
|
20
66
|
api_host?: string;
|
|
21
67
|
/** UI host for dashboard links */
|
|
22
68
|
ui_host?: string | null;
|
|
@@ -26,10 +72,6 @@ interface VTiltConfig {
|
|
|
26
72
|
* If not set, falls back to {api_host}/dist/{script}.js
|
|
27
73
|
*/
|
|
28
74
|
script_host?: string;
|
|
29
|
-
/** Proxy domain for tracking requests */
|
|
30
|
-
proxy?: string;
|
|
31
|
-
/** Full proxy URL for tracking requests */
|
|
32
|
-
proxyUrl?: string;
|
|
33
75
|
/** Instance name (for multiple instances) */
|
|
34
76
|
name?: string;
|
|
35
77
|
/** Domain to track (auto-detected if not provided) - used in event properties */
|
|
@@ -83,8 +125,25 @@ interface VTiltConfig {
|
|
|
83
125
|
mask_all_element_attributes?: boolean;
|
|
84
126
|
/** Respect Do Not Track browser setting */
|
|
85
127
|
respect_dnt?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* When false (default), events are not sent when the browser looks like a bot
|
|
130
|
+
* (known crawler user agents, `navigator.webdriver`, or blocked CH brands).
|
|
131
|
+
* Set to true to disable bot filtering (PostHog: `opt_out_useragent_filter`).
|
|
132
|
+
*/
|
|
133
|
+
opt_out_useragent_filter?: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Extra user-agent substrings to treat as bots (case-insensitive), merged with
|
|
136
|
+
* the built-in list aligned with PostHog (PostHog: `custom_blocked_useragents`).
|
|
137
|
+
*/
|
|
138
|
+
custom_blocked_useragents?: string[];
|
|
86
139
|
/** Opt users out by default */
|
|
87
140
|
opt_out_capturing_by_default?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* When true, non-essential events are blocked until setConsent() is called.
|
|
143
|
+
* Essential events ($identify, $alias, $set) are always allowed.
|
|
144
|
+
* Use with vt.setConsent({ analytics: true, marketing: true, advertising: true }).
|
|
145
|
+
*/
|
|
146
|
+
require_consent?: boolean;
|
|
88
147
|
/** Session recording configuration */
|
|
89
148
|
session_recording?: SessionRecordingOptions;
|
|
90
149
|
/** Disable session recording (convenience flag) */
|
|
@@ -93,6 +152,46 @@ interface VTiltConfig {
|
|
|
93
152
|
chat?: ChatWidgetConfig;
|
|
94
153
|
/** Disable chat (convenience flag) */
|
|
95
154
|
disable_chat?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Google Tag Gateway feature config (merged `ga4_gtag` + `google_ads_gtag`
|
|
157
|
+
* rows). Property name is the stable SDK config key; populated from `/decide`
|
|
158
|
+
* or set for SSR/tests.
|
|
159
|
+
*/
|
|
160
|
+
google_tag?: GoogleTagClientConfig;
|
|
161
|
+
/** Disable the Google Tag Gateway feature (convenience flag) */
|
|
162
|
+
disable_google_tag?: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Console log level for SDK output prefixed with `[vTilt]`.
|
|
165
|
+
*
|
|
166
|
+
* Levels (each includes the levels above it):
|
|
167
|
+
* - 'none' — silence everything (escape hatch for shared kiosks etc.)
|
|
168
|
+
* - 'error' — SDK errors only
|
|
169
|
+
* - 'warn' — errors + warnings (default)
|
|
170
|
+
* - 'info' — + lifecycle events (init, autocapture started, replay started)
|
|
171
|
+
* - 'debug' — + per-event trace (every captured event, autocapture skips, requests)
|
|
172
|
+
*
|
|
173
|
+
* Default is 'warn' so SDK errors and warnings always surface without opt-in
|
|
174
|
+
* (matches Amplitude/PostHog/Sentry).
|
|
175
|
+
*
|
|
176
|
+
* NOT to be confused with the per-event `$debug` flag — that is a separate
|
|
177
|
+
* marker on the event payload itself, controlled by `debug: true` (below)
|
|
178
|
+
* or the `?vtilt_debug=1` URL parameter, and consumed by the Debug View in
|
|
179
|
+
* the dashboard. See the public docs for details.
|
|
180
|
+
*
|
|
181
|
+
* Setting `log_level` (or `debug: true`) at init time pins the level — it
|
|
182
|
+
* cannot be overridden by remote config / Default Configuration. Leave it
|
|
183
|
+
* unset to let project admins control verbosity from the dashboard.
|
|
184
|
+
*/
|
|
185
|
+
log_level?: "none" | "error" | "warn" | "info" | "debug";
|
|
186
|
+
/**
|
|
187
|
+
* PostHog-style shorthand: when true, equivalent to `log_level: 'debug'`.
|
|
188
|
+
* Ignored if `log_level` is also set.
|
|
189
|
+
*
|
|
190
|
+
* Setting this to true ALSO marks every captured event with `$debug: true`
|
|
191
|
+
* so the dashboard's Debug View highlights it. The `?vtilt_debug=1` URL
|
|
192
|
+
* parameter sets the event flag without raising the console log level.
|
|
193
|
+
*/
|
|
194
|
+
debug?: boolean;
|
|
96
195
|
/** Global attributes added to all events */
|
|
97
196
|
globalAttributes?: Record<string, string>;
|
|
98
197
|
/** Bootstrap data for initialization (server-side rendering) */
|
|
@@ -107,6 +206,8 @@ interface VTiltConfig {
|
|
|
107
206
|
before_send?: (event: CaptureResult) => CaptureResult | null;
|
|
108
207
|
/** Loaded callback */
|
|
109
208
|
loaded?: (vtilt: any) => void;
|
|
209
|
+
/** @internal Set by RemoteConfigManager after a fresh /decide response (or fetch failure). */
|
|
210
|
+
__remote_config_loaded?: boolean;
|
|
110
211
|
}
|
|
111
212
|
interface EventPayload {
|
|
112
213
|
[key: string]: any;
|
|
@@ -175,9 +276,13 @@ interface UserIdentity {
|
|
|
175
276
|
interface UserProperties {
|
|
176
277
|
[key: string]: any;
|
|
177
278
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
279
|
+
/** Batched identity state change — applied atomically with a single save. */
|
|
280
|
+
interface IdentityUpdate {
|
|
281
|
+
distinct_id?: string;
|
|
282
|
+
user_state?: "anonymous" | "identified";
|
|
283
|
+
device_id?: string;
|
|
284
|
+
properties_set?: Properties;
|
|
285
|
+
properties_set_once?: Properties;
|
|
181
286
|
}
|
|
182
287
|
/** Supported Web Vitals metrics */
|
|
183
288
|
type SupportedWebVitalsMetric = "LCP" | "CLS" | "FCP" | "INP" | "TTFB";
|
|
@@ -315,6 +420,16 @@ interface AutocaptureOptions {
|
|
|
315
420
|
* @default false
|
|
316
421
|
*/
|
|
317
422
|
capture_element_values?: boolean;
|
|
423
|
+
/**
|
|
424
|
+
* Scroll depth autocapture — two independently opt-in modes (both default off).
|
|
425
|
+
*/
|
|
426
|
+
scroll_depth?: {
|
|
427
|
+
milestones?: boolean | {
|
|
428
|
+
thresholds?: number[];
|
|
429
|
+
};
|
|
430
|
+
pageleave?: boolean;
|
|
431
|
+
scroll_root_selector?: string | string[];
|
|
432
|
+
};
|
|
318
433
|
}
|
|
319
434
|
/** Mask options for input elements in session recording */
|
|
320
435
|
interface SessionRecordingMaskInputOptions {
|
|
@@ -361,6 +476,11 @@ interface SessionRecordingOptions {
|
|
|
361
476
|
blockClass?: string;
|
|
362
477
|
/** Block selector for elements to hide */
|
|
363
478
|
blockSelector?: string;
|
|
479
|
+
/**
|
|
480
|
+
* When `true`, skip built-in `blockSelector` entries for common invisible
|
|
481
|
+
* template nodes (screen-reader-only, Webflow CMS placeholders, etc.).
|
|
482
|
+
*/
|
|
483
|
+
skipDefaultInvisibleBlocking?: boolean;
|
|
364
484
|
/** Ignore class for input masking (default: 'vt-ignore-input') */
|
|
365
485
|
ignoreClass?: string;
|
|
366
486
|
/** Mask text class (default: 'vt-mask') */
|
|
@@ -381,7 +501,7 @@ interface SessionRecordingOptions {
|
|
|
381
501
|
recordHeaders?: boolean;
|
|
382
502
|
/** Record body in network requests */
|
|
383
503
|
recordBody?: boolean;
|
|
384
|
-
/**
|
|
504
|
+
/** Gzip-compress the request body before sending (default: true) */
|
|
385
505
|
compressEvents?: boolean;
|
|
386
506
|
/** Internal: Mutation throttler refill rate */
|
|
387
507
|
__mutationThrottlerRefillRate?: number;
|
|
@@ -410,6 +530,104 @@ interface ChatWidgetConfig {
|
|
|
410
530
|
offlineMessage?: string;
|
|
411
531
|
/** Collect email when offline */
|
|
412
532
|
collectEmailOffline?: boolean;
|
|
533
|
+
/** Bubble appearance and behavior */
|
|
534
|
+
bubble?: BubbleConfig;
|
|
535
|
+
}
|
|
536
|
+
type GoogleConsentValue = "follow_advertising" | "follow_analytics" | "granted" | "denied";
|
|
537
|
+
interface GoogleConsentOverride {
|
|
538
|
+
ad_storage?: GoogleConsentValue;
|
|
539
|
+
ad_user_data?: GoogleConsentValue;
|
|
540
|
+
ad_personalization?: GoogleConsentValue;
|
|
541
|
+
analytics_storage?: GoogleConsentValue;
|
|
542
|
+
}
|
|
543
|
+
interface GoogleAdsConversionMapping {
|
|
544
|
+
event_name: string;
|
|
545
|
+
send_to: string;
|
|
546
|
+
value_param_path?: string;
|
|
547
|
+
currency_param_path?: string;
|
|
548
|
+
default_currency?: string;
|
|
549
|
+
send_transaction_id?: boolean;
|
|
550
|
+
transaction_id_param_path?: string;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* How gtag.js is loaded — mirrors the server-side `proxy_mode` destination
|
|
554
|
+
* setting:
|
|
555
|
+
*
|
|
556
|
+
* - `proxied` (default) — route through `api_host/gt/*`. `api_host` is the
|
|
557
|
+
* SDK-level proxy setting; self-hosted customers point it at their own
|
|
558
|
+
* domain (which must implement the `/gt/*` spec).
|
|
559
|
+
* - `direct` — no proxy; gtag.js loads straight from
|
|
560
|
+
* `https://www.googletagmanager.com/gtag/js`.
|
|
561
|
+
*/
|
|
562
|
+
type GoogleTagProxyMode = "proxied" | "direct";
|
|
563
|
+
/**
|
|
564
|
+
* Configuration for the Google Tag Gateway SDK feature. Ships under the
|
|
565
|
+
* `googleTag` key of /decide when at least one `ga4_gtag` or `google_ads_gtag` destination is
|
|
566
|
+
* enabled for the project.
|
|
567
|
+
*/
|
|
568
|
+
interface GoogleTagClientConfig {
|
|
569
|
+
destinationId: string;
|
|
570
|
+
/**
|
|
571
|
+
* Proxy mode. When absent the SDK falls back to `proxied` so older
|
|
572
|
+
* `/decide` responses and the zero-config default remain compatible.
|
|
573
|
+
*/
|
|
574
|
+
proxyMode?: GoogleTagProxyMode;
|
|
575
|
+
tagIds: string[];
|
|
576
|
+
conversions: GoogleAdsConversionMapping[];
|
|
577
|
+
enhancedConversions: boolean;
|
|
578
|
+
conversionLinker: boolean;
|
|
579
|
+
linkerDomains: string[];
|
|
580
|
+
capturePageview: boolean;
|
|
581
|
+
debugMode: boolean;
|
|
582
|
+
consentOverride?: GoogleConsentOverride;
|
|
583
|
+
/**
|
|
584
|
+
* Master switch for forwarding every `vt.capture()` event to GA4 via
|
|
585
|
+
* `gtag('event', name, params)`. Defaults to `true` when absent. When
|
|
586
|
+
* `false`, only events that match an explicit row in `eventMappings` — or
|
|
587
|
+
* an Ads `conversions` mapping — fire; everything else is left to the
|
|
588
|
+
* Google tag's own behavior (page_view, enhanced measurement, etc.).
|
|
589
|
+
*/
|
|
590
|
+
autoForward?: boolean;
|
|
591
|
+
/**
|
|
592
|
+
* Whether to fire the direct Ads conversion beacon
|
|
593
|
+
* (`gtag('event', 'conversion', {send_to: 'AW-.../...'})`) for rows in
|
|
594
|
+
* `conversions`. Defaults to `true` when absent. Turn off when GA4 is
|
|
595
|
+
* linked to Google Ads in the Ads account — in that mode the GA4 event
|
|
596
|
+
* (marked as a conversion in GA4) propagates to Ads automatically and
|
|
597
|
+
* the direct beacon would duplicate it. Has no effect when `conversions`
|
|
598
|
+
* is empty.
|
|
599
|
+
*/
|
|
600
|
+
sendAdsConversions?: boolean;
|
|
601
|
+
/**
|
|
602
|
+
* Admin-configured event renames and param remappings. Mirrors the
|
|
603
|
+
* generic `event_mappings` configured on the destination. Applied after
|
|
604
|
+
* the filter check and before firing `gtag('event', ...)`.
|
|
605
|
+
*/
|
|
606
|
+
eventMappings?: GoogleTagEventMapping[];
|
|
607
|
+
/**
|
|
608
|
+
* Admin-configured include/exclude lists. Mirrors the generic
|
|
609
|
+
* `event_filter` on the destination. Evaluated before any mapping.
|
|
610
|
+
*/
|
|
611
|
+
eventFilter?: {
|
|
612
|
+
include?: string[];
|
|
613
|
+
exclude?: string[];
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Rename an event and optionally remap payload paths to gtag param paths.
|
|
618
|
+
* Structurally identical to the server-side `EventMapping` type but lives
|
|
619
|
+
* in the browser package to avoid cross-package imports. Source paths use
|
|
620
|
+
* dotted notation into the captured payload (e.g. `order.total`); dest
|
|
621
|
+
* paths use dotted notation into the outgoing gtag `params` object.
|
|
622
|
+
*/
|
|
623
|
+
interface GoogleTagEventMapping {
|
|
624
|
+
source: string;
|
|
625
|
+
destination: string;
|
|
626
|
+
param_mappings?: GoogleTagParamMapping[];
|
|
627
|
+
}
|
|
628
|
+
interface GoogleTagParamMapping {
|
|
629
|
+
source: string;
|
|
630
|
+
destination: string;
|
|
413
631
|
}
|
|
414
632
|
interface RemoteConfig {
|
|
415
633
|
sessionRecording?: {
|
|
@@ -431,6 +649,8 @@ interface RemoteConfig {
|
|
|
431
649
|
enabled?: boolean;
|
|
432
650
|
widgetPosition?: "bottom-right" | "bottom-left";
|
|
433
651
|
widgetColor?: string;
|
|
652
|
+
bubbleDraggable?: boolean;
|
|
653
|
+
bubbleVisible?: boolean;
|
|
434
654
|
};
|
|
435
655
|
chatTracking?: {
|
|
436
656
|
trackUserMessages?: boolean;
|
|
@@ -441,17 +661,33 @@ interface RemoteConfig {
|
|
|
441
661
|
capturePageleave?: boolean;
|
|
442
662
|
capturePerformance?: boolean;
|
|
443
663
|
autocapture?: boolean;
|
|
664
|
+
scrollDepthMilestones?: boolean;
|
|
665
|
+
scrollDepthPageleave?: boolean;
|
|
444
666
|
};
|
|
445
667
|
privacy?: {
|
|
446
668
|
respectDnt?: boolean;
|
|
447
669
|
requireConsent?: boolean;
|
|
448
670
|
ipAnonymization?: boolean;
|
|
449
671
|
};
|
|
672
|
+
/**
|
|
673
|
+
* Diagnostics — runtime-tunable console verbosity. Applied by the SDK only
|
|
674
|
+
* when the integrator did NOT pass `log_level` / `debug` to `vt.init()`.
|
|
675
|
+
* Set from the dashboard's Default Configuration → Diagnostics tab.
|
|
676
|
+
*/
|
|
677
|
+
diagnostics?: {
|
|
678
|
+
defaultLogLevel?: "none" | "error" | "warn" | "info" | "debug";
|
|
679
|
+
};
|
|
450
680
|
featureFlags?: FeatureFlagsConfig;
|
|
451
681
|
/** Whether to send elements as chain string (PostHog compatibility) */
|
|
452
682
|
elementsChainAsString?: boolean;
|
|
453
683
|
/** Server-side autocapture opt-out */
|
|
454
684
|
autocapture_opt_out?: boolean;
|
|
685
|
+
/**
|
|
686
|
+
* Google Tag Gateway config (absent when no client Google gtag destination is
|
|
687
|
+
* enabled for the project). Drives the gtag.js proxy loader, Consent Mode
|
|
688
|
+
* v2 bridge, and event → conversion mappings.
|
|
689
|
+
*/
|
|
690
|
+
googleTag?: GoogleTagClientConfig;
|
|
455
691
|
}
|
|
456
692
|
|
|
457
693
|
/**
|
|
@@ -466,7 +702,13 @@ interface RemoteConfig {
|
|
|
466
702
|
declare class SessionManager {
|
|
467
703
|
private storage;
|
|
468
704
|
private _windowId;
|
|
705
|
+
private _isNewSession;
|
|
469
706
|
constructor(storageMethod?: PersistenceMethod, cross_subdomain?: boolean);
|
|
707
|
+
/**
|
|
708
|
+
* Hydrate window ID from sessionStorage.
|
|
709
|
+
* Called by VTilt._boot() once the browser environment is ready.
|
|
710
|
+
*/
|
|
711
|
+
hydrateFromStorage(): void;
|
|
470
712
|
/**
|
|
471
713
|
* Get session ID (always returns a value, generates if needed)
|
|
472
714
|
*/
|
|
@@ -480,6 +722,12 @@ declare class SessionManager {
|
|
|
480
722
|
* Reset session ID (generates new session on reset)
|
|
481
723
|
*/
|
|
482
724
|
resetSessionId(): void;
|
|
725
|
+
/**
|
|
726
|
+
* Returns true if the current session was just started (new session ID generated
|
|
727
|
+
* because the session cookie expired or didn't exist). Resets after first call.
|
|
728
|
+
* Matches GA4's _ss=1 semantics.
|
|
729
|
+
*/
|
|
730
|
+
consumeSessionStart(): boolean;
|
|
483
731
|
/**
|
|
484
732
|
* Get session ID from storage (raw, can return null)
|
|
485
733
|
* Cookie Max-Age handles expiration automatically
|
|
@@ -537,8 +785,22 @@ declare class SessionManager {
|
|
|
537
785
|
declare class UserManager {
|
|
538
786
|
private storage;
|
|
539
787
|
private userIdentity;
|
|
540
|
-
private
|
|
788
|
+
private _isFirstVisit;
|
|
541
789
|
constructor(storageMethod?: PersistenceMethod, cross_subdomain?: boolean);
|
|
790
|
+
/**
|
|
791
|
+
* Hydrate identity from persistent storage.
|
|
792
|
+
*
|
|
793
|
+
* Called by VTilt._boot() once the browser environment is guaranteed ready
|
|
794
|
+
* (DOMContentLoaded). This is the only code path that reads from
|
|
795
|
+
* localStorage / cookies. If storage is empty (first visit), the generated
|
|
796
|
+
* IDs are persisted so they survive the next page load.
|
|
797
|
+
*/
|
|
798
|
+
hydrateFromStorage(): void;
|
|
799
|
+
/**
|
|
800
|
+
* Generate an ephemeral in-memory identity with no storage access.
|
|
801
|
+
* Used by the constructor so the SDK is safe to instantiate in SSR.
|
|
802
|
+
*/
|
|
803
|
+
private generateEphemeralIdentity;
|
|
542
804
|
/**
|
|
543
805
|
* Get current user identity
|
|
544
806
|
*/
|
|
@@ -568,42 +830,20 @@ declare class UserManager {
|
|
|
568
830
|
*/
|
|
569
831
|
getUserState(): "anonymous" | "identified";
|
|
570
832
|
/**
|
|
571
|
-
*
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Set user properties without changing distinct ID
|
|
833
|
+
* Returns true if this is the user's first visit (no prior anonymous_id
|
|
834
|
+
* in storage when the SDK booted). Resets after first call.
|
|
835
|
+
* Matches GA4's _fv=1 semantics.
|
|
576
836
|
*/
|
|
577
|
-
|
|
837
|
+
consumeFirstVisit(): boolean;
|
|
578
838
|
/**
|
|
579
|
-
*
|
|
580
|
-
*
|
|
839
|
+
* Apply batched identity changes with a single save.
|
|
840
|
+
* Replaces individual setters to avoid multiple storage writes per operation.
|
|
581
841
|
*/
|
|
582
|
-
|
|
842
|
+
applyUpdate(update: IdentityUpdate): void;
|
|
583
843
|
/**
|
|
584
|
-
*
|
|
844
|
+
* Reset identity to anonymous state. Generates new IDs and clears user data.
|
|
585
845
|
*/
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Update user state (internal use - for VTilt)
|
|
589
|
-
*/
|
|
590
|
-
setUserState(state: "anonymous" | "identified"): void;
|
|
591
|
-
/**
|
|
592
|
-
* Update user properties (internal use - for VTilt)
|
|
593
|
-
*/
|
|
594
|
-
updateUserProperties(userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
595
|
-
/**
|
|
596
|
-
* Set device ID if not already set (internal use - for VTilt)
|
|
597
|
-
*/
|
|
598
|
-
ensureDeviceId(deviceId: string): void;
|
|
599
|
-
/**
|
|
600
|
-
* Create an alias to link two distinct IDs
|
|
601
|
-
*/
|
|
602
|
-
createAlias(alias: string, original?: string): AliasEvent | null;
|
|
603
|
-
/**
|
|
604
|
-
* Check if distinct ID is string-like (hardcoded string) - public for validation
|
|
605
|
-
*/
|
|
606
|
-
isDistinctIdStringLikePublic(distinctId: string): boolean;
|
|
846
|
+
reset(resetDeviceId?: boolean): void;
|
|
607
847
|
/**
|
|
608
848
|
* Set initial person info
|
|
609
849
|
*/
|
|
@@ -650,275 +890,95 @@ declare class UserManager {
|
|
|
650
890
|
* Register a value once (only if not already set)
|
|
651
891
|
*/
|
|
652
892
|
private register_once;
|
|
653
|
-
/**
|
|
654
|
-
* Generate a new anonymous ID
|
|
655
|
-
*/
|
|
656
893
|
private generateAnonymousId;
|
|
657
|
-
/**
|
|
658
|
-
* Generate a new device ID
|
|
659
|
-
*/
|
|
660
894
|
private generateDeviceId;
|
|
661
895
|
/**
|
|
662
|
-
*
|
|
663
|
-
*/
|
|
664
|
-
private getPersonPropertiesHash;
|
|
665
|
-
/**
|
|
666
|
-
* Validate distinct ID
|
|
667
|
-
*/
|
|
668
|
-
private isValidDistinctId;
|
|
669
|
-
/**
|
|
670
|
-
* Check if distinct ID is string-like (hardcoded string)
|
|
671
|
-
*/
|
|
672
|
-
private isDistinctIdStringLike;
|
|
673
|
-
/**
|
|
674
|
-
* Update storage method at runtime
|
|
896
|
+
* Update storage method at runtime.
|
|
675
897
|
*/
|
|
676
898
|
updateStorageMethod(method: PersistenceMethod, cross_subdomain?: boolean): void;
|
|
677
899
|
}
|
|
678
900
|
|
|
679
901
|
/**
|
|
680
|
-
* Feature Interface & Base
|
|
902
|
+
* Feature Interface & Base Classes
|
|
681
903
|
*
|
|
682
|
-
* Standard
|
|
683
|
-
* Provides consistent lifecycle management and self-contained configuration.
|
|
904
|
+
* Standard interfaces and abstract base classes for vTilt SDK features.
|
|
684
905
|
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
689
|
-
*
|
|
906
|
+
* Hierarchy:
|
|
907
|
+
* Feature (interface) — eager features (Autocapture, HistoryAutocapture)
|
|
908
|
+
* ToggleableFeature (interface)— features that actively stop when disabled
|
|
909
|
+
* LazyFeature (abstract) — lazy-loaded features (WebVitals, Chat)
|
|
910
|
+
* ToggleableLazyFeature — lazy-loaded + toggle (SessionRecording)
|
|
690
911
|
*
|
|
691
|
-
*
|
|
912
|
+
* @see docs/patterns/tracker-feature-lifecycle.md
|
|
692
913
|
*/
|
|
693
914
|
|
|
694
915
|
/**
|
|
695
916
|
* Feature interface that all vTilt features should implement.
|
|
696
917
|
* Provides a consistent lifecycle for feature initialization and management.
|
|
697
|
-
*
|
|
698
|
-
* @example
|
|
699
|
-
* ```typescript
|
|
700
|
-
* class MyFeature implements Feature {
|
|
701
|
-
* static extractConfig(config: VTiltConfig): MyFeatureConfig {
|
|
702
|
-
* return { enabled: !!config.myFeature };
|
|
703
|
-
* }
|
|
704
|
-
*
|
|
705
|
-
* get isEnabled(): boolean { return this._config.enabled; }
|
|
706
|
-
* get isStarted(): boolean { return this._started; }
|
|
707
|
-
*
|
|
708
|
-
* startIfEnabled(): void {
|
|
709
|
-
* if (this.isEnabled && !this._started) {
|
|
710
|
-
* this._start();
|
|
711
|
-
* }
|
|
712
|
-
* }
|
|
713
|
-
*
|
|
714
|
-
* stop(): void {
|
|
715
|
-
* if (this._started) {
|
|
716
|
-
* this._cleanup();
|
|
717
|
-
* this._started = false;
|
|
718
|
-
* }
|
|
719
|
-
* }
|
|
720
|
-
* }
|
|
721
|
-
* ```
|
|
722
918
|
*/
|
|
723
919
|
interface Feature {
|
|
724
|
-
/**
|
|
725
|
-
* Feature name for logging and debugging.
|
|
726
|
-
*/
|
|
727
920
|
readonly name: string;
|
|
728
|
-
/**
|
|
729
|
-
* Check if the feature is enabled based on current configuration.
|
|
730
|
-
* Features should check both local config and remote config.
|
|
731
|
-
*/
|
|
732
921
|
readonly isEnabled: boolean;
|
|
733
|
-
/**
|
|
734
|
-
* Check if the feature is currently started/active.
|
|
735
|
-
*/
|
|
736
922
|
readonly isStarted: boolean;
|
|
737
|
-
/**
|
|
738
|
-
* Start the feature if it's enabled, otherwise do nothing.
|
|
739
|
-
* This is the primary lifecycle method called during initialization.
|
|
740
|
-
*
|
|
741
|
-
* Safe to call multiple times - should be idempotent.
|
|
742
|
-
*/
|
|
743
923
|
startIfEnabled(): void;
|
|
744
|
-
/**
|
|
745
|
-
* Stop the feature and clean up any resources (event listeners, timers, etc.).
|
|
746
|
-
* Safe to call multiple times - should be idempotent.
|
|
747
|
-
*/
|
|
748
924
|
stop(): void;
|
|
749
925
|
/**
|
|
750
926
|
* Handle VTilt configuration updates.
|
|
751
927
|
* Called when the main VTilt config is updated via updateConfig().
|
|
752
|
-
*
|
|
753
928
|
* Features should re-evaluate their enabled state and start/stop accordingly.
|
|
754
|
-
*
|
|
755
|
-
* @param config - The new VTilt configuration
|
|
756
929
|
*/
|
|
757
930
|
onConfigUpdate?(config: VTiltConfig): void;
|
|
758
|
-
/**
|
|
759
|
-
* Handle remote configuration updates from /decide endpoint.
|
|
760
|
-
* Called when new remote config is received from the server.
|
|
761
|
-
*
|
|
762
|
-
* Features can use this to enable/disable themselves based on server settings.
|
|
763
|
-
*
|
|
764
|
-
* @param remoteConfig - The remote configuration response
|
|
765
|
-
*/
|
|
766
|
-
onRemoteConfig?(remoteConfig: RemoteConfig): void;
|
|
767
931
|
}
|
|
768
|
-
/**
|
|
769
|
-
* Feature with the startIfEnabledOrStop pattern.
|
|
770
|
-
* Used for features that should stop when disabled (not just stay stopped).
|
|
771
|
-
*
|
|
772
|
-
* Example: Session recording should stop if disabled mid-session.
|
|
773
|
-
*/
|
|
774
|
-
interface ToggleableFeature extends Feature {
|
|
775
|
-
/**
|
|
776
|
-
* Start the feature if enabled, or stop it if disabled.
|
|
777
|
-
* More aggressive than startIfEnabled - actively stops if conditions change.
|
|
778
|
-
*
|
|
779
|
-
* @param trigger - Optional trigger name for debugging
|
|
780
|
-
*/
|
|
781
|
-
startIfEnabledOrStop(trigger?: string): void;
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Base configuration that all features receive.
|
|
785
|
-
* Features extend this for their specific config needs.
|
|
786
|
-
*/
|
|
787
932
|
interface FeatureConfig {
|
|
788
|
-
/** Whether the feature is enabled */
|
|
789
933
|
enabled?: boolean;
|
|
790
934
|
}
|
|
791
935
|
|
|
792
936
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
* Captures Core Web Vitals (LCP, CLS, FCP, INP, TTFB) and sends them
|
|
796
|
-
* as batched $web_vitals events. Implements the Feature interface for
|
|
797
|
-
* consistent lifecycle management.
|
|
798
|
-
*
|
|
799
|
-
* Follows PostHog's approach with:
|
|
800
|
-
* 1. Extension pattern - checks for callbacks registered on __VTiltExtensions__
|
|
801
|
-
* 2. Lazy loading - loads web-vitals.js on demand if not bundled
|
|
802
|
-
* 3. Configurable metrics - choose which metrics to capture
|
|
803
|
-
* 4. Smart buffering - collects metrics per page, flushes on navigation or timeout
|
|
804
|
-
* 5. Session context - includes session_id and window_id for correlation
|
|
937
|
+
* Autocapture
|
|
805
938
|
*
|
|
806
|
-
*
|
|
807
|
-
* -
|
|
808
|
-
* - properties:
|
|
809
|
-
* - $web_vitals_LCP_value: number
|
|
810
|
-
* - $web_vitals_LCP_event: { name, value, delta, rating, ... }
|
|
811
|
-
* - $pathname: string
|
|
812
|
-
* - $current_url: string
|
|
813
|
-
*/
|
|
814
|
-
|
|
815
|
-
declare class WebVitalsManager implements Feature {
|
|
816
|
-
readonly name = "WebVitals";
|
|
817
|
-
private _instance;
|
|
818
|
-
private _buffer;
|
|
819
|
-
private _flushTimer;
|
|
820
|
-
private _isStarted;
|
|
821
|
-
private _config;
|
|
822
|
-
/**
|
|
823
|
-
* Extract web vitals config from VTiltConfig (self-contained)
|
|
824
|
-
*/
|
|
825
|
-
static extractConfig(config: VTiltConfig): CapturePerformanceConfig;
|
|
826
|
-
constructor(instance: VTilt);
|
|
827
|
-
/**
|
|
828
|
-
* Check if web vitals capture is enabled
|
|
829
|
-
*/
|
|
830
|
-
get isEnabled(): boolean;
|
|
831
|
-
/**
|
|
832
|
-
* Check if capturing has started
|
|
833
|
-
*/
|
|
834
|
-
get isStarted(): boolean;
|
|
835
|
-
/**
|
|
836
|
-
* Start capturing if enabled
|
|
837
|
-
*/
|
|
838
|
-
startIfEnabled(): void;
|
|
839
|
-
/**
|
|
840
|
-
* Stop capturing (flushes any pending metrics)
|
|
841
|
-
*/
|
|
842
|
-
stop(): void;
|
|
843
|
-
/**
|
|
844
|
-
* Handle config update
|
|
845
|
-
*/
|
|
846
|
-
onConfigUpdate(config: VTiltConfig): void;
|
|
847
|
-
/**
|
|
848
|
-
* Get the list of metrics to capture
|
|
849
|
-
*/
|
|
850
|
-
get allowedMetrics(): SupportedWebVitalsMetric[];
|
|
851
|
-
/**
|
|
852
|
-
* Get flush timeout in ms
|
|
853
|
-
*/
|
|
854
|
-
get flushTimeoutMs(): number;
|
|
855
|
-
/**
|
|
856
|
-
* Get maximum allowed metric value
|
|
857
|
-
*/
|
|
858
|
-
get maxAllowedValue(): number;
|
|
859
|
-
private _createEmptyBuffer;
|
|
860
|
-
private _getWebVitalsCallbacks;
|
|
861
|
-
private _loadWebVitals;
|
|
862
|
-
private _startCapturing;
|
|
863
|
-
private _getCurrentUrl;
|
|
864
|
-
private _getCurrentPathname;
|
|
865
|
-
private _addToBuffer;
|
|
866
|
-
private _cleanAttribution;
|
|
867
|
-
private _getWindowId;
|
|
868
|
-
private _scheduleFlush;
|
|
869
|
-
private _flush;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* History Autocapture
|
|
939
|
+
* Automatic DOM event capture for clicks, form submissions, and input changes.
|
|
940
|
+
* Privacy-first approach with element chain tracking and sensitive data filtering.
|
|
874
941
|
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
942
|
+
* Lifecycle (see docs/patterns/tracker-feature-lifecycle.md):
|
|
943
|
+
* - Construction: created by FeatureManager when not hard-disabled.
|
|
944
|
+
* - startIfEnabled: attaches DOM listeners when isEnabled becomes true.
|
|
945
|
+
* - stop: detaches DOM listeners. Subsequent startIfEnabled re-attaches.
|
|
946
|
+
* - onConfigUpdate: re-evaluates isEnabled on every config change and starts or
|
|
947
|
+
* stops accordingly. This is what flips autocapture on when the
|
|
948
|
+
* /decide endpoint returns `analytics.autocapture: true`.
|
|
877
949
|
*
|
|
878
|
-
*
|
|
950
|
+
* Enabled state precedence (highest first):
|
|
951
|
+
* 1. _userOverride === false → off (set by vt.stopAutocapture())
|
|
952
|
+
* 2. _isDisabledServerSide === true → off (set by remote autocapture_opt_out)
|
|
953
|
+
* 3. _userOverride === true → on (set by vt.startAutocapture())
|
|
954
|
+
* 4. config.autocapture truthy → on
|
|
955
|
+
* 5. otherwise → off
|
|
879
956
|
*/
|
|
880
957
|
|
|
881
|
-
interface HistoryAutocaptureConfig extends FeatureConfig {
|
|
882
|
-
/** Whether to capture pageviews on history changes */
|
|
883
|
-
enabled?: boolean;
|
|
884
|
-
}
|
|
885
958
|
/**
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
* Automatically captures $pageview events on SPA navigation.
|
|
889
|
-
* Implements the Feature interface for consistent lifecycle management.
|
|
959
|
+
* Reasons isEnabled may evaluate to false. Surfaced by getDiagnostics() so that
|
|
960
|
+
* integrators can pinpoint why no `$autocapture` events are flowing.
|
|
890
961
|
*/
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
/**
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
private _patchHistoryMethods;
|
|
911
|
-
private _setupPopstateListener;
|
|
912
|
-
private _capturePageview;
|
|
962
|
+
type AutocaptureDisabledReason = "user_stop_called" | "server_opt_out" | "config_autocapture_false" | "config_autocapture_undefined";
|
|
963
|
+
interface AutocaptureDiagnostics {
|
|
964
|
+
/** Whether the feature is enabled given current config and overrides. */
|
|
965
|
+
isEnabled: boolean;
|
|
966
|
+
/** Whether DOM listeners are currently attached. */
|
|
967
|
+
isStarted: boolean;
|
|
968
|
+
/** Why the feature is disabled (if any). */
|
|
969
|
+
disabledReason: AutocaptureDisabledReason | null;
|
|
970
|
+
/** Snapshot of inputs that drove the decision. */
|
|
971
|
+
inputs: {
|
|
972
|
+
configAutocapture: unknown;
|
|
973
|
+
isDisabledServerSide: boolean;
|
|
974
|
+
userOverride: boolean | null;
|
|
975
|
+
elementsChainAsString: boolean;
|
|
976
|
+
captureCopiedText: boolean;
|
|
977
|
+
scrollDepthMilestones: boolean;
|
|
978
|
+
scrollDepthPageleave: boolean;
|
|
979
|
+
scrollDepthListenerAttached: boolean;
|
|
980
|
+
};
|
|
913
981
|
}
|
|
914
|
-
|
|
915
|
-
/**
|
|
916
|
-
* Autocapture
|
|
917
|
-
*
|
|
918
|
-
* Automatic DOM event capture for clicks, form submissions, and input changes.
|
|
919
|
-
* Privacy-first approach with element chain tracking and sensitive data filtering.
|
|
920
|
-
*/
|
|
921
|
-
|
|
922
982
|
/**
|
|
923
983
|
* Autocapture class for automatic DOM event tracking.
|
|
924
984
|
* Implements the Feature interface for consistent lifecycle management.
|
|
@@ -928,531 +988,287 @@ declare class Autocapture implements Feature {
|
|
|
928
988
|
private _instance;
|
|
929
989
|
private _initialized;
|
|
930
990
|
private _isDisabledServerSide;
|
|
991
|
+
/** Explicit user override via vt.startAutocapture() / vt.stopAutocapture(). */
|
|
992
|
+
private _userOverride;
|
|
931
993
|
private _elementSelectors;
|
|
932
994
|
private _rageclicks;
|
|
995
|
+
/**
|
|
996
|
+
* Compact-payload mode for `$autocapture`. When true (the default), the SDK
|
|
997
|
+
* only sends the `$elements_chain` string and omits the verbose `$elements`
|
|
998
|
+
* array — the array is duplicate information for the ingestion side and is
|
|
999
|
+
* what pushes payloads past the client size cap on apps with deep DOM
|
|
1000
|
+
* trees / Tailwind / Material class soup. Integrators that still need
|
|
1001
|
+
* `$elements` (legacy filters / external pipelines) can opt out with
|
|
1002
|
+
* `vt.init({ elementsChainAsString: false })` or via `/decide`.
|
|
1003
|
+
*/
|
|
933
1004
|
private _elementsChainAsString;
|
|
934
|
-
|
|
1005
|
+
private _cachedConfig;
|
|
1006
|
+
private _cachedConfigSource;
|
|
1007
|
+
/**
|
|
1008
|
+
* Bound DOM handlers. Stored so stop() can detach them — passing the same
|
|
1009
|
+
* function reference is required by removeEventListener().
|
|
1010
|
+
*/
|
|
1011
|
+
private _domHandler;
|
|
1012
|
+
private _copyHandler;
|
|
1013
|
+
private _copyHandlerAttached;
|
|
1014
|
+
private _scrollDepthTracker;
|
|
1015
|
+
private _pageviewUnsubscribe;
|
|
1016
|
+
static extractConfig(config: VTiltConfig): {
|
|
1017
|
+
enabled: boolean;
|
|
1018
|
+
};
|
|
1019
|
+
constructor(instance: VTilt, _config?: {
|
|
1020
|
+
enabled: boolean;
|
|
1021
|
+
});
|
|
935
1022
|
private get _config();
|
|
936
1023
|
get isEnabled(): boolean;
|
|
937
1024
|
get isStarted(): boolean;
|
|
938
1025
|
startIfEnabled(): void;
|
|
939
1026
|
stop(): void;
|
|
940
|
-
onConfigUpdate(_config: VTiltConfig): void;
|
|
941
|
-
onRemoteConfig(response: RemoteConfig): void;
|
|
942
1027
|
/**
|
|
943
|
-
*
|
|
1028
|
+
* Max scroll depth % for the current page when pageleave mode is enabled.
|
|
1029
|
+
* Used to enrich `$pageleave` payloads.
|
|
1030
|
+
*/
|
|
1031
|
+
getMaxScrollDepthPctForPageleave(): number | null;
|
|
1032
|
+
onConfigUpdate(config: VTiltConfig): void;
|
|
1033
|
+
/**
|
|
1034
|
+
* Update autocapture configuration (for programmatic control).
|
|
1035
|
+
* Called from vt.startAutocapture() / vt.stopAutocapture().
|
|
944
1036
|
*/
|
|
945
1037
|
updateConfig(config: Partial<{
|
|
946
1038
|
enabled: boolean;
|
|
947
1039
|
}>): void;
|
|
1040
|
+
getDiagnostics(): AutocaptureDiagnostics;
|
|
948
1041
|
setElementSelectors(selectors: Set<string>): void;
|
|
949
1042
|
getElementSelectors(element: Element | null): string[] | null;
|
|
1043
|
+
/**
|
|
1044
|
+
* Single-source-of-truth for whether autocapture should be active.
|
|
1045
|
+
* Returns the disabled reason so diagnostics and logging can be precise.
|
|
1046
|
+
*/
|
|
1047
|
+
private _evaluateEnabled;
|
|
950
1048
|
private _addDomEventHandlers;
|
|
951
|
-
private
|
|
952
|
-
private _isBrowserSupported;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* Session Recording Types
|
|
957
|
-
*
|
|
958
|
-
* Type definitions for rrweb session recording.
|
|
959
|
-
* Based on PostHog's implementation.
|
|
960
|
-
*/
|
|
961
|
-
|
|
962
|
-
/** Mask options for input elements */
|
|
963
|
-
type MaskInputOptions = Partial<{
|
|
964
|
-
color: boolean;
|
|
965
|
-
date: boolean;
|
|
966
|
-
"datetime-local": boolean;
|
|
967
|
-
email: boolean;
|
|
968
|
-
month: boolean;
|
|
969
|
-
number: boolean;
|
|
970
|
-
range: boolean;
|
|
971
|
-
search: boolean;
|
|
972
|
-
tel: boolean;
|
|
973
|
-
text: boolean;
|
|
974
|
-
time: boolean;
|
|
975
|
-
url: boolean;
|
|
976
|
-
week: boolean;
|
|
977
|
-
textarea: boolean;
|
|
978
|
-
select: boolean;
|
|
979
|
-
password: boolean;
|
|
980
|
-
}>;
|
|
981
|
-
/** Masking configuration */
|
|
982
|
-
interface MaskingConfig {
|
|
983
|
-
maskAllInputs?: boolean;
|
|
984
|
-
maskTextSelector?: string;
|
|
985
|
-
blockSelector?: string;
|
|
986
|
-
}
|
|
987
|
-
/** Session recording configuration */
|
|
988
|
-
interface SessionRecordingConfig {
|
|
989
|
-
/** Enable session recording */
|
|
990
|
-
enabled?: boolean;
|
|
991
|
-
/** Sample rate (0-1, where 1 = 100%) */
|
|
992
|
-
sampleRate?: number;
|
|
993
|
-
/** Minimum session duration in ms before sending */
|
|
994
|
-
minimumDurationMs?: number;
|
|
995
|
-
/** Session idle threshold in ms */
|
|
996
|
-
sessionIdleThresholdMs?: number;
|
|
997
|
-
/** Full snapshot interval in ms */
|
|
998
|
-
fullSnapshotIntervalMs?: number;
|
|
999
|
-
/** Enable console log capture */
|
|
1000
|
-
captureConsole?: boolean;
|
|
1001
|
-
/** Enable network request capture */
|
|
1002
|
-
captureNetwork?: boolean;
|
|
1003
|
-
/** Canvas recording settings */
|
|
1004
|
-
captureCanvas?: {
|
|
1005
|
-
recordCanvas?: boolean;
|
|
1006
|
-
canvasFps?: number;
|
|
1007
|
-
canvasQuality?: number;
|
|
1008
|
-
};
|
|
1009
|
-
/** Masking settings */
|
|
1010
|
-
masking?: MaskingConfig;
|
|
1011
|
-
/** Block class for elements to hide */
|
|
1012
|
-
blockClass?: string;
|
|
1013
|
-
/** Block selector for elements to hide */
|
|
1014
|
-
blockSelector?: string;
|
|
1015
|
-
/** Ignore class for input masking */
|
|
1016
|
-
ignoreClass?: string;
|
|
1017
|
-
/** Mask text class */
|
|
1018
|
-
maskTextClass?: string;
|
|
1019
|
-
/** Mask text selector */
|
|
1020
|
-
maskTextSelector?: string;
|
|
1021
|
-
/** Mask all inputs */
|
|
1022
|
-
maskAllInputs?: boolean;
|
|
1023
|
-
/** Mask input options */
|
|
1024
|
-
maskInputOptions?: MaskInputOptions;
|
|
1025
|
-
/** Record headers in network requests */
|
|
1026
|
-
recordHeaders?: boolean;
|
|
1027
|
-
/** Record body in network requests */
|
|
1028
|
-
recordBody?: boolean;
|
|
1029
|
-
/** Compress events before sending */
|
|
1030
|
-
compressEvents?: boolean;
|
|
1031
|
-
/** Internal: Mutation throttler refill rate */
|
|
1032
|
-
__mutationThrottlerRefillRate?: number;
|
|
1033
|
-
/** Internal: Mutation throttler bucket size */
|
|
1034
|
-
__mutationThrottlerBucketSize?: number;
|
|
1035
|
-
}
|
|
1036
|
-
/** Recording start reason */
|
|
1037
|
-
type SessionStartReason = "recording_initialized" | "session_id_changed" | "linked_flag_matched" | "linked_flag_overridden" | "sampling_overridden" | "url_trigger_matched" | "event_trigger_matched" | "sampled" | "config_updated" | "remote_config";
|
|
1038
|
-
|
|
1039
|
-
/**
|
|
1040
|
-
* Chat message structure (matches PostgreSQL chat_messages table)
|
|
1041
|
-
* Note: Read status is determined by cursor comparison, not per-message
|
|
1042
|
-
*/
|
|
1043
|
-
interface ChatMessage {
|
|
1044
|
-
id: string;
|
|
1045
|
-
channel_id: string;
|
|
1046
|
-
sender_type: "user" | "agent" | "ai" | "system";
|
|
1047
|
-
sender_id: string | null;
|
|
1048
|
-
sender_name: string | null;
|
|
1049
|
-
sender_avatar_url: string | null;
|
|
1050
|
-
content: string;
|
|
1051
|
-
content_type: "text" | "html" | "attachment";
|
|
1052
|
-
metadata: Record<string, unknown>;
|
|
1053
|
-
created_at: string;
|
|
1054
|
-
}
|
|
1055
|
-
/**
|
|
1056
|
-
* Chat channel structure (maps 1:1 to Ably channel)
|
|
1057
|
-
*/
|
|
1058
|
-
interface ChatChannel {
|
|
1059
|
-
id: string;
|
|
1060
|
-
project_id: string;
|
|
1061
|
-
person_id: string;
|
|
1062
|
-
distinct_id: string;
|
|
1063
|
-
status: "open" | "closed" | "snoozed";
|
|
1064
|
-
ai_mode: boolean;
|
|
1065
|
-
unread_count: number;
|
|
1066
|
-
last_message_at: string | null;
|
|
1067
|
-
last_message_preview: string | null;
|
|
1068
|
-
last_message_sender: "user" | "agent" | "ai" | "system" | null;
|
|
1069
|
-
user_last_read_at: string | null;
|
|
1070
|
-
agent_last_read_at: string | null;
|
|
1071
|
-
created_at: string;
|
|
1072
|
-
}
|
|
1073
|
-
/**
|
|
1074
|
-
* Lightweight channel summary for channel list view
|
|
1075
|
-
* Used to avoid loading full channel data until user selects one
|
|
1076
|
-
*/
|
|
1077
|
-
interface ChatChannelSummary {
|
|
1078
|
-
id: string;
|
|
1079
|
-
status: "open" | "closed" | "snoozed";
|
|
1080
|
-
ai_mode: boolean;
|
|
1081
|
-
last_message_at: string | null;
|
|
1082
|
-
last_message_preview: string | null;
|
|
1083
|
-
last_message_sender: "user" | "agent" | "ai" | "system" | null;
|
|
1084
|
-
unread_count: number;
|
|
1085
|
-
user_last_read_at: string | null;
|
|
1086
|
-
created_at: string;
|
|
1087
|
-
}
|
|
1088
|
-
/**
|
|
1089
|
-
* Widget view state - determines what UI to show
|
|
1090
|
-
*/
|
|
1091
|
-
type ChatWidgetView = "list" | "conversation";
|
|
1092
|
-
/**
|
|
1093
|
-
* Chat widget configuration
|
|
1094
|
-
*
|
|
1095
|
-
* Settings can come from two sources:
|
|
1096
|
-
* 1. Dashboard (fetched from /api/chat/settings) - "snippet-only" mode
|
|
1097
|
-
* 2. Code config (passed to vt.init) - overrides dashboard settings
|
|
1098
|
-
*
|
|
1099
|
-
* This enables Intercom-like flexibility: just add snippet OR customize with code.
|
|
1100
|
-
*/
|
|
1101
|
-
interface ChatConfig {
|
|
1049
|
+
private _removeDomEventHandlers;
|
|
1102
1050
|
/**
|
|
1103
|
-
*
|
|
1104
|
-
* - undefined: Use dashboard setting (auto-fetch)
|
|
1105
|
-
* - true: Enable (override dashboard)
|
|
1106
|
-
* - false: Disable entirely
|
|
1051
|
+
* Scroll depth listener — opt-in via `autocapture.scroll_depth` milestones and/or pageleave.
|
|
1107
1052
|
*/
|
|
1108
|
-
|
|
1053
|
+
private _syncScrollDepthHandler;
|
|
1054
|
+
private _teardownScrollDepth;
|
|
1109
1055
|
/**
|
|
1110
|
-
*
|
|
1111
|
-
*
|
|
1112
|
-
*
|
|
1056
|
+
* The copy/cut listener is opt-in via `autocapture.capture_copied_text`.
|
|
1057
|
+
* Callable from both startIfEnabled and onConfigUpdate so toggling the flag
|
|
1058
|
+
* mid-session correctly attaches or detaches the listener.
|
|
1113
1059
|
*/
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
/** Widget header/greeting message */
|
|
1118
|
-
greeting?: string;
|
|
1119
|
-
/** Widget primary color */
|
|
1120
|
-
color?: string;
|
|
1121
|
-
/** Start in AI mode (default: true) */
|
|
1122
|
-
aiMode?: boolean;
|
|
1123
|
-
/** AI greeting message (first message from AI) */
|
|
1124
|
-
aiGreeting?: string;
|
|
1125
|
-
/** Preload widget script on idle vs on-demand */
|
|
1126
|
-
preload?: boolean;
|
|
1127
|
-
/** Custom theme */
|
|
1128
|
-
theme?: ChatTheme;
|
|
1129
|
-
/** Offline message shown when business is unavailable */
|
|
1130
|
-
offlineMessage?: string;
|
|
1131
|
-
/** Collect email when offline */
|
|
1132
|
-
collectEmailOffline?: boolean;
|
|
1133
|
-
/** Called when widget is opened */
|
|
1134
|
-
onWidgetOpen?: () => void;
|
|
1135
|
-
/** Called when widget is closed */
|
|
1136
|
-
onWidgetClose?: (data: {
|
|
1137
|
-
timeOpenSeconds: number;
|
|
1138
|
-
messagesSent: number;
|
|
1139
|
-
}) => void;
|
|
1140
|
-
/** Called when a new conversation is started */
|
|
1141
|
-
onConversationStart?: (data: {
|
|
1142
|
-
channelId: string;
|
|
1143
|
-
aiMode: boolean;
|
|
1144
|
-
}) => void;
|
|
1145
|
-
/** Called when user sends a message */
|
|
1146
|
-
onMessageSent?: (data: {
|
|
1147
|
-
channelId: string;
|
|
1148
|
-
messageId: string;
|
|
1149
|
-
}) => void;
|
|
1150
|
-
/** Called when a message is received (from AI or agent) */
|
|
1151
|
-
onMessageReceived?: (data: {
|
|
1152
|
-
channelId: string;
|
|
1153
|
-
messageId: string;
|
|
1154
|
-
senderType: "ai" | "agent";
|
|
1155
|
-
}) => void;
|
|
1156
|
-
}
|
|
1157
|
-
/**
|
|
1158
|
-
* Chat theme customization
|
|
1159
|
-
*/
|
|
1160
|
-
interface ChatTheme {
|
|
1161
|
-
primaryColor?: string;
|
|
1162
|
-
fontFamily?: string;
|
|
1163
|
-
borderRadius?: string;
|
|
1164
|
-
headerBgColor?: string;
|
|
1165
|
-
userBubbleColor?: string;
|
|
1166
|
-
agentBubbleColor?: string;
|
|
1060
|
+
private _syncCopyHandler;
|
|
1061
|
+
private _captureEvent;
|
|
1062
|
+
private _isBrowserSupported;
|
|
1167
1063
|
}
|
|
1168
1064
|
|
|
1169
1065
|
/**
|
|
1170
|
-
*
|
|
1066
|
+
* Consent Manager
|
|
1171
1067
|
*
|
|
1172
|
-
*
|
|
1173
|
-
*
|
|
1174
|
-
*
|
|
1068
|
+
* Manages user consent state for analytics, marketing, and advertising.
|
|
1069
|
+
* Stores consent in a first-party cookie (_vtilt_consent) and provides
|
|
1070
|
+
* consent properties to attach to every event.
|
|
1175
1071
|
*
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1072
|
+
* When `requireConsent` is true in config, the CaptureManager gates
|
|
1073
|
+
* non-essential events until setConsent() is called.
|
|
1178
1074
|
*/
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
private readonly _instance;
|
|
1198
|
-
readonly name = "SessionRecording";
|
|
1199
|
-
private _lazyLoadedRecording;
|
|
1200
|
-
private _config;
|
|
1201
|
-
private _isStarted;
|
|
1202
|
-
constructor(_instance: VTilt, config?: SessionRecordingConfig);
|
|
1203
|
-
/**
|
|
1204
|
-
* Extract session recording config from VTiltConfig.
|
|
1205
|
-
* Self-contained - vtilt.ts doesn't need to know config details.
|
|
1206
|
-
*/
|
|
1207
|
-
static extractConfig(config: VTiltConfig): SessionRecordingConfig;
|
|
1208
|
-
get isEnabled(): boolean;
|
|
1209
|
-
get isStarted(): boolean;
|
|
1210
|
-
/**
|
|
1211
|
-
* Start if enabled (Feature interface).
|
|
1212
|
-
* Use startIfEnabledOrStop for recording as it needs to actively stop.
|
|
1213
|
-
*/
|
|
1214
|
-
startIfEnabled(): void;
|
|
1215
|
-
/**
|
|
1216
|
-
* Start if enabled, or stop if disabled (ToggleableFeature interface).
|
|
1217
|
-
* This is the primary method for session recording.
|
|
1218
|
-
*/
|
|
1219
|
-
startIfEnabledOrStop(trigger?: SessionStartReason): void;
|
|
1220
|
-
/**
|
|
1221
|
-
* Stop recording (Feature interface).
|
|
1222
|
-
*/
|
|
1223
|
-
stop(): void;
|
|
1224
|
-
/**
|
|
1225
|
-
* Handle config updates (Feature interface).
|
|
1226
|
-
*/
|
|
1227
|
-
onConfigUpdate(config: VTiltConfig): void;
|
|
1075
|
+
interface ConsentState {
|
|
1076
|
+
analytics?: boolean;
|
|
1077
|
+
marketing?: boolean;
|
|
1078
|
+
advertising?: boolean;
|
|
1079
|
+
}
|
|
1080
|
+
interface ConsentHost {
|
|
1081
|
+
_emitter?: {
|
|
1082
|
+
emit(event: string, payload?: unknown): void;
|
|
1083
|
+
};
|
|
1084
|
+
getConfig(): {
|
|
1085
|
+
require_consent?: boolean;
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
declare class ConsentManager {
|
|
1089
|
+
private _host;
|
|
1090
|
+
private _state;
|
|
1091
|
+
private _hasBeenSet;
|
|
1092
|
+
constructor(host: ConsentHost);
|
|
1228
1093
|
/**
|
|
1229
|
-
*
|
|
1094
|
+
* Set consent state. Merges with existing state.
|
|
1095
|
+
* Persists to cookie and emits consent:updated.
|
|
1230
1096
|
*/
|
|
1231
|
-
|
|
1232
|
-
get started(): boolean;
|
|
1233
|
-
get status(): SessionRecordingStatus;
|
|
1234
|
-
get sessionId(): string;
|
|
1097
|
+
setConsent(consent: ConsentState): void;
|
|
1235
1098
|
/**
|
|
1236
|
-
*
|
|
1099
|
+
* Get current consent state.
|
|
1100
|
+
* Returns undefined fields for categories not yet set.
|
|
1237
1101
|
*/
|
|
1238
|
-
|
|
1102
|
+
getConsent(): ConsentState;
|
|
1239
1103
|
/**
|
|
1240
|
-
*
|
|
1104
|
+
* Whether setConsent() has been called (or consent was loaded from cookie).
|
|
1105
|
+
* Used by CaptureManager to gate events when requireConsent is true.
|
|
1241
1106
|
*/
|
|
1242
|
-
|
|
1107
|
+
hasConsent(): boolean;
|
|
1243
1108
|
/**
|
|
1244
|
-
*
|
|
1109
|
+
* Apply default-all-granted state when no explicit consent exists.
|
|
1110
|
+
* Sets all categories to true in memory but does NOT persist to cookie
|
|
1111
|
+
* (implicit defaults don't need storage — only explicit user choices do).
|
|
1245
1112
|
*/
|
|
1246
|
-
|
|
1247
|
-
private get _scriptName();
|
|
1113
|
+
setDefaultGranted(): void;
|
|
1248
1114
|
/**
|
|
1249
|
-
*
|
|
1115
|
+
* Returns event properties to attach to every captured event.
|
|
1116
|
+
* Only includes fields that have been explicitly set.
|
|
1250
1117
|
*/
|
|
1251
|
-
|
|
1118
|
+
getConsentProperties(): Record<string, boolean>;
|
|
1252
1119
|
/**
|
|
1253
|
-
*
|
|
1120
|
+
* Reset consent state (e.g. on user logout).
|
|
1254
1121
|
*/
|
|
1255
|
-
|
|
1122
|
+
reset(): void;
|
|
1123
|
+
private _readFromCookie;
|
|
1124
|
+
private _writeToCookie;
|
|
1125
|
+
private _removeCookie;
|
|
1256
1126
|
}
|
|
1257
1127
|
|
|
1258
1128
|
/**
|
|
1259
|
-
*
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
*
|
|
1129
|
+
* Consent Mode v2 bridge.
|
|
1130
|
+
*
|
|
1131
|
+
* Maps vTilt's 3-boolean consent (analytics / marketing / advertising) to
|
|
1132
|
+
* Google's 4-key Consent Mode v2 payload (ad_storage, ad_user_data,
|
|
1133
|
+
* ad_personalization, analytics_storage) and pushes it through gtag.
|
|
1134
|
+
*
|
|
1135
|
+
* Mapping (default):
|
|
1136
|
+
* advertising -> ad_storage + ad_user_data + ad_personalization
|
|
1137
|
+
* analytics -> analytics_storage
|
|
1138
|
+
* marketing is not sent to Google by default (it covers email/SMS, not ads).
|
|
1139
|
+
*
|
|
1140
|
+
* Admin UI may override individual keys (`consentOverride`) to hard-wire a
|
|
1141
|
+
* specific value regardless of user consent — useful for jurisdictions or
|
|
1142
|
+
* projects with fixed policies.
|
|
1264
1143
|
*/
|
|
1265
|
-
|
|
1144
|
+
|
|
1145
|
+
type GtagFn = (...args: unknown[]) => void;
|
|
1146
|
+
|
|
1266
1147
|
/**
|
|
1267
|
-
*
|
|
1148
|
+
* `vt.gtag(...)` escape hatch.
|
|
1149
|
+
*
|
|
1150
|
+
* Power users may need to call `gtag` directly (e.g. to fire a custom
|
|
1151
|
+
* conversion from a third-party widget or to set a debug param). We expose
|
|
1152
|
+
* a flat passthrough that:
|
|
1153
|
+
*
|
|
1154
|
+
* - queues calls made before the SDK has booted (keeps them in FIFO order),
|
|
1155
|
+
* - queues calls made before `gtag.js` has loaded (forwarded via the
|
|
1156
|
+
* `dataLayer` shim, which naturally buffers until the real script runs),
|
|
1157
|
+
* - records every call so tests + the delivery log can see them.
|
|
1268
1158
|
*/
|
|
1269
|
-
|
|
1159
|
+
|
|
1160
|
+
type GtagCall = unknown[];
|
|
1161
|
+
|
|
1270
1162
|
/**
|
|
1271
|
-
*
|
|
1163
|
+
* Enhanced Conversions helper.
|
|
1164
|
+
*
|
|
1165
|
+
* Hashes user-provided PII (email/phone/name/address) with SHA-256 before
|
|
1166
|
+
* it leaves the browser, matching Google Ads' Enhanced Conversions format:
|
|
1167
|
+
* https://support.google.com/google-ads/answer/13258081
|
|
1168
|
+
*
|
|
1169
|
+
* Returns an object suitable for `gtag('set', 'user_data', { ... })`.
|
|
1272
1170
|
*/
|
|
1273
|
-
|
|
1171
|
+
interface RawUserData {
|
|
1172
|
+
email?: string | null;
|
|
1173
|
+
phone?: string | null;
|
|
1174
|
+
first_name?: string | null;
|
|
1175
|
+
last_name?: string | null;
|
|
1176
|
+
street?: string | null;
|
|
1177
|
+
city?: string | null;
|
|
1178
|
+
region?: string | null;
|
|
1179
|
+
postal_code?: string | null;
|
|
1180
|
+
country?: string | null;
|
|
1181
|
+
}
|
|
1274
1182
|
|
|
1275
1183
|
/**
|
|
1276
|
-
*
|
|
1184
|
+
* GoogleTagGateway feature.
|
|
1185
|
+
*
|
|
1186
|
+
* Orchestrates the client-side half of the Google Tag Gateway destination:
|
|
1277
1187
|
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1188
|
+
* 1. Maintains `window.dataLayer` / `window.gtag`.
|
|
1189
|
+
* 2. Pushes Consent Mode v2 defaults BEFORE gtag.js loads, and re-pushes
|
|
1190
|
+
* on `consent:updated` events.
|
|
1191
|
+
* 3. Injects `gtag/js?id=<primary>` from the vTilt gateway (`/gt`) so
|
|
1192
|
+
* every measurement request flows through the first-party origin.
|
|
1193
|
+
* 4. Subscribes to EVENT_CAPTURED and forwards mapped events to Ads
|
|
1194
|
+
* (`gtag('event', 'conversion', ...)`).
|
|
1195
|
+
* 5. Exposes a flat `vt.gtag(...)` passthrough for power users.
|
|
1280
1196
|
*
|
|
1281
|
-
*
|
|
1282
|
-
*
|
|
1283
|
-
*
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1287
|
-
*
|
|
1197
|
+
* Forwards only after `__remote_config_loaded` is true (same signal as
|
|
1198
|
+
* EventBuffer: fresh `/decide` applied, bootstrap, or fetch failure).
|
|
1199
|
+
* Captures before that are queued so we never drop events just because
|
|
1200
|
+
* `/decide` has not committed yet. After remote is ready, we install the
|
|
1201
|
+
* official `dataLayer` + `gtag` shim (`ensureDataLayer`) and forward
|
|
1202
|
+
* immediately — the shim queues until `gtag.js` loads; we do not maintain a
|
|
1203
|
+
* second SDK queue for that window.
|
|
1204
|
+
*
|
|
1205
|
+
* Feature lifecycle matches the rest of the SDK — registered with
|
|
1206
|
+
* FeatureManager via a descriptor that pulls the admin-configured shape
|
|
1207
|
+
* out of `/decide` under the `googleTag` key.
|
|
1288
1208
|
*/
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1209
|
+
|
|
1210
|
+
interface GoogleTagGatewayFeatureConfig extends FeatureConfig {
|
|
1211
|
+
remote?: GoogleTagClientConfig;
|
|
1212
|
+
}
|
|
1213
|
+
interface DeliveryLogEntry {
|
|
1214
|
+
ts: number;
|
|
1215
|
+
tag_ids: string[];
|
|
1216
|
+
event_name: string;
|
|
1217
|
+
send_to: string;
|
|
1218
|
+
status: "fired" | "dropped";
|
|
1219
|
+
reason?: string;
|
|
1220
|
+
}
|
|
1221
|
+
declare class GoogleTagGateway implements Feature {
|
|
1222
|
+
readonly name = "GoogleTagGateway";
|
|
1223
|
+
private _instance;
|
|
1293
1224
|
private _config;
|
|
1294
|
-
private _serverConfig;
|
|
1295
|
-
private _configFetched;
|
|
1296
|
-
private _isLoading;
|
|
1297
1225
|
private _isStarted;
|
|
1298
|
-
private
|
|
1299
|
-
private
|
|
1300
|
-
private
|
|
1301
|
-
private
|
|
1302
|
-
private
|
|
1303
|
-
private
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1226
|
+
private _scriptInjected;
|
|
1227
|
+
private _scriptLoaded;
|
|
1228
|
+
private _consentDefaultsPushed;
|
|
1229
|
+
private _gtag;
|
|
1230
|
+
private _publicApi;
|
|
1231
|
+
private _loaderOptions;
|
|
1232
|
+
private _unsubscribeCaptured;
|
|
1233
|
+
private _unsubscribeConsent;
|
|
1234
|
+
private _deliveryLog;
|
|
1235
|
+
private readonly _maxDeliveryLog;
|
|
1236
|
+
/**
|
|
1237
|
+
* Captures observed before `__remote_config_loaded` only. Once remote
|
|
1238
|
+
* commits, `ensureDataLayer` + gtag forward — gtag's own queue handles
|
|
1239
|
+
* ordering until `gtag.js` is on the wire.
|
|
1240
|
+
*/
|
|
1241
|
+
private readonly _pendingCaptures;
|
|
1242
|
+
constructor(instance: VTilt, config?: GoogleTagGatewayFeatureConfig);
|
|
1243
|
+
static extractConfig(config: VTiltConfig): GoogleTagGatewayFeatureConfig;
|
|
1310
1244
|
get isEnabled(): boolean;
|
|
1311
1245
|
get isStarted(): boolean;
|
|
1312
|
-
/**
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
*/
|
|
1246
|
+
/** Exposed for tests and the public `vt.gtag` binding. */
|
|
1247
|
+
get gtag(): GtagFn;
|
|
1248
|
+
get deliveryLog(): DeliveryLogEntry[];
|
|
1316
1249
|
startIfEnabled(): void;
|
|
1317
|
-
/**
|
|
1318
|
-
* Stop the chat widget (Feature interface).
|
|
1319
|
-
*/
|
|
1320
1250
|
stop(): void;
|
|
1321
|
-
/**
|
|
1322
|
-
* Handle config updates (Feature interface).
|
|
1323
|
-
*/
|
|
1324
1251
|
onConfigUpdate(config: VTiltConfig): void;
|
|
1325
1252
|
/**
|
|
1326
|
-
*
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
/**
|
|
1330
|
-
* Async start implementation
|
|
1331
|
-
*/
|
|
1332
|
-
private _startAsync;
|
|
1333
|
-
/**
|
|
1334
|
-
* Whether the chat widget is open
|
|
1335
|
-
*/
|
|
1336
|
-
get isOpen(): boolean;
|
|
1337
|
-
/**
|
|
1338
|
-
* Whether connected to realtime service
|
|
1339
|
-
*/
|
|
1340
|
-
get isConnected(): boolean;
|
|
1341
|
-
/**
|
|
1342
|
-
* Whether the widget is loading
|
|
1343
|
-
*/
|
|
1344
|
-
get isLoading(): boolean;
|
|
1345
|
-
/**
|
|
1346
|
-
* Number of unread messages
|
|
1347
|
-
*/
|
|
1348
|
-
get unreadCount(): number;
|
|
1349
|
-
/**
|
|
1350
|
-
* Current channel (if any)
|
|
1351
|
-
*/
|
|
1352
|
-
get channel(): ChatChannel | null;
|
|
1353
|
-
/**
|
|
1354
|
-
* List of user's channels (multi-channel support)
|
|
1355
|
-
*/
|
|
1356
|
-
get channels(): ChatChannelSummary[];
|
|
1357
|
-
/**
|
|
1358
|
-
* Current view state ('list' or 'conversation')
|
|
1359
|
-
*/
|
|
1360
|
-
get currentView(): ChatWidgetView;
|
|
1361
|
-
/**
|
|
1362
|
-
* Open the chat widget
|
|
1363
|
-
*/
|
|
1364
|
-
open(): void;
|
|
1365
|
-
/**
|
|
1366
|
-
* Close the chat widget
|
|
1367
|
-
*/
|
|
1368
|
-
close(): void;
|
|
1369
|
-
/**
|
|
1370
|
-
* Toggle the chat widget open/closed
|
|
1371
|
-
*/
|
|
1372
|
-
toggle(): void;
|
|
1373
|
-
/**
|
|
1374
|
-
* Show the chat widget (make visible but not necessarily open)
|
|
1375
|
-
*/
|
|
1376
|
-
show(): void;
|
|
1377
|
-
/**
|
|
1378
|
-
* Hide the chat widget
|
|
1379
|
-
*/
|
|
1380
|
-
hide(): void;
|
|
1381
|
-
/**
|
|
1382
|
-
* Fetch/refresh the list of user's channels
|
|
1383
|
-
*/
|
|
1384
|
-
getChannels(): void;
|
|
1385
|
-
/**
|
|
1386
|
-
* Select a channel and load its messages
|
|
1387
|
-
*/
|
|
1388
|
-
selectChannel(channelId: string): void;
|
|
1389
|
-
/**
|
|
1390
|
-
* Create a new channel and enter it
|
|
1391
|
-
*/
|
|
1392
|
-
createChannel(): void;
|
|
1393
|
-
/**
|
|
1394
|
-
* Go back to channel list from conversation view
|
|
1395
|
-
*/
|
|
1396
|
-
goToChannelList(): void;
|
|
1397
|
-
/**
|
|
1398
|
-
* Send a message
|
|
1399
|
-
*/
|
|
1400
|
-
sendMessage(content: string): void;
|
|
1401
|
-
/**
|
|
1402
|
-
* Mark messages as read
|
|
1403
|
-
*/
|
|
1404
|
-
markAsRead(): void;
|
|
1405
|
-
/**
|
|
1406
|
-
* Subscribe to new messages
|
|
1407
|
-
*/
|
|
1408
|
-
onMessage(callback: MessageCallback): Unsubscribe$1;
|
|
1409
|
-
/**
|
|
1410
|
-
* Subscribe to typing indicators
|
|
1411
|
-
*/
|
|
1412
|
-
onTyping(callback: TypingCallback): Unsubscribe$1;
|
|
1413
|
-
/**
|
|
1414
|
-
* Subscribe to connection changes
|
|
1415
|
-
*/
|
|
1416
|
-
onConnectionChange(callback: ConnectionCallback): Unsubscribe$1;
|
|
1417
|
-
/**
|
|
1418
|
-
* Update configuration
|
|
1419
|
-
*/
|
|
1420
|
-
updateConfig(config: Partial<ChatConfig>): void;
|
|
1421
|
-
/**
|
|
1422
|
-
* Get the merged configuration (server + code, code takes precedence)
|
|
1423
|
-
*/
|
|
1424
|
-
getMergedConfig(): ChatConfig;
|
|
1425
|
-
/**
|
|
1426
|
-
* Destroy the chat widget
|
|
1427
|
-
*/
|
|
1428
|
-
destroy(): void;
|
|
1429
|
-
/**
|
|
1430
|
-
* Fetch chat settings from the server
|
|
1431
|
-
* This enables "snippet-only" installation where widget configures from dashboard
|
|
1432
|
-
*/
|
|
1433
|
-
private _fetchServerSettings;
|
|
1434
|
-
/**
|
|
1435
|
-
* Show the chat bubble (launcher button) without fully loading the widget
|
|
1436
|
-
* This creates a lightweight bubble that loads the full widget on click
|
|
1253
|
+
* Set the user identifiers that power Enhanced Conversions. Values are
|
|
1254
|
+
* normalized + SHA-256 hashed client-side before being pushed to gtag,
|
|
1255
|
+
* so raw PII never leaves the browser.
|
|
1437
1256
|
*/
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
private
|
|
1444
|
-
/**
|
|
1445
|
-
*
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
private
|
|
1452
|
-
|
|
1453
|
-
* Called after the chat script is loaded
|
|
1454
|
-
*/
|
|
1455
|
-
private _onScriptLoaded;
|
|
1257
|
+
setUserData(raw: RawUserData): Promise<void>;
|
|
1258
|
+
getRecentPublicCalls(): GtagCall[];
|
|
1259
|
+
private _start;
|
|
1260
|
+
private _drainPending;
|
|
1261
|
+
private _pushConsentDefaultsOnce;
|
|
1262
|
+
private _subscribeCaptured;
|
|
1263
|
+
/**
|
|
1264
|
+
* Handle one captured event. Only `__remote_config_loaded === false` uses
|
|
1265
|
+
* `_pendingCaptures`. After remote commits, we boot the gtag pipeline on
|
|
1266
|
+
* demand (`startIfEnabled`) and forward — the dataLayer shim buffers until
|
|
1267
|
+
* `gtag.js` loads.
|
|
1268
|
+
*/
|
|
1269
|
+
private _handleCaptured;
|
|
1270
|
+
private _subscribeConsent;
|
|
1271
|
+
private _record;
|
|
1456
1272
|
}
|
|
1457
1273
|
|
|
1458
1274
|
/**
|
|
@@ -1547,6 +1363,18 @@ interface QueuedRequest {
|
|
|
1547
1363
|
transport?: "xhr" | "sendBeacon";
|
|
1548
1364
|
}
|
|
1549
1365
|
|
|
1366
|
+
/**
|
|
1367
|
+
* Rate Limiter - Token Bucket Algorithm (PostHog-style)
|
|
1368
|
+
*
|
|
1369
|
+
* Prevents runaway loops from flooding the server with events.
|
|
1370
|
+
* Uses a token bucket algorithm with configurable rate and burst limits.
|
|
1371
|
+
*
|
|
1372
|
+
* Features:
|
|
1373
|
+
* - Configurable events per second (default: 10)
|
|
1374
|
+
* - Configurable burst limit (default: 100)
|
|
1375
|
+
* - Token replenishment over time
|
|
1376
|
+
* - Warning event when rate limited
|
|
1377
|
+
*/
|
|
1550
1378
|
interface RateLimitBucket {
|
|
1551
1379
|
tokens: number;
|
|
1552
1380
|
last: number;
|
|
@@ -1669,6 +1497,93 @@ declare class SimpleEventEmitter {
|
|
|
1669
1497
|
hasListeners(event: string): boolean;
|
|
1670
1498
|
}
|
|
1671
1499
|
|
|
1500
|
+
/**
|
|
1501
|
+
* Feature Manager
|
|
1502
|
+
*
|
|
1503
|
+
* Central registry for SDK features. Features self-describe via descriptors
|
|
1504
|
+
* that declare their config keys, remote config mappings, and class references.
|
|
1505
|
+
*
|
|
1506
|
+
* Responsibilities:
|
|
1507
|
+
* - Registration: features register descriptors before init
|
|
1508
|
+
* - Instance creation: createInstances() constructs instances during init() (pre-boot)
|
|
1509
|
+
* - Starting: initAll() starts created instances at boot via startIfEnabled
|
|
1510
|
+
* - Config propagation: notifyAll() calls onConfigUpdate on each instance
|
|
1511
|
+
* - Descriptor exposure: getDescriptors() lets RemoteConfigManager._apply iterate
|
|
1512
|
+
*
|
|
1513
|
+
* @see docs/patterns/tracker-feature-lifecycle.md
|
|
1514
|
+
*/
|
|
1515
|
+
|
|
1516
|
+
/**
|
|
1517
|
+
* Self-describing metadata for a feature.
|
|
1518
|
+
* Declared once at registration time; used by FeatureManager and RemoteConfigManager.
|
|
1519
|
+
*/
|
|
1520
|
+
interface FeatureDescriptor {
|
|
1521
|
+
/** Unique name (used as map key and for get()) */
|
|
1522
|
+
name: string;
|
|
1523
|
+
/** VTiltConfig key that holds this feature's config (e.g. "session_recording") */
|
|
1524
|
+
configKey?: keyof VTiltConfig;
|
|
1525
|
+
/** VTiltConfig boolean key that hard-disables the feature (e.g. "disable_session_recording") */
|
|
1526
|
+
disableKey?: keyof VTiltConfig;
|
|
1527
|
+
/** Remote config mapping — tells _apply how to extract config from RemoteConfig */
|
|
1528
|
+
remoteConfig?: {
|
|
1529
|
+
/** Key on the RemoteConfig object (e.g. "sessionRecording") */
|
|
1530
|
+
key: string;
|
|
1531
|
+
/** Transform remote section into the shape written to VTiltConfig[configKey] */
|
|
1532
|
+
map: (remote: Record<string, unknown>) => Record<string, unknown>;
|
|
1533
|
+
};
|
|
1534
|
+
/** Feature class — must have a static extractConfig and a constructor */
|
|
1535
|
+
FeatureClass: {
|
|
1536
|
+
new (instance: any, config?: any): Feature;
|
|
1537
|
+
extractConfig(config: VTiltConfig): any;
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
/**
|
|
1541
|
+
* Minimal host interface to avoid circular dependency with VTilt.
|
|
1542
|
+
*/
|
|
1543
|
+
interface FeatureHost {
|
|
1544
|
+
getConfig(): VTiltConfig;
|
|
1545
|
+
}
|
|
1546
|
+
declare class FeatureManager {
|
|
1547
|
+
private _host;
|
|
1548
|
+
private _descriptors;
|
|
1549
|
+
private _instances;
|
|
1550
|
+
constructor(host: FeatureHost);
|
|
1551
|
+
/** Register a feature descriptor. Call before initAll(). */
|
|
1552
|
+
register(desc: FeatureDescriptor): void;
|
|
1553
|
+
/**
|
|
1554
|
+
* Create instances for all registered features without starting them.
|
|
1555
|
+
* Safe to call before DOM boot — constructors are lightweight.
|
|
1556
|
+
* Idempotent: skips features that already have an instance.
|
|
1557
|
+
*
|
|
1558
|
+
* Hard-disabled features are skipped (instance not created):
|
|
1559
|
+
* - `disableKey` is true (e.g. `disable_chat: true`)
|
|
1560
|
+
* - `configKey` section has `enabled: false` (e.g. `chat: { enabled: false }`)
|
|
1561
|
+
*/
|
|
1562
|
+
createInstances(): void;
|
|
1563
|
+
/**
|
|
1564
|
+
* Create and start all registered features.
|
|
1565
|
+
* Calls `createInstances()` first (idempotent), then `startIfEnabled()` on each.
|
|
1566
|
+
*/
|
|
1567
|
+
initAll(): void;
|
|
1568
|
+
/** Notify all initialized features of a config change. */
|
|
1569
|
+
notifyAll(config: VTiltConfig): void;
|
|
1570
|
+
/** Get a feature instance by name. */
|
|
1571
|
+
get<T extends Feature>(name: string): T | undefined;
|
|
1572
|
+
/** Register a late-created feature instance (e.g. from a public start*() call). */
|
|
1573
|
+
set(name: string, instance: Feature): void;
|
|
1574
|
+
/** Expose descriptors so RemoteConfigManager._apply can iterate for remote config mapping. */
|
|
1575
|
+
getDescriptors(): Map<string, FeatureDescriptor>;
|
|
1576
|
+
/**
|
|
1577
|
+
* True when the integrator explicitly hard-disabled this feature in code config.
|
|
1578
|
+
* Two signals: `disableKey` flag (e.g. `disable_chat: true`) or
|
|
1579
|
+
* `configKey` section with `enabled: false` (e.g. `chat: { enabled: false }`).
|
|
1580
|
+
*
|
|
1581
|
+
* When `enabled` is omitted (undefined), the feature may still auto-configure
|
|
1582
|
+
* from dashboard settings, so we must construct the instance.
|
|
1583
|
+
*/
|
|
1584
|
+
private _isHardDisabled;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1672
1587
|
/**
|
|
1673
1588
|
* VTilt SDK - Main Entry Point
|
|
1674
1589
|
*
|
|
@@ -1681,57 +1596,111 @@ declare class SimpleEventEmitter {
|
|
|
1681
1596
|
* - CaptureManager: Event capture and payload enrichment
|
|
1682
1597
|
* - IdentityManager: High-level identity operations
|
|
1683
1598
|
* - RemoteConfigManager: Remote configuration from /decide
|
|
1684
|
-
* - FeatureManager: Feature lifecycle management
|
|
1599
|
+
* - FeatureManager: Feature lifecycle management (descriptors, initAll, notifyAll)
|
|
1685
1600
|
*
|
|
1686
|
-
* @see docs/tracker
|
|
1601
|
+
* @see docs/patterns/tracker-feature-lifecycle.md
|
|
1687
1602
|
*/
|
|
1688
1603
|
|
|
1689
1604
|
declare class VTilt {
|
|
1690
1605
|
readonly version: string;
|
|
1691
1606
|
__loaded: boolean;
|
|
1692
|
-
__request_queue: QueuedRequest[];
|
|
1693
|
-
historyAutocapture?: HistoryAutocapture;
|
|
1694
|
-
autocapture?: Autocapture;
|
|
1695
|
-
sessionRecording?: SessionRecordingWrapper;
|
|
1696
|
-
chat?: ChatWrapper;
|
|
1697
|
-
webVitals?: WebVitalsManager;
|
|
1698
|
-
vtdOverlay?: VtdOverlay;
|
|
1699
1607
|
private configManager;
|
|
1700
1608
|
sessionManager: SessionManager;
|
|
1701
1609
|
userManager: UserManager;
|
|
1702
1610
|
private _captureManager;
|
|
1703
1611
|
private _identityManager;
|
|
1704
1612
|
private _remoteConfigManager;
|
|
1705
|
-
|
|
1613
|
+
consentManager: ConsentManager;
|
|
1614
|
+
_featureManager: FeatureManager;
|
|
1615
|
+
vtdOverlay?: VtdOverlay;
|
|
1616
|
+
private _eventBuffer;
|
|
1706
1617
|
private requestQueue;
|
|
1707
1618
|
private retryQueue;
|
|
1708
1619
|
rateLimiter: RateLimiter;
|
|
1709
1620
|
_emitter: SimpleEventEmitter;
|
|
1710
1621
|
private _has_warned_about_config;
|
|
1622
|
+
private static readonly BOOT_GATED_METHODS;
|
|
1623
|
+
private _booted;
|
|
1624
|
+
private _pendingCalls;
|
|
1625
|
+
private _postBootInitDone;
|
|
1711
1626
|
constructor(config?: Partial<VTiltConfig>);
|
|
1627
|
+
/**
|
|
1628
|
+
* Register all features with their descriptors.
|
|
1629
|
+
* Descriptors tell FeatureManager and RemoteConfigManager how each feature works.
|
|
1630
|
+
*/
|
|
1631
|
+
private _registerFeatures;
|
|
1632
|
+
private _installBootGate;
|
|
1633
|
+
_boot(): void;
|
|
1712
1634
|
init(token: string, config?: Partial<VTiltConfig>, name?: string): VTilt;
|
|
1713
1635
|
private _init;
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1636
|
+
/**
|
|
1637
|
+
* Substantive init work that requires both init() config AND a booted
|
|
1638
|
+
* browser environment. Runs exactly once.
|
|
1639
|
+
*
|
|
1640
|
+
* Init order: hydrate storage -> initAll features -> load remote config
|
|
1641
|
+
* Features must exist before remote config loads so cached/fresh config
|
|
1642
|
+
* can trigger onConfigUpdate on already-initialized features.
|
|
1643
|
+
*/
|
|
1644
|
+
private _runPostBootInit;
|
|
1720
1645
|
startAutocapture(): void;
|
|
1721
1646
|
stopAutocapture(): void;
|
|
1722
1647
|
isAutocaptureActive(): boolean;
|
|
1648
|
+
/**
|
|
1649
|
+
* Returns a structured snapshot of the autocapture state — useful for
|
|
1650
|
+
* debugging "no `$autocapture` events" complaints. Returns `null` if the
|
|
1651
|
+
* Autocapture feature has not been registered (e.g. before init).
|
|
1652
|
+
*/
|
|
1653
|
+
getAutocaptureDiagnostics(): ReturnType<Autocapture["getDiagnostics"]> | null;
|
|
1723
1654
|
startSessionRecording(): void;
|
|
1724
1655
|
stopSessionRecording(): void;
|
|
1725
1656
|
isRecordingActive(): boolean;
|
|
1726
1657
|
getSessionRecordingId(): string | null;
|
|
1658
|
+
openChat(): void;
|
|
1659
|
+
closeChat(): void;
|
|
1660
|
+
toggleChat(): void;
|
|
1661
|
+
showChat(): void;
|
|
1662
|
+
hideChat(): void;
|
|
1663
|
+
/**
|
|
1664
|
+
* Send a chat message. By default uses the active conversation; pass options to
|
|
1665
|
+
* start a new conversation, target a channel, or open the widget panel.
|
|
1666
|
+
*/
|
|
1667
|
+
sendChatMessage(content: SendChatMessageContent, options?: SendChatMessageOptions): void;
|
|
1668
|
+
/**
|
|
1669
|
+
* Raw `gtag(...)` passthrough. Queues calls made before the feature is
|
|
1670
|
+
* enabled or before `gtag.js` has loaded, flushed FIFO once ready. Safe
|
|
1671
|
+
* to call at any time, including before `vt.init()`.
|
|
1672
|
+
*
|
|
1673
|
+
* @example
|
|
1674
|
+
* vt.gtag('event', 'sign_up', { method: 'email' })
|
|
1675
|
+
*/
|
|
1676
|
+
gtag(...args: unknown[]): void;
|
|
1677
|
+
/**
|
|
1678
|
+
* Set Enhanced Conversions user identifiers. Values are normalized and
|
|
1679
|
+
* SHA-256 hashed in the browser before being forwarded to gtag.
|
|
1680
|
+
*/
|
|
1681
|
+
setGoogleUserData(data: Parameters<GoogleTagGateway["setUserData"]>[0]): Promise<void>;
|
|
1682
|
+
get featureManager(): FeatureManager;
|
|
1683
|
+
on<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
|
|
1684
|
+
once<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
|
|
1685
|
+
/** Removes all listeners for `event` (same semantics as internal emitter). */
|
|
1686
|
+
off(event: string): void;
|
|
1687
|
+
/**
|
|
1688
|
+
* Whether this browser session looks like a bot/crawler (PostHog parity).
|
|
1689
|
+
* When true and bot filtering is enabled, `capture()` is a no-op.
|
|
1690
|
+
*/
|
|
1691
|
+
_is_bot(): boolean;
|
|
1727
1692
|
capture(name: string, payload: EventPayload, options?: {
|
|
1728
1693
|
skip_client_rate_limiting?: boolean;
|
|
1694
|
+
skip_engagement?: boolean;
|
|
1729
1695
|
}): void;
|
|
1730
|
-
|
|
1696
|
+
/** Emit $pageleave for the current page when enabled (SPA transitions, lifecycle hooks). */
|
|
1697
|
+
tryCapturePageleave(reason: string): void;
|
|
1731
1698
|
identify(newDistinctId?: string, userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
1732
1699
|
setUserProperties(userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
1733
1700
|
resetUser(reset_device_id?: boolean): void;
|
|
1734
|
-
|
|
1701
|
+
alias(alias: string, original?: string): void;
|
|
1702
|
+
setConsent(consent: ConsentState): void;
|
|
1703
|
+
getConsent(): ConsentState;
|
|
1735
1704
|
getUserIdentity(): Record<string, any>;
|
|
1736
1705
|
getDeviceId(): string;
|
|
1737
1706
|
getUserState(): "anonymous" | "identified";
|
|
@@ -1742,9 +1711,15 @@ declare class VTilt {
|
|
|
1742
1711
|
getAnonymousId(): string;
|
|
1743
1712
|
toString(): string;
|
|
1744
1713
|
updateConfig(config: Partial<VTiltConfig>): void;
|
|
1745
|
-
private _notifyFeaturesOfConfigUpdate;
|
|
1746
1714
|
buildUrl(): string;
|
|
1747
|
-
|
|
1715
|
+
buildEndpointUrl(path: string): string;
|
|
1716
|
+
sendRequest(url: string, event: TrackingEvent): void;
|
|
1717
|
+
/**
|
|
1718
|
+
* Route a captured event through the EventBuffer.
|
|
1719
|
+
* $snapshot and $snapshot_items bypass the buffer (they have identity from
|
|
1720
|
+
* UserManager and don't need config filtering).
|
|
1721
|
+
*/
|
|
1722
|
+
bufferEvent(name: string, url: string, event: TrackingEvent): void;
|
|
1748
1723
|
private _is_configured;
|
|
1749
1724
|
private _send_batched_request;
|
|
1750
1725
|
private _send_http_request;
|
|
@@ -1761,4 +1736,4 @@ declare class VTilt {
|
|
|
1761
1736
|
declare const vt: VTilt;
|
|
1762
1737
|
|
|
1763
1738
|
export { ALL_WEB_VITALS_METRICS, DEFAULT_WEB_VITALS_METRICS, VTilt, vt as default, vt };
|
|
1764
|
-
export type {
|
|
1739
|
+
export type { AutocaptureOptions, CaptureOptions, CapturePerformanceConfig, CaptureResult, ChatWidgetConfig, EventPayload, FeatureFlagsConfig, GeolocationData, GoogleAdsConversionMapping, GoogleConsentOverride, GoogleConsentValue, GoogleTagClientConfig, GoogleTagEventMapping, GoogleTagParamMapping, GoogleTagProxyMode, GroupsConfig, IdentityUpdate, PersistenceMethod, Properties, Property, PropertyOperations, RemoteConfig, RequestOptions, SessionData, SessionIdChangedCallback, SessionRecordingMaskInputOptions, SessionRecordingOptions, SupportedWebVitalsMetric, TrackingEvent, UserIdentity, UserProperties, VTiltConfig, WebVitalMetric };
|