@v-tilt/browser 1.8.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 (48) 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 +1 -1
  12. package/dist/chat.js.map +1 -1
  13. package/dist/constants.d.ts +1 -1
  14. package/dist/core/capture.d.ts +70 -0
  15. package/dist/core/feature-manager.d.ts +95 -0
  16. package/dist/core/identity.d.ts +77 -0
  17. package/dist/core/index.d.ts +13 -0
  18. package/dist/core/remote-config.d.ts +50 -0
  19. package/dist/extensions/chat/chat-wrapper.d.ts +36 -10
  20. package/dist/extensions/chat/chat.d.ts +1 -1
  21. package/dist/extensions/chat/types.d.ts +23 -11
  22. package/dist/extensions/history-autocapture.d.ts +34 -7
  23. package/dist/extensions/replay/session-recording-wrapper.d.ts +42 -11
  24. package/dist/extensions/replay/types.d.ts +1 -1
  25. package/dist/extensions/web-vitals/index.d.ts +7 -0
  26. package/dist/extensions/web-vitals/web-vitals-manager.d.ts +81 -0
  27. package/dist/external-scripts-loader.js.map +1 -1
  28. package/dist/feature.d.ts +231 -0
  29. package/dist/main.js +1 -1
  30. package/dist/main.js.map +1 -1
  31. package/dist/module.d.ts +904 -317
  32. package/dist/module.js +1 -1
  33. package/dist/module.js.map +1 -1
  34. package/dist/module.no-external.d.ts +904 -317
  35. package/dist/module.no-external.js +1 -1
  36. package/dist/module.no-external.js.map +1 -1
  37. package/dist/recorder.js.map +1 -1
  38. package/dist/server.d.ts +2 -0
  39. package/dist/types.d.ts +50 -2
  40. package/dist/utils/event-emitter.d.ts +106 -0
  41. package/dist/utils/globals.d.ts +24 -0
  42. package/dist/utils/index.d.ts +3 -0
  43. package/dist/utils/safewrap.d.ts +101 -0
  44. package/dist/utils/type-guards.d.ts +70 -0
  45. package/dist/vtilt.d.ts +66 -329
  46. package/dist/web-vitals.d.ts +39 -53
  47. package/dist/web-vitals.js.map +1 -1
  48. package/package.json +65 -65
package/dist/server.d.ts CHANGED
@@ -13,6 +13,8 @@ interface RemoteConfig {
13
13
  enabled?: boolean;
14
14
  sampleRate?: number;
15
15
  minimumDurationMs?: number;
16
+ /** Full DOM snapshot interval in ms (default 300000 = 5 min). Higher = less data. */
17
+ fullSnapshotIntervalMs?: number;
16
18
  maskAllInputs?: boolean;
17
19
  maskAllText?: boolean;
18
20
  captureConsole?: boolean;
package/dist/types.d.ts CHANGED
@@ -48,8 +48,12 @@ export interface VTiltConfig {
48
48
  * - 'never': Never create person profiles
49
49
  */
50
50
  person_profiles?: PersonProfilesMode;
51
- /** Enable autocapture */
52
- autocapture?: boolean;
51
+ /**
52
+ * Enable autocapture for automatic DOM event tracking.
53
+ * Can be a boolean or an object with detailed configuration.
54
+ * When true, captures clicks, form submissions, and input changes.
55
+ */
56
+ autocapture?: boolean | AutocaptureOptions;
53
57
  /**
54
58
  * Enable web vitals tracking.
55
59
  * Can be a boolean or an object with detailed configuration.
@@ -222,6 +226,48 @@ export interface RequestOptions {
222
226
  timeout?: number;
223
227
  retry?: boolean;
224
228
  }
229
+ /**
230
+ * Autocapture configuration options
231
+ * Controls automatic DOM event tracking (clicks, form submissions, input changes)
232
+ */
233
+ export interface AutocaptureOptions {
234
+ /**
235
+ * Enable autocapture (default: true when autocapture config is present)
236
+ */
237
+ enabled?: boolean;
238
+ /**
239
+ * URL patterns to allow autocapture on (default: all URLs)
240
+ * Supports strings (exact match) and RegExp patterns
241
+ */
242
+ url_allowlist?: (string | RegExp)[];
243
+ /**
244
+ * URL patterns to exclude from autocapture
245
+ * Supports strings (exact match) and RegExp patterns
246
+ */
247
+ url_ignorelist?: (string | RegExp)[];
248
+ /**
249
+ * DOM events to capture (default: ['click', 'change', 'submit'])
250
+ */
251
+ dom_event_allowlist?: ("click" | "change" | "submit")[];
252
+ /**
253
+ * Element tags to capture (default: ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'])
254
+ */
255
+ element_allowlist?: string[];
256
+ /**
257
+ * CSS selectors to allow for capture (elements matching these are always captured)
258
+ * Example: ['[data-track]', '.track-click']
259
+ */
260
+ css_selector_allowlist?: string[];
261
+ /**
262
+ * Element attributes to exclude from capture
263
+ * Example: ['data-secret', 'aria-label']
264
+ */
265
+ element_attribute_ignorelist?: string[];
266
+ /**
267
+ * Capture text content from copy/cut events (default: false)
268
+ */
269
+ capture_copied_text?: boolean;
270
+ }
225
271
  /** Mask options for input elements in session recording */
226
272
  export interface SessionRecordingMaskInputOptions {
227
273
  color?: boolean;
@@ -322,6 +368,8 @@ export interface RemoteConfig {
322
368
  enabled?: boolean;
323
369
  sampleRate?: number;
324
370
  minimumDurationMs?: number;
371
+ /** Full DOM snapshot interval in ms (default 300000 = 5 min). Higher = less data. */
372
+ fullSnapshotIntervalMs?: number;
325
373
  maskAllInputs?: boolean;
326
374
  maskAllText?: boolean;
327
375
  captureConsole?: boolean;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Simple Event Emitter
3
+ *
4
+ * Lightweight pub/sub system for internal feature communication.
5
+ * Following PostHog's SimpleEventEmitter pattern.
6
+ */
7
+ /**
8
+ * Event listener function type
9
+ */
10
+ export type EventListener<T = unknown> = (payload: T) => void;
11
+ /**
12
+ * Unsubscribe function returned by on()
13
+ */
14
+ export type Unsubscribe = () => void;
15
+ /**
16
+ * Simple event emitter for internal SDK communication.
17
+ * Features can emit and listen to events without direct coupling.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const emitter = new SimpleEventEmitter();
22
+ *
23
+ * // Subscribe to events
24
+ * const unsubscribe = emitter.on('user:identified', (data) => {
25
+ * console.log('User identified:', data);
26
+ * });
27
+ *
28
+ * // Emit events
29
+ * emitter.emit('user:identified', { userId: '123' });
30
+ *
31
+ * // Unsubscribe when done
32
+ * unsubscribe();
33
+ * ```
34
+ */
35
+ export declare class SimpleEventEmitter {
36
+ private _events;
37
+ private _onceEvents;
38
+ /**
39
+ * Subscribe to an event.
40
+ *
41
+ * @param event - Event name to subscribe to
42
+ * @param listener - Callback function
43
+ * @returns Unsubscribe function
44
+ */
45
+ on<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
46
+ /**
47
+ * Subscribe to an event once (auto-unsubscribes after first call).
48
+ *
49
+ * @param event - Event name to subscribe to
50
+ * @param listener - Callback function
51
+ * @returns Unsubscribe function
52
+ */
53
+ once<T = unknown>(event: string, listener: EventListener<T>): Unsubscribe;
54
+ /**
55
+ * Emit an event to all listeners.
56
+ *
57
+ * @param event - Event name to emit
58
+ * @param payload - Data to pass to listeners
59
+ */
60
+ emit<T = unknown>(event: string, payload?: T): void;
61
+ /**
62
+ * Remove all listeners for an event.
63
+ *
64
+ * @param event - Event name (or undefined to remove all)
65
+ */
66
+ off(event?: string): void;
67
+ /**
68
+ * Get the number of listeners for an event.
69
+ *
70
+ * @param event - Event name
71
+ * @returns Number of listeners
72
+ */
73
+ listenerCount(event: string): number;
74
+ /**
75
+ * Check if there are any listeners for an event.
76
+ *
77
+ * @param event - Event name
78
+ * @returns True if there are listeners
79
+ */
80
+ hasListeners(event: string): boolean;
81
+ }
82
+ /**
83
+ * VTilt SDK Events
84
+ *
85
+ * Standard events emitted by the SDK for internal communication.
86
+ */
87
+ export declare const VTiltEvents: {
88
+ readonly INITIALIZED: "sdk:initialized";
89
+ readonly CONFIG_UPDATED: "sdk:config_updated";
90
+ readonly REMOTE_CONFIG_LOADED: "sdk:remote_config_loaded";
91
+ readonly USER_IDENTIFIED: "user:identified";
92
+ readonly USER_RESET: "user:reset";
93
+ readonly USER_PROPERTIES_SET: "user:properties_set";
94
+ readonly SESSION_STARTED: "session:started";
95
+ readonly SESSION_ENDED: "session:ended";
96
+ readonly SESSION_ROTATED: "session:rotated";
97
+ readonly FEATURE_STARTED: "feature:started";
98
+ readonly FEATURE_STOPPED: "feature:stopped";
99
+ readonly EVENT_CAPTURED: "event:captured";
100
+ readonly EVENT_SENT: "event:sent";
101
+ readonly EVENT_FAILED: "event:failed";
102
+ readonly RECORDING_STARTED: "recording:started";
103
+ readonly RECORDING_STOPPED: "recording:stopped";
104
+ readonly ERROR: "error";
105
+ };
106
+ export type VTiltEventName = (typeof VTiltEvents)[keyof typeof VTiltEvents];
@@ -136,6 +136,29 @@ export interface ChatConfig {
136
136
  offlineMessage?: string;
137
137
  /** Collect email when offline */
138
138
  collectEmailOffline?: boolean;
139
+ /** Called when widget is opened */
140
+ onWidgetOpen?: () => void;
141
+ /** Called when widget is closed */
142
+ onWidgetClose?: (data: {
143
+ timeOpenSeconds: number;
144
+ messagesSent: number;
145
+ }) => void;
146
+ /** Called when a new conversation is started */
147
+ onConversationStart?: (data: {
148
+ channelId: string;
149
+ aiMode: boolean;
150
+ }) => void;
151
+ /** Called when user sends a message */
152
+ onMessageSent?: (data: {
153
+ channelId: string;
154
+ messageId: string;
155
+ }) => void;
156
+ /** Called when a message is received (from AI or agent) */
157
+ onMessageReceived?: (data: {
158
+ channelId: string;
159
+ messageId: string;
160
+ senderType: "ai" | "agent";
161
+ }) => void;
139
162
  }
140
163
  /**
141
164
  * Chat theme customization
@@ -177,6 +200,7 @@ export interface LazyLoadedChatInterface {
177
200
  onMessage(callback: (message: ChatMessage) => void): () => void;
178
201
  onTyping(callback: (isTyping: boolean, senderType: string) => void): () => void;
179
202
  onConnectionChange(callback: (connected: boolean) => void): () => void;
203
+ updateConfig?(config: ChatConfig): void;
180
204
  destroy(): void;
181
205
  }
182
206
  /**
@@ -1,3 +1,6 @@
1
+ export * from "./type-guards";
2
+ export * from "./safewrap";
3
+ export * from "./event-emitter";
1
4
  /**
2
5
  * Generate uuid to identify the session. Random, not data-derived
3
6
  */
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Safe Wrapper Utilities
3
+ *
4
+ * Error isolation utilities to prevent feature errors from crashing the SDK.
5
+ * Following PostHog's safewrap pattern.
6
+ */
7
+ /**
8
+ * Logger interface for error reporting
9
+ */
10
+ interface Logger {
11
+ error: (...args: unknown[]) => void;
12
+ warn: (...args: unknown[]) => void;
13
+ }
14
+ /**
15
+ * Wrap a function to catch and log errors without throwing.
16
+ * Prevents errors in one feature from crashing the entire SDK.
17
+ *
18
+ * @param fn - The function to wrap
19
+ * @param context - Optional context string for error messages
20
+ * @param logger - Optional custom logger
21
+ * @returns Wrapped function that catches errors
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const safeHandler = safewrap(
26
+ * (event: Event) => this._handleEvent(event),
27
+ * 'Autocapture._handleEvent'
28
+ * );
29
+ * document.addEventListener('click', safeHandler);
30
+ * ```
31
+ */
32
+ export declare function safewrap<F extends (...args: any[]) => any>(fn: F, context?: string, logger?: Logger): F;
33
+ /**
34
+ * Try to execute a function and return undefined on error.
35
+ * Useful for one-off operations that might fail.
36
+ *
37
+ * @param fn - The function to try
38
+ * @param fallback - Optional fallback value on error
39
+ * @returns The result or fallback/undefined
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const value = trySafe(() => JSON.parse(data), {});
44
+ * const element = trySafe(() => document.querySelector('.my-class'));
45
+ * ```
46
+ */
47
+ export declare function trySafe<T>(fn: () => T): T | undefined;
48
+ export declare function trySafe<T, F>(fn: () => T, fallback: F): T | F;
49
+ /**
50
+ * Wrap all methods of a class prototype with safewrap.
51
+ * Useful for wrapping entire feature classes.
52
+ *
53
+ * @param Class - The class constructor
54
+ * @param methodNames - Array of method names to wrap
55
+ * @param logger - Optional custom logger
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * class MyFeature {
60
+ * capture() { ... }
61
+ * identify() { ... }
62
+ * }
63
+ * safewrapClass(MyFeature, ['capture', 'identify']);
64
+ * ```
65
+ */
66
+ export declare function safewrapClass<T extends new (...args: any[]) => any>(Class: T, methodNames: (keyof InstanceType<T>)[], logger?: Logger): void;
67
+ /**
68
+ * Create a safe event handler that won't break on errors.
69
+ * Specifically designed for DOM event handlers.
70
+ *
71
+ * @param handler - The event handler function
72
+ * @param context - Context string for error messages
73
+ * @returns Safe event handler
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * document.addEventListener('click', safeEventHandler(
78
+ * (e) => this._onClick(e),
79
+ * 'Autocapture.onClick'
80
+ * ));
81
+ * ```
82
+ */
83
+ export declare function safeEventHandler<E extends Event>(handler: (event: E) => void, context?: string): (event: E) => void;
84
+ /**
85
+ * Execute an async function safely, catching any errors.
86
+ *
87
+ * @param fn - The async function to execute
88
+ * @param context - Context string for error messages
89
+ * @param logger - Optional custom logger
90
+ * @returns Promise that resolves to result or undefined
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const result = await trySafeAsync(
95
+ * () => fetch('/api/data'),
96
+ * 'fetchData'
97
+ * );
98
+ * ```
99
+ */
100
+ export declare function trySafeAsync<T>(fn: () => Promise<T>, context?: string, logger?: Logger): Promise<T | undefined>;
101
+ export {};
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Type Guards
3
+ *
4
+ * Runtime type checking utilities for type-safe code.
5
+ * Following PostHog's pattern from @posthog/core.
6
+ */
7
+ /**
8
+ * Check if value is a string
9
+ */
10
+ export declare function isString(x: unknown): x is string;
11
+ /**
12
+ * Check if value is a number (and not NaN)
13
+ */
14
+ export declare function isNumber(x: unknown): x is number;
15
+ /**
16
+ * Check if value is a boolean
17
+ */
18
+ export declare function isBoolean(x: unknown): x is boolean;
19
+ /**
20
+ * Check if value is undefined
21
+ */
22
+ export declare function isUndefined(x: unknown): x is undefined;
23
+ /**
24
+ * Check if value is null
25
+ */
26
+ export declare function isNull(x: unknown): x is null;
27
+ /**
28
+ * Check if value is null or undefined
29
+ */
30
+ export declare function isNullish(x: unknown): x is null | undefined;
31
+ /**
32
+ * Check if value is an array
33
+ */
34
+ export declare function isArray(x: unknown): x is unknown[];
35
+ /**
36
+ * Check if value is a plain object (not null, not array)
37
+ */
38
+ export declare function isObject(x: unknown): x is Record<string, unknown>;
39
+ /**
40
+ * Check if value is a function
41
+ */
42
+ export declare function isFunction(x: unknown): x is Function;
43
+ /**
44
+ * Check if value is a Date object
45
+ */
46
+ export declare function isDate(x: unknown): x is Date;
47
+ /**
48
+ * Check if value is a valid element
49
+ */
50
+ export declare function isElement(x: unknown): x is Element;
51
+ /**
52
+ * Check if value is a valid HTMLElement
53
+ */
54
+ export declare function isHTMLElement(x: unknown): x is HTMLElement;
55
+ /**
56
+ * Check if value is empty (null, undefined, empty string, empty array, empty object)
57
+ */
58
+ export declare function isEmpty(x: unknown): boolean;
59
+ /**
60
+ * Check if value is a non-empty string
61
+ */
62
+ export declare function isNonEmptyString(x: unknown): x is string;
63
+ /**
64
+ * Check if value is a positive number
65
+ */
66
+ export declare function isPositiveNumber(x: unknown): x is number;
67
+ /**
68
+ * Check if value is a RegExp
69
+ */
70
+ export declare function isRegExp(x: unknown): x is RegExp;