@v-tilt/browser 1.0.8 → 1.0.9
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/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/constants.d.ts +0 -1
- package/dist/extensions/history-autocapture.d.ts +0 -2
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.d.ts +52 -132
- package/dist/module.js +1 -1
- package/dist/module.js.map +1 -1
- package/dist/module.no-external.d.ts +52 -132
- package/dist/module.no-external.js +1 -1
- package/dist/module.no-external.js.map +1 -1
- package/dist/session.d.ts +5 -5
- package/dist/types.d.ts +1 -0
- package/dist/user-manager.d.ts +30 -20
- package/dist/utils/event-utils.d.ts +7 -8
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/patch.d.ts +0 -1
- package/dist/vtilt.d.ts +54 -14
- package/dist/web-vitals.d.ts +3 -3
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +1 -23
- package/lib/extensions/history-autocapture.d.ts +0 -2
- package/lib/extensions/history-autocapture.js +3 -5
- package/lib/session.d.ts +5 -5
- package/lib/session.js +8 -8
- package/lib/types.d.ts +1 -0
- package/lib/user-manager.d.ts +30 -20
- package/lib/user-manager.js +103 -92
- package/lib/utils/event-utils.d.ts +7 -8
- package/lib/utils/event-utils.js +8 -9
- package/lib/utils/index.d.ts +0 -5
- package/lib/utils/index.js +0 -13
- package/lib/utils/patch.d.ts +0 -1
- package/lib/utils/patch.js +0 -1
- package/lib/vtilt.d.ts +54 -14
- package/lib/vtilt.js +328 -45
- package/lib/web-vitals.d.ts +3 -3
- package/lib/web-vitals.js +3 -3
- package/package.json +61 -61
- package/dist/tracking.d.ts +0 -120
- package/dist/utils/is-function.d.ts +0 -4
- package/lib/tracking.d.ts +0 -120
- package/lib/tracking.js +0 -338
- package/lib/utils/is-function.d.ts +0 -4
- package/lib/utils/is-function.js +0 -9
package/lib/tracking.js
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TrackingManager = void 0;
|
|
4
|
-
const session_1 = require("./session");
|
|
5
|
-
const user_manager_1 = require("./user-manager");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
const event_utils_1 = require("./utils/event-utils");
|
|
8
|
-
const globals_1 = require("./utils/globals");
|
|
9
|
-
class TrackingManager {
|
|
10
|
-
constructor(config) {
|
|
11
|
-
this.__request_queue = [];
|
|
12
|
-
this._hasWarnedAboutConfig = false; // Track if we've already warned about missing config
|
|
13
|
-
this.config = config;
|
|
14
|
-
// Auto-detect domain from location if not provided
|
|
15
|
-
if (!this.config.domain && globals_1.location) {
|
|
16
|
-
this.config.domain = this.getCurrentDomain();
|
|
17
|
-
}
|
|
18
|
-
this.sessionManager = new session_1.SessionManager(config.storage || "cookie", this.config.domain);
|
|
19
|
-
this.userManager = new user_manager_1.UserManager(config.persistence || "localStorage", this.config.domain);
|
|
20
|
-
// Listen for identify events
|
|
21
|
-
this.setupIdentifyListener();
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Get current domain from location
|
|
25
|
-
* Returns full URL format for consistency with dashboard
|
|
26
|
-
*/
|
|
27
|
-
getCurrentDomain() {
|
|
28
|
-
if (!globals_1.location) {
|
|
29
|
-
return "";
|
|
30
|
-
}
|
|
31
|
-
const protocol = globals_1.location.protocol;
|
|
32
|
-
const hostname = globals_1.location.hostname;
|
|
33
|
-
const port = globals_1.location.port;
|
|
34
|
-
const portSuffix = port ? `:${port}` : "";
|
|
35
|
-
return `${protocol}//${hostname}${portSuffix}`;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Check if tracking is properly configured
|
|
39
|
-
* Returns true if projectId and token are present, false otherwise
|
|
40
|
-
* Logs a warning only once per instance if not configured
|
|
41
|
-
*/
|
|
42
|
-
_isConfigured() {
|
|
43
|
-
if (this.config.projectId && this.config.token) {
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
// Only warn once to avoid console spam
|
|
47
|
-
if (!this._hasWarnedAboutConfig) {
|
|
48
|
-
console.warn("VTilt: projectId and token are required for tracking. " +
|
|
49
|
-
"Events will be skipped until init() or updateConfig() is called with these fields.");
|
|
50
|
-
this._hasWarnedAboutConfig = true;
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Send event to endpoint
|
|
56
|
-
* PostHog-style: Automatically adds common properties to all events
|
|
57
|
-
* ($current_url, $host, $pathname, $referrer, $referring_domain, $browser_language, etc.)
|
|
58
|
-
* Also adds title property for $pageview events only
|
|
59
|
-
*/
|
|
60
|
-
async sendEvent(name, payload) {
|
|
61
|
-
this.sessionManager.setSessionId();
|
|
62
|
-
// Only send events in browser environment (not SSR)
|
|
63
|
-
if (!globals_1.navigator || !globals_1.navigator.userAgent) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
if (!(0, utils_1.isValidUserAgent)(globals_1.navigator.userAgent)) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const url = this.buildUrl();
|
|
70
|
-
// Add properties to all events (PostHog-style)
|
|
71
|
-
// This includes: $current_url, $host, $pathname, $referrer, $referring_domain, $browser_language, etc.
|
|
72
|
-
const eventProperties = (0, event_utils_1.getEventProperties)();
|
|
73
|
-
// Get session and window IDs (PostHog-style)
|
|
74
|
-
// Both methods ensure IDs always exist (generate if needed)
|
|
75
|
-
const session_id = this.sessionManager.getSessionId();
|
|
76
|
-
const window_id = this.sessionManager.getWindowId();
|
|
77
|
-
const enrichedPayload = {
|
|
78
|
-
...eventProperties, // Base properties for all events
|
|
79
|
-
$session_id: session_id, // PostHog-style: session ID in properties
|
|
80
|
-
$window_id: window_id, // PostHog-style: window ID in properties
|
|
81
|
-
...payload, // User-provided payload (can override base properties)
|
|
82
|
-
};
|
|
83
|
-
// Add title only to $pageview events (PostHog-style)
|
|
84
|
-
if (name === "$pageview" && globals_1.document) {
|
|
85
|
-
enrichedPayload.title = globals_1.document.title;
|
|
86
|
-
}
|
|
87
|
-
let processedPayload;
|
|
88
|
-
if (this.config.stringifyPayload !== false) {
|
|
89
|
-
processedPayload = (0, utils_1.maskSuspiciousAttributes)(enrichedPayload);
|
|
90
|
-
processedPayload = Object.assign({}, JSON.parse(processedPayload), this.config.globalAttributes);
|
|
91
|
-
processedPayload = JSON.stringify(processedPayload);
|
|
92
|
-
if (!(0, utils_1.isValidPayload)(processedPayload)) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
processedPayload = Object.assign({}, enrichedPayload, this.config.globalAttributes);
|
|
98
|
-
const maskedStr = (0, utils_1.maskSuspiciousAttributes)(processedPayload);
|
|
99
|
-
if (!(0, utils_1.isValidPayload)(maskedStr)) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
processedPayload = JSON.parse(maskedStr);
|
|
103
|
-
}
|
|
104
|
-
// session_id is already in payload as $session_id (PostHog-style)
|
|
105
|
-
const distinct_id = this.userManager.getDistinctId();
|
|
106
|
-
const anonymous_id = this.userManager.getAnonymousId();
|
|
107
|
-
const trackingEvent = {
|
|
108
|
-
timestamp: new Date().toISOString(),
|
|
109
|
-
event: name,
|
|
110
|
-
tenant_id: this.config.projectId || "",
|
|
111
|
-
domain: this.config.domain || this.getCurrentDomain(), // Use config domain or current domain
|
|
112
|
-
payload: processedPayload,
|
|
113
|
-
distinct_id: distinct_id || anonymous_id,
|
|
114
|
-
};
|
|
115
|
-
this.sendRequest(url, trackingEvent, true);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Build the tracking URL with token in query parameters (PostHog style)
|
|
119
|
-
*/
|
|
120
|
-
buildUrl() {
|
|
121
|
-
const { proxyUrl, proxy, host, token } = this.config;
|
|
122
|
-
// Use proxy endpoint to handle Tinybird authentication
|
|
123
|
-
if (proxyUrl) {
|
|
124
|
-
// Use the full proxy URL as provided
|
|
125
|
-
return proxyUrl;
|
|
126
|
-
}
|
|
127
|
-
else if (proxy) {
|
|
128
|
-
// Construct the proxy URL from the proxy domain with token
|
|
129
|
-
return `${proxy}/api/tracking?token=${token}`;
|
|
130
|
-
}
|
|
131
|
-
else if (host) {
|
|
132
|
-
const cleanHost = host.replace(/\/+$/gm, "");
|
|
133
|
-
return `${cleanHost}/api/tracking?token=${token}`;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
// Use relative path to our tracking proxy endpoint
|
|
137
|
-
return `/api/tracking?token=${token}`;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Send HTTP request
|
|
142
|
-
* This is the central entry point for all tracking requests
|
|
143
|
-
*/
|
|
144
|
-
sendRequest(url, event, shouldEnqueue) {
|
|
145
|
-
// Validate configuration (only warns once per instance)
|
|
146
|
-
// This is the single place where validation happens for all sending methods
|
|
147
|
-
if (!this._isConfigured()) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
// Check if we should queue requests (for older browsers before DOM is loaded)
|
|
151
|
-
if (shouldEnqueue && typeof globals_1.window !== "undefined") {
|
|
152
|
-
// ENQUEUE_REQUESTS is defined in vtilt.ts as a module-level variable
|
|
153
|
-
const ENQUEUE_REQUESTS = globals_1.window.__VTILT_ENQUEUE_REQUESTS;
|
|
154
|
-
if (ENQUEUE_REQUESTS) {
|
|
155
|
-
this.__request_queue.push({ url, event });
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const request = new XMLHttpRequest();
|
|
160
|
-
request.open("POST", url, true);
|
|
161
|
-
request.setRequestHeader("Content-Type", "application/json");
|
|
162
|
-
request.send(JSON.stringify(event));
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Send a queued request (called after DOM is loaded)
|
|
166
|
-
*/
|
|
167
|
-
_send_retriable_request(item) {
|
|
168
|
-
this.sendRequest(item.url, item.event, false);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Get current session ID
|
|
172
|
-
*/
|
|
173
|
-
getSessionId() {
|
|
174
|
-
return this.sessionManager.getSessionId();
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Identify a user with PostHog-style property operations
|
|
178
|
-
* Copied from PostHog's identify method signature
|
|
179
|
-
*/
|
|
180
|
-
identify(distinctId, userPropertiesToSet, userPropertiesToSetOnce) {
|
|
181
|
-
this.userManager.identify(distinctId, userPropertiesToSet, userPropertiesToSetOnce);
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Set user properties (PostHog-style)
|
|
185
|
-
*/
|
|
186
|
-
setUserProperties(userPropertiesToSet, userPropertiesToSetOnce) {
|
|
187
|
-
this.userManager.setUserProperties(userPropertiesToSet, userPropertiesToSetOnce);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Reset user identity (logout)
|
|
191
|
-
* PostHog behavior: Clears all user data, generates new anonymous ID, resets session
|
|
192
|
-
*
|
|
193
|
-
* @param reset_device_id - If true, also resets device_id. Default: false
|
|
194
|
-
*/
|
|
195
|
-
resetUser(reset_device_id) {
|
|
196
|
-
// PostHog behavior: Reset session ID
|
|
197
|
-
this.sessionManager.resetSessionId();
|
|
198
|
-
this.userManager.reset(reset_device_id);
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Get current user identity
|
|
202
|
-
*/
|
|
203
|
-
getUserIdentity() {
|
|
204
|
-
return this.userManager.getUserIdentity();
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Get current device ID
|
|
208
|
-
*/
|
|
209
|
-
getDeviceId() {
|
|
210
|
-
return this.userManager.getDeviceId();
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Get current user state
|
|
214
|
-
*/
|
|
215
|
-
getUserState() {
|
|
216
|
-
return this.userManager.getUserState();
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Create an alias to link two distinct IDs
|
|
220
|
-
* PostHog behavior: Links anonymous session to account on signup
|
|
221
|
-
*
|
|
222
|
-
* @param alias - A unique identifier that you want to use for this user in the future
|
|
223
|
-
* @param original - The current identifier being used for this user (optional, defaults to current distinct_id)
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* // Link anonymous user to account on signup
|
|
227
|
-
* vtilt.createAlias('user_12345')
|
|
228
|
-
*
|
|
229
|
-
* @example
|
|
230
|
-
* // Explicit alias with original ID
|
|
231
|
-
* vtilt.createAlias('user_12345', 'anonymous_abc123')
|
|
232
|
-
*/
|
|
233
|
-
createAlias(alias, original) {
|
|
234
|
-
this.userManager.createAlias(alias, original);
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Setup listener for identify, set, and alias events
|
|
238
|
-
*/
|
|
239
|
-
setupIdentifyListener() {
|
|
240
|
-
// Only setup listeners in browser environment (not SSR)
|
|
241
|
-
if (!globals_1.window) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
// Listen for identify events
|
|
245
|
-
globals_1.window.addEventListener("vtilt:identify", (event) => {
|
|
246
|
-
const customEvent = event;
|
|
247
|
-
const { distinct_id, anonymous_id, device_id, properties } = customEvent.detail;
|
|
248
|
-
this.sendIdentifyEvent(distinct_id, anonymous_id, device_id, properties);
|
|
249
|
-
});
|
|
250
|
-
// Listen for set events (property updates)
|
|
251
|
-
globals_1.window.addEventListener("vtilt:set", (event) => {
|
|
252
|
-
const customEvent = event;
|
|
253
|
-
const { $set, $set_once } = customEvent.detail;
|
|
254
|
-
this.sendSetEvent($set || {}, $set_once || {});
|
|
255
|
-
});
|
|
256
|
-
// Listen for alias events
|
|
257
|
-
globals_1.window.addEventListener("vtilt:alias", (event) => {
|
|
258
|
-
const customEvent = event;
|
|
259
|
-
const aliasEvent = customEvent.detail;
|
|
260
|
-
this.sendAliasEvent(aliasEvent);
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Get session and window IDs (PostHog-style)
|
|
265
|
-
* Both methods ensure IDs always exist (generate if needed)
|
|
266
|
-
*/
|
|
267
|
-
_getSessionAndWindowIds() {
|
|
268
|
-
return {
|
|
269
|
-
session_id: this.sessionManager.getSessionId(),
|
|
270
|
-
window_id: this.sessionManager.getWindowId(),
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Create base tracking event structure
|
|
275
|
-
*/
|
|
276
|
-
_createTrackingEvent(event, payload, distinct_id) {
|
|
277
|
-
return {
|
|
278
|
-
timestamp: new Date().toISOString(),
|
|
279
|
-
event,
|
|
280
|
-
tenant_id: this.config.projectId || "",
|
|
281
|
-
domain: this.config.domain || this.getCurrentDomain(),
|
|
282
|
-
payload,
|
|
283
|
-
distinct_id,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Send identify event for session merging
|
|
288
|
-
*/
|
|
289
|
-
sendIdentifyEvent(distinctId, anonymousId, deviceId, properties) {
|
|
290
|
-
const { session_id, window_id } = this._getSessionAndWindowIds();
|
|
291
|
-
// Payload contains only properties, not event or distinct_id (those are in trackingEvent)
|
|
292
|
-
// Add $session_id and $window_id to payload (PostHog-style)
|
|
293
|
-
const identifyPayload = {
|
|
294
|
-
$session_id: session_id,
|
|
295
|
-
$window_id: window_id,
|
|
296
|
-
$anon_distinct_id: anonymousId,
|
|
297
|
-
$device_id: deviceId,
|
|
298
|
-
...properties,
|
|
299
|
-
};
|
|
300
|
-
const trackingEvent = this._createTrackingEvent("$identify", identifyPayload, distinctId);
|
|
301
|
-
this.sendRequest(this.buildUrl(), trackingEvent, true);
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Send $set event for property updates (PostHog behavior)
|
|
305
|
-
* This notifies Tinybird when user properties are updated
|
|
306
|
-
*/
|
|
307
|
-
sendSetEvent(userPropertiesToSet, userPropertiesToSetOnce) {
|
|
308
|
-
const { session_id, window_id } = this._getSessionAndWindowIds();
|
|
309
|
-
const distinct_id = this.userManager.getDistinctId();
|
|
310
|
-
const anonymous_id = this.userManager.getAnonymousId();
|
|
311
|
-
// Add $session_id and $window_id to payload (PostHog-style)
|
|
312
|
-
const setEventPayload = {
|
|
313
|
-
$session_id: session_id,
|
|
314
|
-
$window_id: window_id,
|
|
315
|
-
$set: userPropertiesToSet || {},
|
|
316
|
-
$set_once: userPropertiesToSetOnce || {},
|
|
317
|
-
};
|
|
318
|
-
const trackingEvent = this._createTrackingEvent("$set", setEventPayload, distinct_id || anonymous_id);
|
|
319
|
-
this.sendRequest(this.buildUrl(), trackingEvent, true);
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Send alias event for identity linking
|
|
323
|
-
* PostHog format: { alias: alias, distinct_id: original }
|
|
324
|
-
*/
|
|
325
|
-
sendAliasEvent(aliasEvent) {
|
|
326
|
-
const { session_id, window_id } = this._getSessionAndWindowIds();
|
|
327
|
-
// Add $session_id and $window_id to payload (PostHog-style)
|
|
328
|
-
const aliasPayload = {
|
|
329
|
-
$session_id: session_id,
|
|
330
|
-
$window_id: window_id,
|
|
331
|
-
$original_id: aliasEvent.original,
|
|
332
|
-
$alias_id: aliasEvent.distinct_id,
|
|
333
|
-
};
|
|
334
|
-
const trackingEvent = this._createTrackingEvent("$alias", aliasPayload, aliasEvent.distinct_id);
|
|
335
|
-
this.sendRequest(this.buildUrl(), trackingEvent, true);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
exports.TrackingManager = TrackingManager;
|
package/lib/utils/is-function.js
DELETED