@v-tilt/browser 1.9.0 → 1.10.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.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 +130 -0
- package/dist/autocapture-utils.d.ts +78 -0
- package/dist/autocapture.d.ts +84 -0
- package/dist/chat.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/core/capture.d.ts +70 -0
- package/dist/core/feature-manager.d.ts +95 -0
- package/dist/core/identity.d.ts +77 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/remote-config.d.ts +50 -0
- package/dist/extensions/chat/chat-wrapper.d.ts +36 -10
- package/dist/extensions/history-autocapture.d.ts +34 -7
- package/dist/extensions/replay/session-recording-wrapper.d.ts +42 -11
- package/dist/extensions/replay/types.d.ts +1 -1
- package/dist/extensions/web-vitals/index.d.ts +7 -0
- package/dist/extensions/web-vitals/web-vitals-manager.d.ts +81 -0
- package/dist/external-scripts-loader.js.map +1 -1
- package/dist/feature.d.ts +231 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.d.ts +881 -324
- package/dist/module.js +1 -1
- package/dist/module.js.map +1 -1
- package/dist/module.no-external.d.ts +881 -324
- package/dist/module.no-external.js +1 -1
- package/dist/module.no-external.js.map +1 -1
- package/dist/recorder.js.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/types.d.ts +50 -2
- package/dist/utils/event-emitter.d.ts +106 -0
- package/dist/utils/globals.d.ts +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/safewrap.d.ts +101 -0
- package/dist/utils/type-guards.d.ts +70 -0
- package/dist/vtilt.d.ts +66 -336
- package/dist/web-vitals.d.ts +39 -53
- package/dist/web-vitals.js.map +1 -1
- package/package.json +1 -1
package/dist/module.d.ts
CHANGED
|
@@ -56,8 +56,12 @@ interface VTiltConfig {
|
|
|
56
56
|
* - 'never': Never create person profiles
|
|
57
57
|
*/
|
|
58
58
|
person_profiles?: PersonProfilesMode;
|
|
59
|
-
/**
|
|
60
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Enable autocapture for automatic DOM event tracking.
|
|
61
|
+
* Can be a boolean or an object with detailed configuration.
|
|
62
|
+
* When true, captures clicks, form submissions, and input changes.
|
|
63
|
+
*/
|
|
64
|
+
autocapture?: boolean | AutocaptureOptions;
|
|
61
65
|
/**
|
|
62
66
|
* Enable web vitals tracking.
|
|
63
67
|
* Can be a boolean or an object with detailed configuration.
|
|
@@ -230,6 +234,48 @@ interface RequestOptions {
|
|
|
230
234
|
timeout?: number;
|
|
231
235
|
retry?: boolean;
|
|
232
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Autocapture configuration options
|
|
239
|
+
* Controls automatic DOM event tracking (clicks, form submissions, input changes)
|
|
240
|
+
*/
|
|
241
|
+
interface AutocaptureOptions {
|
|
242
|
+
/**
|
|
243
|
+
* Enable autocapture (default: true when autocapture config is present)
|
|
244
|
+
*/
|
|
245
|
+
enabled?: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* URL patterns to allow autocapture on (default: all URLs)
|
|
248
|
+
* Supports strings (exact match) and RegExp patterns
|
|
249
|
+
*/
|
|
250
|
+
url_allowlist?: (string | RegExp)[];
|
|
251
|
+
/**
|
|
252
|
+
* URL patterns to exclude from autocapture
|
|
253
|
+
* Supports strings (exact match) and RegExp patterns
|
|
254
|
+
*/
|
|
255
|
+
url_ignorelist?: (string | RegExp)[];
|
|
256
|
+
/**
|
|
257
|
+
* DOM events to capture (default: ['click', 'change', 'submit'])
|
|
258
|
+
*/
|
|
259
|
+
dom_event_allowlist?: ("click" | "change" | "submit")[];
|
|
260
|
+
/**
|
|
261
|
+
* Element tags to capture (default: ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'])
|
|
262
|
+
*/
|
|
263
|
+
element_allowlist?: string[];
|
|
264
|
+
/**
|
|
265
|
+
* CSS selectors to allow for capture (elements matching these are always captured)
|
|
266
|
+
* Example: ['[data-track]', '.track-click']
|
|
267
|
+
*/
|
|
268
|
+
css_selector_allowlist?: string[];
|
|
269
|
+
/**
|
|
270
|
+
* Element attributes to exclude from capture
|
|
271
|
+
* Example: ['data-secret', 'aria-label']
|
|
272
|
+
*/
|
|
273
|
+
element_attribute_ignorelist?: string[];
|
|
274
|
+
/**
|
|
275
|
+
* Capture text content from copy/cut events (default: false)
|
|
276
|
+
*/
|
|
277
|
+
capture_copied_text?: boolean;
|
|
278
|
+
}
|
|
233
279
|
/** Mask options for input elements in session recording */
|
|
234
280
|
interface SessionRecordingMaskInputOptions {
|
|
235
281
|
color?: boolean;
|
|
@@ -330,6 +376,8 @@ interface RemoteConfig {
|
|
|
330
376
|
enabled?: boolean;
|
|
331
377
|
sampleRate?: number;
|
|
332
378
|
minimumDurationMs?: number;
|
|
379
|
+
/** Full DOM snapshot interval in ms (default 300000 = 5 min). Higher = less data. */
|
|
380
|
+
fullSnapshotIntervalMs?: number;
|
|
333
381
|
maskAllInputs?: boolean;
|
|
334
382
|
maskAllText?: boolean;
|
|
335
383
|
captureConsole?: boolean;
|
|
@@ -359,20 +407,596 @@ interface RemoteConfig {
|
|
|
359
407
|
}
|
|
360
408
|
|
|
361
409
|
/**
|
|
362
|
-
*
|
|
363
|
-
*
|
|
410
|
+
* Session Manager - Handles session_id and window_id
|
|
411
|
+
*
|
|
412
|
+
* Uses shared StorageManager for consistent storage operations.
|
|
413
|
+
*
|
|
414
|
+
* Session ID: Unique per user session, expires after 30 minutes of inactivity
|
|
415
|
+
* Window ID: Unique per browser tab, persists across page reloads
|
|
416
|
+
*/
|
|
417
|
+
|
|
418
|
+
declare class SessionManager {
|
|
419
|
+
private storage;
|
|
420
|
+
private _windowId;
|
|
421
|
+
constructor(storageMethod?: PersistenceMethod, cross_subdomain?: boolean);
|
|
422
|
+
/**
|
|
423
|
+
* Get session ID (always returns a value, generates if needed)
|
|
424
|
+
*/
|
|
425
|
+
getSessionId(): string;
|
|
426
|
+
/**
|
|
427
|
+
* Set session ID in storage
|
|
428
|
+
* Extends TTL if session_id exists, generates new one if not
|
|
429
|
+
*/
|
|
430
|
+
setSessionId(): string;
|
|
431
|
+
/**
|
|
432
|
+
* Reset session ID (generates new session on reset)
|
|
433
|
+
*/
|
|
434
|
+
resetSessionId(): void;
|
|
435
|
+
/**
|
|
436
|
+
* Get session ID from storage (raw, can return null)
|
|
437
|
+
* Cookie Max-Age handles expiration automatically
|
|
438
|
+
*/
|
|
439
|
+
private _getSessionIdRaw;
|
|
440
|
+
/**
|
|
441
|
+
* Store session ID
|
|
442
|
+
* Uses plain string format - cookie Max-Age handles expiration
|
|
443
|
+
*/
|
|
444
|
+
private _storeSessionId;
|
|
445
|
+
/**
|
|
446
|
+
* Clear session ID from storage
|
|
447
|
+
*/
|
|
448
|
+
private _clearSessionId;
|
|
449
|
+
/**
|
|
450
|
+
* Get window ID
|
|
451
|
+
* Window ID is unique per browser tab/window and persists across page reloads
|
|
452
|
+
* Always returns a window_id (generates one if not set)
|
|
453
|
+
*/
|
|
454
|
+
getWindowId(): string;
|
|
455
|
+
/**
|
|
456
|
+
* Set window ID
|
|
457
|
+
* Stores in sessionStorage which is unique per tab
|
|
458
|
+
*/
|
|
459
|
+
private _setWindowId;
|
|
460
|
+
/**
|
|
461
|
+
* Initialize window ID
|
|
462
|
+
* Detects tab duplication and handles window_id persistence
|
|
463
|
+
*/
|
|
464
|
+
private _initializeWindowId;
|
|
465
|
+
/**
|
|
466
|
+
* Listen to window unload to clear primary window flag
|
|
467
|
+
* This helps distinguish between page reloads and tab duplication
|
|
468
|
+
*/
|
|
469
|
+
private _listenToUnload;
|
|
470
|
+
/**
|
|
471
|
+
* Update storage method at runtime
|
|
472
|
+
*/
|
|
473
|
+
updateStorageMethod(method: PersistenceMethod, cross_subdomain?: boolean): void;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* User Manager - Handles user identity and properties
|
|
478
|
+
*
|
|
479
|
+
* Uses shared StorageManager for consistent storage operations.
|
|
480
|
+
*
|
|
481
|
+
* Manages:
|
|
482
|
+
* - anonymous_id: Generated ID for anonymous users
|
|
483
|
+
* - distinct_id: User-provided ID after identification
|
|
484
|
+
* - device_id: Persistent device identifier
|
|
485
|
+
* - user_properties: Custom properties set via identify/setUserProperties
|
|
486
|
+
* - user_state: "anonymous" or "identified"
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
declare class UserManager {
|
|
490
|
+
private storage;
|
|
491
|
+
private userIdentity;
|
|
492
|
+
private _cachedPersonProperties;
|
|
493
|
+
constructor(storageMethod?: PersistenceMethod, cross_subdomain?: boolean);
|
|
494
|
+
/**
|
|
495
|
+
* Get current user identity
|
|
496
|
+
*/
|
|
497
|
+
getUserIdentity(): UserIdentity;
|
|
498
|
+
/**
|
|
499
|
+
* Get current distinct ID (identified user ID)
|
|
500
|
+
*/
|
|
501
|
+
getDistinctId(): string | null;
|
|
502
|
+
/**
|
|
503
|
+
* Get current anonymous ID
|
|
504
|
+
*/
|
|
505
|
+
getAnonymousId(): string;
|
|
506
|
+
/**
|
|
507
|
+
* Get current user properties
|
|
508
|
+
*/
|
|
509
|
+
getUserProperties(): Record<string, any>;
|
|
510
|
+
/**
|
|
511
|
+
* Get the effective ID for event tracking
|
|
512
|
+
*/
|
|
513
|
+
getEffectiveId(): string;
|
|
514
|
+
/**
|
|
515
|
+
* Get current device ID
|
|
516
|
+
*/
|
|
517
|
+
getDeviceId(): string;
|
|
518
|
+
/**
|
|
519
|
+
* Get current user state
|
|
520
|
+
*/
|
|
521
|
+
getUserState(): "anonymous" | "identified";
|
|
522
|
+
/**
|
|
523
|
+
* Identify a user with distinct ID and properties
|
|
524
|
+
*/
|
|
525
|
+
identify(newDistinctId?: string, userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
526
|
+
/**
|
|
527
|
+
* Set user properties without changing distinct ID
|
|
528
|
+
*/
|
|
529
|
+
setUserProperties(userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): boolean;
|
|
530
|
+
/**
|
|
531
|
+
* Reset user identity (logout)
|
|
532
|
+
* Generates new anonymous ID, clears user data, optionally resets device ID
|
|
533
|
+
*/
|
|
534
|
+
reset(reset_device_id?: boolean): void;
|
|
535
|
+
/**
|
|
536
|
+
* Update distinct ID (internal use - for VTilt)
|
|
537
|
+
*/
|
|
538
|
+
setDistinctId(distinctId: string): void;
|
|
539
|
+
/**
|
|
540
|
+
* Update user state (internal use - for VTilt)
|
|
541
|
+
*/
|
|
542
|
+
setUserState(state: "anonymous" | "identified"): void;
|
|
543
|
+
/**
|
|
544
|
+
* Update user properties (internal use - for VTilt)
|
|
545
|
+
*/
|
|
546
|
+
updateUserProperties(userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
547
|
+
/**
|
|
548
|
+
* Set device ID if not already set (internal use - for VTilt)
|
|
549
|
+
*/
|
|
550
|
+
ensureDeviceId(deviceId: string): void;
|
|
551
|
+
/**
|
|
552
|
+
* Create an alias to link two distinct IDs
|
|
553
|
+
*/
|
|
554
|
+
createAlias(alias: string, original?: string): AliasEvent | null;
|
|
555
|
+
/**
|
|
556
|
+
* Check if distinct ID is string-like (hardcoded string) - public for validation
|
|
557
|
+
*/
|
|
558
|
+
isDistinctIdStringLikePublic(distinctId: string): boolean;
|
|
559
|
+
/**
|
|
560
|
+
* Set initial person info
|
|
561
|
+
*/
|
|
562
|
+
set_initial_person_info(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[]): void;
|
|
563
|
+
/**
|
|
564
|
+
* Get initial props
|
|
565
|
+
*/
|
|
566
|
+
get_initial_props(): Record<string, any>;
|
|
567
|
+
/**
|
|
568
|
+
* Update referrer info
|
|
569
|
+
*/
|
|
570
|
+
update_referrer_info(): void;
|
|
571
|
+
/**
|
|
572
|
+
* Load user identity from storage.
|
|
573
|
+
*
|
|
574
|
+
* For traditional SSR websites where each page navigation reloads JavaScript,
|
|
575
|
+
* identity MUST be persisted immediately when generated to ensure the same
|
|
576
|
+
* anonymous_id is used across all page loads.
|
|
577
|
+
*
|
|
578
|
+
* Flow:
|
|
579
|
+
* 1. Load from storage (reads cookies first for critical properties in SSR mode)
|
|
580
|
+
* 2. Generate new IDs if not found
|
|
581
|
+
* 3. Immediately persist to storage (saved to both localStorage and cookies)
|
|
582
|
+
*
|
|
583
|
+
* With `localStorage+cookie` persistence (default):
|
|
584
|
+
* - Critical properties are stored in cookies for SSR compatibility
|
|
585
|
+
* - Full data is stored in localStorage for fast SPA-style access
|
|
586
|
+
* - Cookies ensure identity persists across full page reloads
|
|
587
|
+
*/
|
|
588
|
+
private loadUserIdentity;
|
|
589
|
+
/**
|
|
590
|
+
* Save user identity to storage
|
|
591
|
+
*/
|
|
592
|
+
private saveUserIdentity;
|
|
593
|
+
/**
|
|
594
|
+
* Get user properties from storage
|
|
595
|
+
*/
|
|
596
|
+
private getStoredUserProperties;
|
|
597
|
+
/**
|
|
598
|
+
* Set user properties in storage
|
|
599
|
+
*/
|
|
600
|
+
private setStoredUserProperties;
|
|
601
|
+
/**
|
|
602
|
+
* Register a value once (only if not already set)
|
|
603
|
+
*/
|
|
604
|
+
private register_once;
|
|
605
|
+
/**
|
|
606
|
+
* Generate a new anonymous ID
|
|
607
|
+
*/
|
|
608
|
+
private generateAnonymousId;
|
|
609
|
+
/**
|
|
610
|
+
* Generate a new device ID
|
|
611
|
+
*/
|
|
612
|
+
private generateDeviceId;
|
|
613
|
+
/**
|
|
614
|
+
* Get hash for person properties (for deduplication)
|
|
615
|
+
*/
|
|
616
|
+
private getPersonPropertiesHash;
|
|
617
|
+
/**
|
|
618
|
+
* Validate distinct ID
|
|
619
|
+
*/
|
|
620
|
+
private isValidDistinctId;
|
|
621
|
+
/**
|
|
622
|
+
* Check if distinct ID is string-like (hardcoded string)
|
|
623
|
+
*/
|
|
624
|
+
private isDistinctIdStringLike;
|
|
625
|
+
/**
|
|
626
|
+
* Update storage method at runtime
|
|
627
|
+
*/
|
|
628
|
+
updateStorageMethod(method: PersistenceMethod, cross_subdomain?: boolean): void;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Feature Interface & Base Class
|
|
633
|
+
*
|
|
634
|
+
* Standard interface that all vTilt features implement.
|
|
635
|
+
* Provides consistent lifecycle management and self-contained configuration.
|
|
636
|
+
*
|
|
637
|
+
* Design Principles:
|
|
638
|
+
* 1. Features are self-contained - they extract their own config
|
|
639
|
+
* 2. Features implement a common interface - vtilt.ts doesn't need to know details
|
|
640
|
+
* 3. Features handle their own errors - using safewrap utilities
|
|
641
|
+
* 4. Features can communicate via events - using the event emitter
|
|
642
|
+
*
|
|
643
|
+
* Based on PostHog's convention patterns, formalized as TypeScript interfaces.
|
|
644
|
+
*/
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Feature interface that all vTilt features should implement.
|
|
648
|
+
* Provides a consistent lifecycle for feature initialization and management.
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* ```typescript
|
|
652
|
+
* class MyFeature implements Feature {
|
|
653
|
+
* static extractConfig(config: VTiltConfig): MyFeatureConfig {
|
|
654
|
+
* return { enabled: !!config.myFeature };
|
|
655
|
+
* }
|
|
656
|
+
*
|
|
657
|
+
* get isEnabled(): boolean { return this._config.enabled; }
|
|
658
|
+
* get isStarted(): boolean { return this._started; }
|
|
659
|
+
*
|
|
660
|
+
* startIfEnabled(): void {
|
|
661
|
+
* if (this.isEnabled && !this._started) {
|
|
662
|
+
* this._start();
|
|
663
|
+
* }
|
|
664
|
+
* }
|
|
665
|
+
*
|
|
666
|
+
* stop(): void {
|
|
667
|
+
* if (this._started) {
|
|
668
|
+
* this._cleanup();
|
|
669
|
+
* this._started = false;
|
|
670
|
+
* }
|
|
671
|
+
* }
|
|
672
|
+
* }
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
interface Feature {
|
|
676
|
+
/**
|
|
677
|
+
* Feature name for logging and debugging.
|
|
678
|
+
*/
|
|
679
|
+
readonly name: string;
|
|
680
|
+
/**
|
|
681
|
+
* Check if the feature is enabled based on current configuration.
|
|
682
|
+
* Features should check both local config and remote config.
|
|
683
|
+
*/
|
|
684
|
+
readonly isEnabled: boolean;
|
|
685
|
+
/**
|
|
686
|
+
* Check if the feature is currently started/active.
|
|
687
|
+
*/
|
|
688
|
+
readonly isStarted: boolean;
|
|
689
|
+
/**
|
|
690
|
+
* Start the feature if it's enabled, otherwise do nothing.
|
|
691
|
+
* This is the primary lifecycle method called during initialization.
|
|
692
|
+
*
|
|
693
|
+
* Safe to call multiple times - should be idempotent.
|
|
694
|
+
*/
|
|
695
|
+
startIfEnabled(): void;
|
|
696
|
+
/**
|
|
697
|
+
* Stop the feature and clean up any resources (event listeners, timers, etc.).
|
|
698
|
+
* Safe to call multiple times - should be idempotent.
|
|
699
|
+
*/
|
|
700
|
+
stop(): void;
|
|
701
|
+
/**
|
|
702
|
+
* Handle VTilt configuration updates.
|
|
703
|
+
* Called when the main VTilt config is updated via updateConfig().
|
|
704
|
+
*
|
|
705
|
+
* Features should re-evaluate their enabled state and start/stop accordingly.
|
|
706
|
+
*
|
|
707
|
+
* @param config - The new VTilt configuration
|
|
708
|
+
*/
|
|
709
|
+
onConfigUpdate?(config: VTiltConfig): void;
|
|
710
|
+
/**
|
|
711
|
+
* Handle remote configuration updates from /decide endpoint.
|
|
712
|
+
* Called when new remote config is received from the server.
|
|
713
|
+
*
|
|
714
|
+
* Features can use this to enable/disable themselves based on server settings.
|
|
715
|
+
*
|
|
716
|
+
* @param remoteConfig - The remote configuration response
|
|
717
|
+
*/
|
|
718
|
+
onRemoteConfig?(remoteConfig: RemoteConfig): void;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Feature with the startIfEnabledOrStop pattern.
|
|
722
|
+
* Used for features that should stop when disabled (not just stay stopped).
|
|
723
|
+
*
|
|
724
|
+
* Example: Session recording should stop if disabled mid-session.
|
|
725
|
+
*/
|
|
726
|
+
interface ToggleableFeature extends Feature {
|
|
727
|
+
/**
|
|
728
|
+
* Start the feature if enabled, or stop it if disabled.
|
|
729
|
+
* More aggressive than startIfEnabled - actively stops if conditions change.
|
|
730
|
+
*
|
|
731
|
+
* @param trigger - Optional trigger name for debugging
|
|
732
|
+
*/
|
|
733
|
+
startIfEnabledOrStop(trigger?: string): void;
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Base configuration that all features receive.
|
|
737
|
+
* Features extend this for their specific config needs.
|
|
738
|
+
*/
|
|
739
|
+
interface FeatureConfig {
|
|
740
|
+
/** Whether the feature is enabled */
|
|
741
|
+
enabled?: boolean;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Web Vitals Manager
|
|
746
|
+
*
|
|
747
|
+
* Captures Core Web Vitals (LCP, CLS, FCP, INP, TTFB) and sends them
|
|
748
|
+
* as batched $web_vitals events. Implements the Feature interface for
|
|
749
|
+
* consistent lifecycle management.
|
|
750
|
+
*
|
|
751
|
+
* Follows PostHog's approach with:
|
|
752
|
+
* 1. Extension pattern - checks for callbacks registered on __VTiltExtensions__
|
|
753
|
+
* 2. Lazy loading - loads web-vitals.js on demand if not bundled
|
|
754
|
+
* 3. Configurable metrics - choose which metrics to capture
|
|
755
|
+
* 4. Smart buffering - collects metrics per page, flushes on navigation or timeout
|
|
756
|
+
* 5. Session context - includes session_id and window_id for correlation
|
|
757
|
+
*
|
|
758
|
+
* Event structure:
|
|
759
|
+
* - event: "$web_vitals"
|
|
760
|
+
* - properties:
|
|
761
|
+
* - $web_vitals_LCP_value: number
|
|
762
|
+
* - $web_vitals_LCP_event: { name, value, delta, rating, ... }
|
|
763
|
+
* - $pathname: string
|
|
764
|
+
* - $current_url: string
|
|
765
|
+
*/
|
|
766
|
+
|
|
767
|
+
declare class WebVitalsManager implements Feature {
|
|
768
|
+
readonly name = "WebVitals";
|
|
769
|
+
private _instance;
|
|
770
|
+
private _buffer;
|
|
771
|
+
private _flushTimer;
|
|
772
|
+
private _isStarted;
|
|
773
|
+
private _config;
|
|
774
|
+
/**
|
|
775
|
+
* Extract web vitals config from VTiltConfig (self-contained)
|
|
776
|
+
*/
|
|
777
|
+
static extractConfig(config: VTiltConfig): CapturePerformanceConfig;
|
|
778
|
+
constructor(instance: VTilt);
|
|
779
|
+
/**
|
|
780
|
+
* Check if web vitals capture is enabled
|
|
781
|
+
*/
|
|
782
|
+
get isEnabled(): boolean;
|
|
783
|
+
/**
|
|
784
|
+
* Check if capturing has started
|
|
785
|
+
*/
|
|
786
|
+
get isStarted(): boolean;
|
|
787
|
+
/**
|
|
788
|
+
* Start capturing if enabled
|
|
789
|
+
*/
|
|
790
|
+
startIfEnabled(): void;
|
|
791
|
+
/**
|
|
792
|
+
* Stop capturing (flushes any pending metrics)
|
|
793
|
+
*/
|
|
794
|
+
stop(): void;
|
|
795
|
+
/**
|
|
796
|
+
* Handle config update
|
|
797
|
+
*/
|
|
798
|
+
onConfigUpdate(config: VTiltConfig): void;
|
|
799
|
+
/**
|
|
800
|
+
* Get the list of metrics to capture
|
|
801
|
+
*/
|
|
802
|
+
get allowedMetrics(): SupportedWebVitalsMetric[];
|
|
803
|
+
/**
|
|
804
|
+
* Get flush timeout in ms
|
|
805
|
+
*/
|
|
806
|
+
get flushTimeoutMs(): number;
|
|
807
|
+
/**
|
|
808
|
+
* Get maximum allowed metric value
|
|
809
|
+
*/
|
|
810
|
+
get maxAllowedValue(): number;
|
|
811
|
+
private _createEmptyBuffer;
|
|
812
|
+
private _getWebVitalsCallbacks;
|
|
813
|
+
private _loadWebVitals;
|
|
814
|
+
private _startCapturing;
|
|
815
|
+
private _getCurrentUrl;
|
|
816
|
+
private _getCurrentPathname;
|
|
817
|
+
private _addToBuffer;
|
|
818
|
+
private _cleanAttribution;
|
|
819
|
+
private _getWindowId;
|
|
820
|
+
private _scheduleFlush;
|
|
821
|
+
private _flush;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* History Autocapture
|
|
826
|
+
*
|
|
827
|
+
* Captures pageview events when the user navigates using the History API
|
|
828
|
+
* (pushState, replaceState) or browser back/forward buttons.
|
|
829
|
+
*
|
|
830
|
+
* Implements the Feature interface for consistent lifecycle management.
|
|
831
|
+
*/
|
|
832
|
+
|
|
833
|
+
interface HistoryAutocaptureConfig extends FeatureConfig {
|
|
834
|
+
/** Whether to capture pageviews on history changes */
|
|
835
|
+
enabled?: boolean;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* History Autocapture Feature
|
|
839
|
+
*
|
|
840
|
+
* Automatically captures $pageview events on SPA navigation.
|
|
841
|
+
* Implements the Feature interface for consistent lifecycle management.
|
|
364
842
|
*/
|
|
365
|
-
declare class HistoryAutocapture {
|
|
843
|
+
declare class HistoryAutocapture implements Feature {
|
|
844
|
+
readonly name = "HistoryAutocapture";
|
|
366
845
|
private _instance;
|
|
846
|
+
private _config;
|
|
847
|
+
private _isStarted;
|
|
367
848
|
private _popstateListener;
|
|
368
849
|
private _lastPathname;
|
|
369
|
-
constructor(instance: VTilt);
|
|
850
|
+
constructor(instance: VTilt, config?: HistoryAutocaptureConfig);
|
|
851
|
+
/**
|
|
852
|
+
* Extract history autocapture config from VTiltConfig.
|
|
853
|
+
* Self-contained - vtilt.ts doesn't need to know config details.
|
|
854
|
+
*/
|
|
855
|
+
static extractConfig(config: VTiltConfig): HistoryAutocaptureConfig;
|
|
370
856
|
get isEnabled(): boolean;
|
|
857
|
+
get isStarted(): boolean;
|
|
371
858
|
startIfEnabled(): void;
|
|
372
859
|
stop(): void;
|
|
373
|
-
|
|
374
|
-
private
|
|
860
|
+
onConfigUpdate(config: VTiltConfig): void;
|
|
861
|
+
private _start;
|
|
862
|
+
private _patchHistoryMethods;
|
|
375
863
|
private _setupPopstateListener;
|
|
864
|
+
private _capturePageview;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Autocapture Types
|
|
869
|
+
*
|
|
870
|
+
* Type definitions for the DOM autocapture feature.
|
|
871
|
+
* Following PostHog's patterns for element capture and privacy.
|
|
872
|
+
*/
|
|
873
|
+
/**
|
|
874
|
+
* Autocapture configuration options
|
|
875
|
+
* Controls what events and elements are captured
|
|
876
|
+
*/
|
|
877
|
+
interface AutocaptureConfig {
|
|
878
|
+
/**
|
|
879
|
+
* Enable autocapture (default: true when autocapture config is present)
|
|
880
|
+
*/
|
|
881
|
+
enabled?: boolean;
|
|
882
|
+
/**
|
|
883
|
+
* URL patterns to allow autocapture on (default: all URLs)
|
|
884
|
+
* Supports strings (exact match) and RegExp patterns
|
|
885
|
+
*/
|
|
886
|
+
url_allowlist?: (string | RegExp)[];
|
|
887
|
+
/**
|
|
888
|
+
* URL patterns to exclude from autocapture
|
|
889
|
+
* Supports strings (exact match) and RegExp patterns
|
|
890
|
+
*/
|
|
891
|
+
url_ignorelist?: (string | RegExp)[];
|
|
892
|
+
/**
|
|
893
|
+
* DOM events to capture (default: ['click', 'change', 'submit'])
|
|
894
|
+
*/
|
|
895
|
+
dom_event_allowlist?: AutocaptureEventType[];
|
|
896
|
+
/**
|
|
897
|
+
* Element tags to capture (default: ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'])
|
|
898
|
+
*/
|
|
899
|
+
element_allowlist?: string[];
|
|
900
|
+
/**
|
|
901
|
+
* CSS selectors to allow for capture (elements matching these are always captured)
|
|
902
|
+
* Example: ['[data-track]', '.track-click']
|
|
903
|
+
*/
|
|
904
|
+
css_selector_allowlist?: string[];
|
|
905
|
+
/**
|
|
906
|
+
* Element attributes to exclude from capture
|
|
907
|
+
* Example: ['data-secret', 'aria-label']
|
|
908
|
+
*/
|
|
909
|
+
element_attribute_ignorelist?: string[];
|
|
910
|
+
/**
|
|
911
|
+
* Capture text content from copy/cut events (default: false)
|
|
912
|
+
*/
|
|
913
|
+
capture_copied_text?: boolean;
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Supported DOM event types for autocapture
|
|
917
|
+
*/
|
|
918
|
+
type AutocaptureEventType = "click" | "change" | "submit";
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* Autocapture
|
|
922
|
+
*
|
|
923
|
+
* Automatic DOM event capture for clicks, form submissions, and input changes.
|
|
924
|
+
* Following PostHog's privacy-first approach with element chain tracking.
|
|
925
|
+
*/
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Autocapture class for automatic DOM event tracking.
|
|
929
|
+
* Implements the Feature interface for consistent lifecycle management.
|
|
930
|
+
*/
|
|
931
|
+
declare class Autocapture implements Feature {
|
|
932
|
+
readonly name = "Autocapture";
|
|
933
|
+
private _instance;
|
|
934
|
+
private _config;
|
|
935
|
+
private _isStarted;
|
|
936
|
+
private _eventHandlers;
|
|
937
|
+
constructor(instance: VTilt, config?: AutocaptureConfig);
|
|
938
|
+
/**
|
|
939
|
+
* Extract autocapture config from VTiltConfig.
|
|
940
|
+
* This allows the feature to be self-contained - vtilt.ts doesn't need
|
|
941
|
+
* to know about autocapture-specific config transformations.
|
|
942
|
+
*/
|
|
943
|
+
static extractConfig(config: VTiltConfig): AutocaptureConfig;
|
|
944
|
+
/**
|
|
945
|
+
* Check if autocapture is enabled
|
|
946
|
+
*/
|
|
947
|
+
get isEnabled(): boolean;
|
|
948
|
+
/**
|
|
949
|
+
* Check if autocapture is currently active
|
|
950
|
+
*/
|
|
951
|
+
get isStarted(): boolean;
|
|
952
|
+
/**
|
|
953
|
+
* Start autocapture if enabled (Feature interface)
|
|
954
|
+
*/
|
|
955
|
+
startIfEnabled(): void;
|
|
956
|
+
/**
|
|
957
|
+
* Stop autocapture (Feature interface)
|
|
958
|
+
*/
|
|
959
|
+
stop(): void;
|
|
960
|
+
/**
|
|
961
|
+
* Handle config updates (Feature interface)
|
|
962
|
+
*/
|
|
963
|
+
onConfigUpdate(config: VTiltConfig): void;
|
|
964
|
+
/**
|
|
965
|
+
* Update autocapture configuration
|
|
966
|
+
*/
|
|
967
|
+
updateConfig(config: Partial<AutocaptureConfig>): void;
|
|
968
|
+
/**
|
|
969
|
+
* Start autocapture
|
|
970
|
+
*/
|
|
971
|
+
private _start;
|
|
972
|
+
/**
|
|
973
|
+
* Add DOM event handlers
|
|
974
|
+
*/
|
|
975
|
+
private _addEventHandlers;
|
|
976
|
+
/**
|
|
977
|
+
* Remove DOM event handlers
|
|
978
|
+
*/
|
|
979
|
+
private _removeEventHandlers;
|
|
980
|
+
/**
|
|
981
|
+
* Create event handler for a specific event type
|
|
982
|
+
*/
|
|
983
|
+
private _createEventHandler;
|
|
984
|
+
/**
|
|
985
|
+
* Capture a DOM event
|
|
986
|
+
*/
|
|
987
|
+
private _captureEvent;
|
|
988
|
+
/**
|
|
989
|
+
* Build properties for an autocapture event
|
|
990
|
+
*/
|
|
991
|
+
private _buildEventProperties;
|
|
992
|
+
/**
|
|
993
|
+
* Add element-specific properties
|
|
994
|
+
*/
|
|
995
|
+
private _addElementSpecificProps;
|
|
996
|
+
/**
|
|
997
|
+
* Add event-specific properties
|
|
998
|
+
*/
|
|
999
|
+
private _addEventSpecificProps;
|
|
376
1000
|
}
|
|
377
1001
|
|
|
378
1002
|
/**
|
|
@@ -457,7 +1081,7 @@ interface SessionRecordingConfig {
|
|
|
457
1081
|
__mutationThrottlerBucketSize?: number;
|
|
458
1082
|
}
|
|
459
1083
|
/** Recording start reason */
|
|
460
|
-
type SessionStartReason = "recording_initialized" | "session_id_changed" | "linked_flag_matched" | "linked_flag_overridden" | "sampling_overridden" | "url_trigger_matched" | "event_trigger_matched" | "sampled";
|
|
1084
|
+
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";
|
|
461
1085
|
|
|
462
1086
|
/**
|
|
463
1087
|
* Chat message structure (matches PostgreSQL chat_messages table)
|
|
@@ -596,6 +1220,7 @@ interface ChatTheme {
|
|
|
596
1220
|
* The actual recording logic is in LazyLoadedSessionRecording which is
|
|
597
1221
|
* loaded on demand.
|
|
598
1222
|
*
|
|
1223
|
+
* Implements the ToggleableFeature interface for consistent lifecycle management.
|
|
599
1224
|
* Based on PostHog's sessionrecording-wrapper.ts
|
|
600
1225
|
*/
|
|
601
1226
|
|
|
@@ -608,43 +1233,71 @@ type SessionRecordingStatus = "disabled" | "buffering" | "active" | "paused" | "
|
|
|
608
1233
|
* Session Recording Wrapper
|
|
609
1234
|
*
|
|
610
1235
|
* This is the lightweight class that lives in the main bundle.
|
|
1236
|
+
* Implements ToggleableFeature for consistent lifecycle management.
|
|
1237
|
+
*
|
|
611
1238
|
* It handles:
|
|
612
1239
|
* - Deciding if recording should be enabled
|
|
613
1240
|
* - Lazy loading the actual recording code
|
|
614
1241
|
* - Delegating to LazyLoadedSessionRecording
|
|
615
1242
|
*/
|
|
616
|
-
declare class SessionRecordingWrapper {
|
|
1243
|
+
declare class SessionRecordingWrapper implements ToggleableFeature {
|
|
617
1244
|
private readonly _instance;
|
|
1245
|
+
readonly name = "SessionRecording";
|
|
618
1246
|
private _lazyLoadedRecording;
|
|
619
1247
|
private _config;
|
|
1248
|
+
private _isStarted;
|
|
620
1249
|
constructor(_instance: VTilt, config?: SessionRecordingConfig);
|
|
1250
|
+
/**
|
|
1251
|
+
* Extract session recording config from VTiltConfig.
|
|
1252
|
+
* Self-contained - vtilt.ts doesn't need to know config details.
|
|
1253
|
+
*/
|
|
1254
|
+
static extractConfig(config: VTiltConfig): SessionRecordingConfig;
|
|
1255
|
+
get isEnabled(): boolean;
|
|
1256
|
+
get isStarted(): boolean;
|
|
1257
|
+
/**
|
|
1258
|
+
* Start if enabled (Feature interface).
|
|
1259
|
+
* Use startIfEnabledOrStop for recording as it needs to actively stop.
|
|
1260
|
+
*/
|
|
1261
|
+
startIfEnabled(): void;
|
|
1262
|
+
/**
|
|
1263
|
+
* Start if enabled, or stop if disabled (ToggleableFeature interface).
|
|
1264
|
+
* This is the primary method for session recording.
|
|
1265
|
+
*/
|
|
1266
|
+
startIfEnabledOrStop(trigger?: SessionStartReason): void;
|
|
1267
|
+
/**
|
|
1268
|
+
* Stop recording (Feature interface).
|
|
1269
|
+
*/
|
|
1270
|
+
stop(): void;
|
|
1271
|
+
/**
|
|
1272
|
+
* Handle config updates (Feature interface).
|
|
1273
|
+
*/
|
|
1274
|
+
onConfigUpdate(config: VTiltConfig): void;
|
|
1275
|
+
/**
|
|
1276
|
+
* Handle remote config updates (Feature interface).
|
|
1277
|
+
*/
|
|
1278
|
+
onRemoteConfig(remoteConfig: RemoteConfig): void;
|
|
621
1279
|
get started(): boolean;
|
|
622
1280
|
get status(): SessionRecordingStatus;
|
|
623
1281
|
get sessionId(): string;
|
|
624
1282
|
/**
|
|
625
|
-
*
|
|
626
|
-
*/
|
|
627
|
-
startIfEnabledOrStop(startReason?: SessionStartReason): void;
|
|
628
|
-
/**
|
|
629
|
-
* Stop recording
|
|
1283
|
+
* Alias for stop() for backwards compatibility.
|
|
630
1284
|
*/
|
|
631
1285
|
stopRecording(): void;
|
|
632
1286
|
/**
|
|
633
|
-
* Log a message to the recording
|
|
1287
|
+
* Log a message to the recording.
|
|
634
1288
|
*/
|
|
635
1289
|
log(message: string, level?: "log" | "warn" | "error"): void;
|
|
636
1290
|
/**
|
|
637
|
-
* Update configuration
|
|
1291
|
+
* Update configuration.
|
|
638
1292
|
*/
|
|
639
1293
|
updateConfig(config: Partial<SessionRecordingConfig>): void;
|
|
640
|
-
private get _isRecordingEnabled();
|
|
641
1294
|
private get _scriptName();
|
|
642
1295
|
/**
|
|
643
|
-
* Lazy load the recording script and start
|
|
1296
|
+
* Lazy load the recording script and start.
|
|
644
1297
|
*/
|
|
645
1298
|
private _lazyLoadAndStart;
|
|
646
1299
|
/**
|
|
647
|
-
* Called after the recording script is loaded
|
|
1300
|
+
* Called after the recording script is loaded.
|
|
648
1301
|
*/
|
|
649
1302
|
private _onScriptLoaded;
|
|
650
1303
|
}
|
|
@@ -664,12 +1317,14 @@ type ConnectionCallback = (connected: boolean) => void;
|
|
|
664
1317
|
/**
|
|
665
1318
|
* Unsubscribe function type
|
|
666
1319
|
*/
|
|
667
|
-
type Unsubscribe = () => void;
|
|
1320
|
+
type Unsubscribe$1 = () => void;
|
|
668
1321
|
|
|
669
1322
|
/**
|
|
670
1323
|
* Chat Wrapper
|
|
671
1324
|
*
|
|
672
1325
|
* This is the lightweight class that lives in the main bundle.
|
|
1326
|
+
* Implements Feature for consistent lifecycle management.
|
|
1327
|
+
*
|
|
673
1328
|
* It handles:
|
|
674
1329
|
* - Auto-fetching settings from dashboard (Intercom-like)
|
|
675
1330
|
* - Merging server settings with code config
|
|
@@ -678,13 +1333,15 @@ type Unsubscribe = () => void;
|
|
|
678
1333
|
* - Delegating to LazyLoadedChat
|
|
679
1334
|
* - Queuing messages/callbacks before widget loads
|
|
680
1335
|
*/
|
|
681
|
-
declare class ChatWrapper {
|
|
1336
|
+
declare class ChatWrapper implements Feature {
|
|
682
1337
|
private readonly _instance;
|
|
1338
|
+
readonly name = "Chat";
|
|
683
1339
|
private _lazyLoadedChat;
|
|
684
1340
|
private _config;
|
|
685
1341
|
private _serverConfig;
|
|
686
1342
|
private _configFetched;
|
|
687
1343
|
private _isLoading;
|
|
1344
|
+
private _isStarted;
|
|
688
1345
|
private _loadError;
|
|
689
1346
|
private _pendingMessages;
|
|
690
1347
|
private _pendingCallbacks;
|
|
@@ -692,6 +1349,34 @@ declare class ChatWrapper {
|
|
|
692
1349
|
private _typingCallbacks;
|
|
693
1350
|
private _connectionCallbacks;
|
|
694
1351
|
constructor(_instance: VTilt, config?: ChatConfig);
|
|
1352
|
+
/**
|
|
1353
|
+
* Extract chat config from VTiltConfig.
|
|
1354
|
+
* Self-contained - vtilt.ts doesn't need to know config details.
|
|
1355
|
+
*/
|
|
1356
|
+
static extractConfig(config: VTiltConfig): ChatConfig;
|
|
1357
|
+
get isEnabled(): boolean;
|
|
1358
|
+
get isStarted(): boolean;
|
|
1359
|
+
/**
|
|
1360
|
+
* Start chat if enabled (Feature interface).
|
|
1361
|
+
* This is async because it may fetch server settings.
|
|
1362
|
+
*/
|
|
1363
|
+
startIfEnabled(): void;
|
|
1364
|
+
/**
|
|
1365
|
+
* Stop the chat widget (Feature interface).
|
|
1366
|
+
*/
|
|
1367
|
+
stop(): void;
|
|
1368
|
+
/**
|
|
1369
|
+
* Handle config updates (Feature interface).
|
|
1370
|
+
*/
|
|
1371
|
+
onConfigUpdate(config: VTiltConfig): void;
|
|
1372
|
+
/**
|
|
1373
|
+
* Handle remote config updates (Feature interface).
|
|
1374
|
+
*/
|
|
1375
|
+
onRemoteConfig(remoteConfig: RemoteConfig): void;
|
|
1376
|
+
/**
|
|
1377
|
+
* Async start implementation
|
|
1378
|
+
*/
|
|
1379
|
+
private _startAsync;
|
|
695
1380
|
/**
|
|
696
1381
|
* Whether the chat widget is open
|
|
697
1382
|
*/
|
|
@@ -767,23 +1452,15 @@ declare class ChatWrapper {
|
|
|
767
1452
|
/**
|
|
768
1453
|
* Subscribe to new messages
|
|
769
1454
|
*/
|
|
770
|
-
onMessage(callback: MessageCallback): Unsubscribe;
|
|
1455
|
+
onMessage(callback: MessageCallback): Unsubscribe$1;
|
|
771
1456
|
/**
|
|
772
1457
|
* Subscribe to typing indicators
|
|
773
1458
|
*/
|
|
774
|
-
onTyping(callback: TypingCallback): Unsubscribe;
|
|
1459
|
+
onTyping(callback: TypingCallback): Unsubscribe$1;
|
|
775
1460
|
/**
|
|
776
1461
|
* Subscribe to connection changes
|
|
777
1462
|
*/
|
|
778
|
-
onConnectionChange(callback: ConnectionCallback): Unsubscribe;
|
|
779
|
-
/**
|
|
780
|
-
* Start chat if enabled, called by VTilt after init
|
|
781
|
-
*
|
|
782
|
-
* This method supports two modes (Intercom-like):
|
|
783
|
-
* 1. Auto-config: Fetch settings from /api/chat/settings (default)
|
|
784
|
-
* 2. Code-only: Use only code config (autoConfig: false)
|
|
785
|
-
*/
|
|
786
|
-
startIfEnabled(): Promise<void>;
|
|
1463
|
+
onConnectionChange(callback: ConnectionCallback): Unsubscribe$1;
|
|
787
1464
|
/**
|
|
788
1465
|
* Update configuration
|
|
789
1466
|
*/
|
|
@@ -796,7 +1473,6 @@ declare class ChatWrapper {
|
|
|
796
1473
|
* Destroy the chat widget
|
|
797
1474
|
*/
|
|
798
1475
|
destroy(): void;
|
|
799
|
-
private get _isChatEnabled();
|
|
800
1476
|
/**
|
|
801
1477
|
* Fetch chat settings from the server
|
|
802
1478
|
* This enables "snippet-only" installation where widget configures from dashboard
|
|
@@ -846,334 +1522,215 @@ interface QueuedRequest {
|
|
|
846
1522
|
transport?: "xhr" | "sendBeacon";
|
|
847
1523
|
}
|
|
848
1524
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
private
|
|
864
|
-
|
|
865
|
-
private
|
|
866
|
-
private
|
|
867
|
-
private
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
/**
|
|
872
|
-
* Initializes a new instance of the VTilt tracking object.
|
|
873
|
-
*
|
|
874
|
-
* @remarks
|
|
875
|
-
* All new instances are added to the main vt object as sub properties (such as
|
|
876
|
-
* `vt.library_name`) and also returned by this function.
|
|
877
|
-
*
|
|
878
|
-
* @example
|
|
879
|
-
* ```js
|
|
880
|
-
* // basic initialization
|
|
881
|
-
* vt.init('<project_id>', {
|
|
882
|
-
* api_host: '<client_api_host>'
|
|
883
|
-
* })
|
|
884
|
-
* ```
|
|
885
|
-
*
|
|
886
|
-
* @example
|
|
887
|
-
* ```js
|
|
888
|
-
* // multiple instances
|
|
889
|
-
* vt.init('<project_id>', {}, 'project1')
|
|
890
|
-
* vt.init('<project_id>', {}, 'project2')
|
|
891
|
-
* ```
|
|
892
|
-
*
|
|
893
|
-
* @public
|
|
894
|
-
*
|
|
895
|
-
* @param projectId - Your VTilt project ID
|
|
896
|
-
* @param config - A dictionary of config options to override
|
|
897
|
-
* @param name - The name for the new VTilt instance that you want created
|
|
1525
|
+
interface RateLimitBucket {
|
|
1526
|
+
tokens: number;
|
|
1527
|
+
last: number;
|
|
1528
|
+
}
|
|
1529
|
+
interface RateLimiterConfig {
|
|
1530
|
+
eventsPerSecond?: number;
|
|
1531
|
+
eventsBurstLimit?: number;
|
|
1532
|
+
persistence?: {
|
|
1533
|
+
get: (key: string) => RateLimitBucket | null;
|
|
1534
|
+
set: (key: string, value: RateLimitBucket) => void;
|
|
1535
|
+
};
|
|
1536
|
+
captureWarning?: (message: string) => void;
|
|
1537
|
+
}
|
|
1538
|
+
declare class RateLimiter {
|
|
1539
|
+
private eventsPerSecond;
|
|
1540
|
+
private eventsBurstLimit;
|
|
1541
|
+
private lastEventRateLimited;
|
|
1542
|
+
private persistence?;
|
|
1543
|
+
private captureWarning?;
|
|
1544
|
+
constructor(config?: RateLimiterConfig);
|
|
1545
|
+
/**
|
|
1546
|
+
* Check if the client should be rate limited
|
|
898
1547
|
*
|
|
899
|
-
* @
|
|
1548
|
+
* @param checkOnly - If true, don't consume a token (just check)
|
|
1549
|
+
* @returns Object with isRateLimited flag and remaining tokens
|
|
900
1550
|
*/
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
*/
|
|
906
|
-
private _init;
|
|
907
|
-
/**
|
|
908
|
-
* Start the request queue if user hasn't opted out
|
|
909
|
-
* Following PostHog's pattern - called from both _init() and _dom_loaded()
|
|
910
|
-
* Safe to call multiple times as enable() is idempotent
|
|
911
|
-
*/
|
|
912
|
-
private _start_queue_if_opted_in;
|
|
913
|
-
/**
|
|
914
|
-
* Set up handler to flush event queue on page unload
|
|
915
|
-
* Uses both beforeunload and pagehide for maximum compatibility
|
|
916
|
-
*/
|
|
917
|
-
private _setup_unload_handler;
|
|
918
|
-
/**
|
|
919
|
-
* Read vt=person_uuid from current URL (tracking link for manually created persons).
|
|
920
|
-
* Stores the value for inclusion in event payload as $vt; removes param from URL via replaceState.
|
|
921
|
-
*/
|
|
922
|
-
private _read_vt_param_from_url;
|
|
923
|
-
/**
|
|
924
|
-
* Load remote config from cache and fetch fresh in background.
|
|
925
|
-
* Uses sessionStorage for per-session caching.
|
|
926
|
-
* Local config always overrides remote config.
|
|
927
|
-
*/
|
|
928
|
-
private _loadRemoteConfig;
|
|
1551
|
+
checkRateLimit(checkOnly?: boolean): {
|
|
1552
|
+
isRateLimited: boolean;
|
|
1553
|
+
remainingTokens: number;
|
|
1554
|
+
};
|
|
929
1555
|
/**
|
|
930
|
-
*
|
|
931
|
-
* Caches response in localStorage for persistence across sessions.
|
|
1556
|
+
* Check if an event should be allowed (consumes a token if allowed)
|
|
932
1557
|
*/
|
|
933
|
-
|
|
1558
|
+
shouldAllowEvent(): boolean;
|
|
934
1559
|
/**
|
|
935
|
-
*
|
|
936
|
-
* Local config takes precedence over remote.
|
|
937
|
-
* Also triggers feature initialization if settings changed after init.
|
|
1560
|
+
* Get remaining tokens without consuming
|
|
938
1561
|
*/
|
|
939
|
-
|
|
1562
|
+
getRemainingTokens(): number;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
/**
|
|
1566
|
+
* Simple Event Emitter
|
|
1567
|
+
*
|
|
1568
|
+
* Lightweight pub/sub system for internal feature communication.
|
|
1569
|
+
* Following PostHog's SimpleEventEmitter pattern.
|
|
1570
|
+
*/
|
|
1571
|
+
/**
|
|
1572
|
+
* Event listener function type
|
|
1573
|
+
*/
|
|
1574
|
+
type EventListener<T = unknown> = (payload: T) => void;
|
|
1575
|
+
/**
|
|
1576
|
+
* Unsubscribe function returned by on()
|
|
1577
|
+
*/
|
|
1578
|
+
type Unsubscribe = () => void;
|
|
1579
|
+
/**
|
|
1580
|
+
* Simple event emitter for internal SDK communication.
|
|
1581
|
+
* Features can emit and listen to events without direct coupling.
|
|
1582
|
+
*
|
|
1583
|
+
* @example
|
|
1584
|
+
* ```typescript
|
|
1585
|
+
* const emitter = new SimpleEventEmitter();
|
|
1586
|
+
*
|
|
1587
|
+
* // Subscribe to events
|
|
1588
|
+
* const unsubscribe = emitter.on('user:identified', (data) => {
|
|
1589
|
+
* console.log('User identified:', data);
|
|
1590
|
+
* });
|
|
1591
|
+
*
|
|
1592
|
+
* // Emit events
|
|
1593
|
+
* emitter.emit('user:identified', { userId: '123' });
|
|
1594
|
+
*
|
|
1595
|
+
* // Unsubscribe when done
|
|
1596
|
+
* unsubscribe();
|
|
1597
|
+
* ```
|
|
1598
|
+
*/
|
|
1599
|
+
declare class SimpleEventEmitter {
|
|
1600
|
+
private _events;
|
|
1601
|
+
private _onceEvents;
|
|
940
1602
|
/**
|
|
941
|
-
*
|
|
942
|
-
* Used for debugging and logging
|
|
1603
|
+
* Subscribe to an event.
|
|
943
1604
|
*
|
|
944
|
-
* @
|
|
1605
|
+
* @param event - Event name to subscribe to
|
|
1606
|
+
* @param listener - Callback function
|
|
1607
|
+
* @returns Unsubscribe function
|
|
945
1608
|
*/
|
|
946
|
-
|
|
947
|
-
/**
|
|
948
|
-
* Get current domain from location
|
|
949
|
-
* Returns full URL format for consistency with dashboard
|
|
950
|
-
*/
|
|
951
|
-
private getCurrentDomain;
|
|
952
|
-
/**
|
|
953
|
-
* Check if tracking is properly configured
|
|
954
|
-
* Returns true if projectId and token are present, false otherwise
|
|
955
|
-
* Logs a warning only once per instance if not configured
|
|
956
|
-
*/
|
|
957
|
-
private _is_configured;
|
|
958
|
-
/**
|
|
959
|
-
* Build the tracking URL with token in query parameters
|
|
960
|
-
*/
|
|
961
|
-
private buildUrl;
|
|
1609
|
+
on<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
|
|
962
1610
|
/**
|
|
963
|
-
*
|
|
964
|
-
*
|
|
965
|
-
*
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
/**
|
|
969
|
-
* Send a batched request with multiple events
|
|
970
|
-
* Called by RequestQueue when flushing
|
|
971
|
-
* Uses RetryQueue for automatic retry on failure
|
|
1611
|
+
* Subscribe to an event once (auto-unsubscribes after first call).
|
|
1612
|
+
*
|
|
1613
|
+
* @param event - Event name to subscribe to
|
|
1614
|
+
* @param listener - Callback function
|
|
1615
|
+
* @returns Unsubscribe function
|
|
972
1616
|
*/
|
|
973
|
-
|
|
1617
|
+
once<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
|
|
974
1618
|
/**
|
|
975
|
-
*
|
|
976
|
-
*
|
|
977
|
-
*
|
|
1619
|
+
* Emit an event to all listeners.
|
|
1620
|
+
*
|
|
1621
|
+
* @param event - Event name to emit
|
|
1622
|
+
* @param payload - Data to pass to listeners
|
|
978
1623
|
*/
|
|
979
|
-
|
|
1624
|
+
emit<T = unknown>(event: string, payload?: T): void;
|
|
980
1625
|
/**
|
|
981
|
-
*
|
|
982
|
-
*
|
|
1626
|
+
* Remove all listeners for an event.
|
|
1627
|
+
*
|
|
1628
|
+
* @param event - Event name (or undefined to remove all)
|
|
983
1629
|
*/
|
|
984
|
-
|
|
1630
|
+
off(event?: string): void;
|
|
985
1631
|
/**
|
|
986
|
-
*
|
|
1632
|
+
* Get the number of listeners for an event.
|
|
1633
|
+
*
|
|
1634
|
+
* @param event - Event name
|
|
1635
|
+
* @returns Number of listeners
|
|
987
1636
|
*/
|
|
988
|
-
|
|
1637
|
+
listenerCount(event: string): number;
|
|
989
1638
|
/**
|
|
990
|
-
*
|
|
991
|
-
* Automatically adds common properties to all events
|
|
992
|
-
* ($current_url, $host, $pathname, $referrer, $referring_domain, $browser, $os, $device, $timezone, etc.)
|
|
993
|
-
* Only properties in EVENT_TO_PERSON_PROPERTIES are copied to person properties
|
|
994
|
-
* Also adds title property for $pageview events only
|
|
1639
|
+
* Check if there are any listeners for an event.
|
|
995
1640
|
*
|
|
996
|
-
* @param
|
|
997
|
-
* @
|
|
998
|
-
* @param options - Optional capture options
|
|
1641
|
+
* @param event - Event name
|
|
1642
|
+
* @returns True if there are listeners
|
|
999
1643
|
*/
|
|
1644
|
+
hasListeners(event: string): boolean;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* VTilt SDK - Main Entry Point
|
|
1649
|
+
*
|
|
1650
|
+
* Privacy-first analytics SDK with modular architecture.
|
|
1651
|
+
* This file is a thin orchestrator that delegates to specialized managers:
|
|
1652
|
+
*
|
|
1653
|
+
* - ConfigManager: Configuration management
|
|
1654
|
+
* - SessionManager: Session and window ID management
|
|
1655
|
+
* - UserManager: User identity and properties
|
|
1656
|
+
* - CaptureManager: Event capture and payload enrichment
|
|
1657
|
+
* - IdentityManager: High-level identity operations
|
|
1658
|
+
* - RemoteConfigManager: Remote configuration from /decide
|
|
1659
|
+
* - FeatureManager: Feature lifecycle management
|
|
1660
|
+
*
|
|
1661
|
+
* @see docs/tracker/README.md for full documentation
|
|
1662
|
+
*/
|
|
1663
|
+
|
|
1664
|
+
declare class VTilt {
|
|
1665
|
+
readonly version = "1.10.0";
|
|
1666
|
+
__loaded: boolean;
|
|
1667
|
+
__request_queue: QueuedRequest[];
|
|
1668
|
+
historyAutocapture?: HistoryAutocapture;
|
|
1669
|
+
autocapture?: Autocapture;
|
|
1670
|
+
sessionRecording?: SessionRecordingWrapper;
|
|
1671
|
+
chat?: ChatWrapper;
|
|
1672
|
+
webVitals?: WebVitalsManager;
|
|
1673
|
+
private configManager;
|
|
1674
|
+
sessionManager: SessionManager;
|
|
1675
|
+
userManager: UserManager;
|
|
1676
|
+
private _captureManager;
|
|
1677
|
+
private _identityManager;
|
|
1678
|
+
private _remoteConfigManager;
|
|
1679
|
+
private _featureManager;
|
|
1680
|
+
private requestQueue;
|
|
1681
|
+
private retryQueue;
|
|
1682
|
+
rateLimiter: RateLimiter;
|
|
1683
|
+
_emitter: SimpleEventEmitter;
|
|
1684
|
+
private _has_warned_about_config;
|
|
1685
|
+
constructor(config?: Partial<VTiltConfig>);
|
|
1686
|
+
init(projectId: string, config?: Partial<VTiltConfig>, name?: string): VTilt;
|
|
1687
|
+
private _init;
|
|
1688
|
+
private _initFeatures;
|
|
1689
|
+
private _initHistoryAutocapture;
|
|
1690
|
+
private _initAutocapture;
|
|
1691
|
+
private _initWebVitals;
|
|
1692
|
+
_initSessionRecording(): void;
|
|
1693
|
+
_initChat(): void;
|
|
1694
|
+
startAutocapture(): void;
|
|
1695
|
+
stopAutocapture(): void;
|
|
1696
|
+
isAutocaptureActive(): boolean;
|
|
1697
|
+
startSessionRecording(): void;
|
|
1698
|
+
stopSessionRecording(): void;
|
|
1699
|
+
isRecordingActive(): boolean;
|
|
1700
|
+
getSessionRecordingId(): string | null;
|
|
1000
1701
|
capture(name: string, payload: EventPayload, options?: {
|
|
1001
1702
|
skip_client_rate_limiting?: boolean;
|
|
1002
1703
|
}): void;
|
|
1003
|
-
/**
|
|
1004
|
-
* Internal capture method that bypasses rate limiting
|
|
1005
|
-
* Used for system events like rate limit warnings
|
|
1006
|
-
*/
|
|
1007
|
-
private _capture_internal;
|
|
1008
|
-
/**
|
|
1009
|
-
* Track a custom event (alias for capture)
|
|
1010
|
-
*/
|
|
1011
1704
|
trackEvent(name: string, payload?: EventPayload): void;
|
|
1012
|
-
/**
|
|
1013
|
-
* Identify a user with property operations
|
|
1014
|
-
* Sends $identify event when transitioning from anonymous to identified
|
|
1015
|
-
* Event's distinct_id is the previous/anonymous ID, new distinct_id is in payload
|
|
1016
|
-
*
|
|
1017
|
-
* @example
|
|
1018
|
-
* ```js
|
|
1019
|
-
* // Basic identify with properties
|
|
1020
|
-
* vTilt.identify('user_123',
|
|
1021
|
-
* { name: 'John Doe', email: 'john@example.com' }, // $set properties
|
|
1022
|
-
* { first_login: new Date().toISOString() } // $set_once properties
|
|
1023
|
-
* )
|
|
1024
|
-
* ```
|
|
1025
|
-
*
|
|
1026
|
-
* @example
|
|
1027
|
-
* ```js
|
|
1028
|
-
* // If no $set is provided, all properties are treated as $set
|
|
1029
|
-
* vTilt.identify('user_123', { name: 'John Doe', email: 'john@example.com' })
|
|
1030
|
-
* ```
|
|
1031
|
-
*/
|
|
1032
1705
|
identify(newDistinctId?: string, userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
1033
|
-
/**
|
|
1034
|
-
* Set user properties
|
|
1035
|
-
* Sets properties on the person profile associated with the current distinct_id
|
|
1036
|
-
*
|
|
1037
|
-
* @example
|
|
1038
|
-
* ```js
|
|
1039
|
-
* // Set properties that can be updated
|
|
1040
|
-
* vTilt.setUserProperties({ name: 'John Doe', email: 'john@example.com' })
|
|
1041
|
-
* ```
|
|
1042
|
-
*
|
|
1043
|
-
* @example
|
|
1044
|
-
* ```js
|
|
1045
|
-
* // Set properties with $set and $set_once operations
|
|
1046
|
-
* vTilt.setUserProperties(
|
|
1047
|
-
* { name: 'John Doe', last_login: new Date().toISOString() }, // $set properties
|
|
1048
|
-
* { first_login: new Date().toISOString() } // $set_once properties
|
|
1049
|
-
* )
|
|
1050
|
-
* ```
|
|
1051
|
-
*
|
|
1052
|
-
* @param userPropertiesToSet Optional: Properties to set (can be updated)
|
|
1053
|
-
* @param userPropertiesToSetOnce Optional: Properties to set once (preserves first value)
|
|
1054
|
-
*/
|
|
1055
1706
|
setUserProperties(userPropertiesToSet?: Record<string, any>, userPropertiesToSetOnce?: Record<string, any>): void;
|
|
1056
|
-
/**
|
|
1057
|
-
* Reset user identity (logout)
|
|
1058
|
-
* Clears all user data, generates new anonymous ID, resets session
|
|
1059
|
-
*
|
|
1060
|
-
* @param reset_device_id - If true, also resets device_id. Default: false
|
|
1061
|
-
*
|
|
1062
|
-
* @example
|
|
1063
|
-
* // Reset on user logout
|
|
1064
|
-
* vtilt.resetUser()
|
|
1065
|
-
*
|
|
1066
|
-
* @example
|
|
1067
|
-
* // Reset and generate new device ID
|
|
1068
|
-
* vtilt.resetUser(true)
|
|
1069
|
-
*/
|
|
1070
1707
|
resetUser(reset_device_id?: boolean): void;
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
*/
|
|
1074
|
-
getUserIdentity(): UserIdentity;
|
|
1075
|
-
/**
|
|
1076
|
-
* Get current device ID
|
|
1077
|
-
*/
|
|
1708
|
+
createAlias(alias: string, original?: string): void;
|
|
1709
|
+
getUserIdentity(): Record<string, any>;
|
|
1078
1710
|
getDeviceId(): string;
|
|
1079
|
-
/**
|
|
1080
|
-
* Get current user state
|
|
1081
|
-
*/
|
|
1082
1711
|
getUserState(): "anonymous" | "identified";
|
|
1083
|
-
/**
|
|
1084
|
-
* Create an alias to link two distinct IDs
|
|
1085
|
-
* Links anonymous session to account on signup
|
|
1086
|
-
*
|
|
1087
|
-
* @param alias - A unique identifier that you want to use for this user in the future
|
|
1088
|
-
* @param original - The current identifier being used for this user (optional, defaults to current distinct_id)
|
|
1089
|
-
*
|
|
1090
|
-
* @example
|
|
1091
|
-
* // Link anonymous user to account on signup
|
|
1092
|
-
* vtilt.createAlias('user_12345')
|
|
1093
|
-
*
|
|
1094
|
-
* @example
|
|
1095
|
-
* // Explicit alias with original ID
|
|
1096
|
-
* vtilt.createAlias('user_12345', 'anonymous_abc123')
|
|
1097
|
-
*/
|
|
1098
|
-
createAlias(alias: string, original?: string): void;
|
|
1099
|
-
/**
|
|
1100
|
-
* Capture initial pageview with visibility check
|
|
1101
|
-
* Note: The capture_pageview config check happens at the call site (in _init)
|
|
1102
|
-
*/
|
|
1103
|
-
private _capture_initial_pageview;
|
|
1104
|
-
/**
|
|
1105
|
-
* Get current configuration
|
|
1106
|
-
*/
|
|
1107
1712
|
getConfig(): VTiltConfig;
|
|
1108
|
-
/**
|
|
1109
|
-
* Get current session ID
|
|
1110
|
-
*/
|
|
1111
1713
|
getSessionId(): string | null;
|
|
1112
|
-
/**
|
|
1113
|
-
* Get current distinct ID
|
|
1114
|
-
*/
|
|
1115
1714
|
getDistinctId(): string;
|
|
1116
|
-
/**
|
|
1117
|
-
* Get anonymous ID
|
|
1118
|
-
*/
|
|
1119
1715
|
getAnonymousId(): string;
|
|
1120
|
-
|
|
1121
|
-
* Update configuration
|
|
1122
|
-
*/
|
|
1716
|
+
toString(): string;
|
|
1123
1717
|
updateConfig(config: Partial<VTiltConfig>): void;
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
private
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
*/
|
|
1136
|
-
startSessionRecording(): void;
|
|
1137
|
-
/**
|
|
1138
|
-
* Stop session recording
|
|
1139
|
-
*/
|
|
1140
|
-
stopSessionRecording(): void;
|
|
1141
|
-
/**
|
|
1142
|
-
* Check if session recording is active
|
|
1143
|
-
*/
|
|
1144
|
-
isRecordingActive(): boolean;
|
|
1145
|
-
/**
|
|
1146
|
-
* Get session recording ID
|
|
1147
|
-
*/
|
|
1148
|
-
getSessionRecordingId(): string | null;
|
|
1149
|
-
/**
|
|
1150
|
-
* Initialize chat widget
|
|
1151
|
-
*/
|
|
1152
|
-
private _initChat;
|
|
1153
|
-
/**
|
|
1154
|
-
* Build chat config from VTiltConfig
|
|
1155
|
-
*/
|
|
1156
|
-
private _buildChatConfig;
|
|
1157
|
-
/**
|
|
1158
|
-
* _execute_array() deals with processing any vTilt function
|
|
1159
|
-
* calls that were called before the vTilt library was loaded
|
|
1160
|
-
* (and are thus stored in an array so they can be called later)
|
|
1161
|
-
*
|
|
1162
|
-
* Note: we fire off all the vTilt function calls BEFORE we fire off
|
|
1163
|
-
* tracking calls. This is so identify/setUserProperties/updateConfig calls
|
|
1164
|
-
* can properly modify early tracking calls.
|
|
1165
|
-
*
|
|
1166
|
-
* @param {Array} array Array of queued calls in format [methodName, ...args]
|
|
1167
|
-
*/
|
|
1718
|
+
private _notifyFeaturesOfConfigUpdate;
|
|
1719
|
+
buildUrl(): string;
|
|
1720
|
+
sendRequest(url: string, event: TrackingEvent, shouldEnqueue?: boolean): void;
|
|
1721
|
+
private _is_configured;
|
|
1722
|
+
private _send_batched_request;
|
|
1723
|
+
private _send_http_request;
|
|
1724
|
+
private _send_beacon_request;
|
|
1725
|
+
_send_retriable_request(item: QueuedRequest): void;
|
|
1726
|
+
private _setup_unload_handler;
|
|
1727
|
+
private _start_queue_if_opted_in;
|
|
1728
|
+
private _read_vt_param_from_url;
|
|
1168
1729
|
_execute_array(array: any[]): void;
|
|
1169
|
-
/**
|
|
1170
|
-
* Called when DOM is loaded - processes queued requests and enables batching
|
|
1171
|
-
* Following PostHog's pattern in _dom_loaded()
|
|
1172
|
-
*/
|
|
1173
1730
|
_dom_loaded(): void;
|
|
1174
1731
|
}
|
|
1175
1732
|
|
|
1176
1733
|
declare const vt: VTilt;
|
|
1177
1734
|
|
|
1178
1735
|
export { ALL_WEB_VITALS_METRICS, DEFAULT_WEB_VITALS_METRICS, VTilt, vt as default, vt };
|
|
1179
|
-
export type { AliasEvent, CaptureOptions, CapturePerformanceConfig, CaptureResult, ChatWidgetConfig, EventPayload, FeatureFlagsConfig, GeolocationData, GroupsConfig, PersistenceMethod, Properties, Property, PropertyOperations, RemoteConfig, RequestOptions, SessionData, SessionIdChangedCallback, SessionRecordingMaskInputOptions, SessionRecordingOptions, SupportedWebVitalsMetric, TrackingEvent, UserIdentity, UserProperties, VTiltConfig, WebVitalMetric };
|
|
1736
|
+
export type { AliasEvent, AutocaptureOptions, CaptureOptions, CapturePerformanceConfig, CaptureResult, ChatWidgetConfig, EventPayload, FeatureFlagsConfig, GeolocationData, GroupsConfig, PersistenceMethod, Properties, Property, PropertyOperations, RemoteConfig, RequestOptions, SessionData, SessionIdChangedCallback, SessionRecordingMaskInputOptions, SessionRecordingOptions, SupportedWebVitalsMetric, TrackingEvent, UserIdentity, UserProperties, VTiltConfig, WebVitalMetric };
|