@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.
Files changed (45) hide show
  1. package/dist/all-external-dependencies.js.map +1 -1
  2. package/dist/array.full.js +1 -1
  3. package/dist/array.full.js.map +1 -1
  4. package/dist/array.js +1 -1
  5. package/dist/array.js.map +1 -1
  6. package/dist/array.no-external.js +1 -1
  7. package/dist/array.no-external.js.map +1 -1
  8. package/dist/autocapture-types.d.ts +130 -0
  9. package/dist/autocapture-utils.d.ts +78 -0
  10. package/dist/autocapture.d.ts +84 -0
  11. package/dist/chat.js.map +1 -1
  12. package/dist/constants.d.ts +1 -1
  13. package/dist/core/capture.d.ts +70 -0
  14. package/dist/core/feature-manager.d.ts +95 -0
  15. package/dist/core/identity.d.ts +77 -0
  16. package/dist/core/index.d.ts +13 -0
  17. package/dist/core/remote-config.d.ts +50 -0
  18. package/dist/extensions/chat/chat-wrapper.d.ts +36 -10
  19. package/dist/extensions/history-autocapture.d.ts +34 -7
  20. package/dist/extensions/replay/session-recording-wrapper.d.ts +42 -11
  21. package/dist/extensions/replay/types.d.ts +1 -1
  22. package/dist/extensions/web-vitals/index.d.ts +7 -0
  23. package/dist/extensions/web-vitals/web-vitals-manager.d.ts +81 -0
  24. package/dist/external-scripts-loader.js.map +1 -1
  25. package/dist/feature.d.ts +231 -0
  26. package/dist/main.js +1 -1
  27. package/dist/main.js.map +1 -1
  28. package/dist/module.d.ts +881 -324
  29. package/dist/module.js +1 -1
  30. package/dist/module.js.map +1 -1
  31. package/dist/module.no-external.d.ts +881 -324
  32. package/dist/module.no-external.js +1 -1
  33. package/dist/module.no-external.js.map +1 -1
  34. package/dist/recorder.js.map +1 -1
  35. package/dist/server.d.ts +2 -0
  36. package/dist/types.d.ts +50 -2
  37. package/dist/utils/event-emitter.d.ts +106 -0
  38. package/dist/utils/globals.d.ts +1 -0
  39. package/dist/utils/index.d.ts +3 -0
  40. package/dist/utils/safewrap.d.ts +101 -0
  41. package/dist/utils/type-guards.d.ts +70 -0
  42. package/dist/vtilt.d.ts +66 -336
  43. package/dist/web-vitals.d.ts +39 -53
  44. package/dist/web-vitals.js.map +1 -1
  45. 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
- /** Enable autocapture */
60
- autocapture?: boolean;
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
- * This class is used to capture pageview events when the user navigates using the history API (pushState, replaceState)
363
- * and when the user navigates using the browser's back/forward buttons.
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
- monitorHistoryChanges(): void;
374
- private _capturePageview;
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
- * Start recording if enabled, otherwise stop
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
- declare class VTilt {
850
- readonly version = "1.9.0";
851
- private configManager;
852
- private sessionManager;
853
- private userManager;
854
- private webVitalsManager;
855
- private requestQueue;
856
- private retryQueue;
857
- private rateLimiter;
858
- historyAutocapture?: HistoryAutocapture;
859
- sessionRecording?: SessionRecordingWrapper;
860
- chat?: ChatWrapper;
861
- __loaded: boolean;
862
- private _initial_pageview_captured;
863
- private _visibility_state_listener;
864
- __request_queue: QueuedRequest[];
865
- private _has_warned_about_config;
866
- private _set_once_properties_sent;
867
- private _remoteConfig;
868
- /** Person UUID from vt= URL param (manual person tracking link); sent as $vt until backend links distinct_id */
869
- private _vt_person_uuid;
870
- constructor(config?: Partial<VTiltConfig>);
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
- * @returns The newly initialized VTilt instance
1548
+ * @param checkOnly - If true, don't consume a token (just check)
1549
+ * @returns Object with isRateLimited flag and remaining tokens
900
1550
  */
901
- init(projectId: string, config?: Partial<VTiltConfig>, name?: string): VTilt;
902
- /**
903
- * Handles the actual initialization logic for a VTilt instance.
904
- * This internal method should only be called by `init()`.
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
- * Fetch remote config from /decide endpoint.
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
- private _fetchRemoteConfig;
1558
+ shouldAllowEvent(): boolean;
934
1559
  /**
935
- * Apply remote config to current config.
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
- private _applyRemoteConfig;
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
- * Returns a string representation of the instance name
942
- * Used for debugging and logging
1603
+ * Subscribe to an event.
943
1604
  *
944
- * @internal
1605
+ * @param event - Event name to subscribe to
1606
+ * @param listener - Callback function
1607
+ * @returns Unsubscribe function
945
1608
  */
946
- toString(): string;
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
- * Send HTTP request
964
- * This is the central entry point for all tracking requests
965
- * Events are batched and sent every 3 seconds for better performance
966
- */
967
- private sendRequest;
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
- private _send_batched_request;
1617
+ once<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
974
1618
  /**
975
- * Send HTTP request and return status code
976
- * Uses GZip compression for payloads > 1KB
977
- * Used by RetryQueue for retryable requests
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
- private _send_http_request;
1624
+ emit<T = unknown>(event: string, payload?: T): void;
980
1625
  /**
981
- * Send request using sendBeacon for reliable delivery on page unload
982
- * Uses GZip compression for payloads > 1KB
1626
+ * Remove all listeners for an event.
1627
+ *
1628
+ * @param event - Event name (or undefined to remove all)
983
1629
  */
984
- private _send_beacon_request;
1630
+ off(event?: string): void;
985
1631
  /**
986
- * Send a queued request (called after DOM is loaded)
1632
+ * Get the number of listeners for an event.
1633
+ *
1634
+ * @param event - Event name
1635
+ * @returns Number of listeners
987
1636
  */
988
- _send_retriable_request(item: QueuedRequest): void;
1637
+ listenerCount(event: string): number;
989
1638
  /**
990
- * Capture an event
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 name - Event name
997
- * @param payload - Event payload
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
- * Get current user identity
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
- * Initialize session recording
1126
- */
1127
- private _initSessionRecording;
1128
- /**
1129
- * Build session recording config from VTiltConfig
1130
- */
1131
- private _buildSessionRecordingConfig;
1132
- /**
1133
- * Start session recording
1134
- * Call this to manually start recording if it wasn't enabled initially
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 };