aurea-tracking-sdk 1.0.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/README.md +429 -0
- package/dist/index.d.mts +144 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +473 -0
- package/dist/index.mjs +444 -0
- package/package.json +40 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.ts
|
|
20
|
+
var index_exports = {};
|
|
21
|
+
__export(index_exports, {
|
|
22
|
+
getAurea: () => getAurea,
|
|
23
|
+
identifyUser: () => identifyUser,
|
|
24
|
+
initAurea: () => initAurea,
|
|
25
|
+
trackConversion: () => trackConversion,
|
|
26
|
+
trackEvent: () => trackEvent,
|
|
27
|
+
trackPage: () => trackPage
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
var AureaSDK = class {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.eventQueue = [];
|
|
33
|
+
this.initialized = false;
|
|
34
|
+
this.config = {
|
|
35
|
+
apiUrl: "http://localhost:3000/api",
|
|
36
|
+
debug: false,
|
|
37
|
+
autoTrack: {
|
|
38
|
+
pageViews: true,
|
|
39
|
+
forms: true,
|
|
40
|
+
clicks: false,
|
|
41
|
+
scrollDepth: false
|
|
42
|
+
},
|
|
43
|
+
respectDoNotTrack: true,
|
|
44
|
+
anonymizeIp: true,
|
|
45
|
+
batchSize: 10,
|
|
46
|
+
batchInterval: 2e3,
|
|
47
|
+
...config
|
|
48
|
+
};
|
|
49
|
+
this.sessionId = this.getOrCreateSessionId();
|
|
50
|
+
this.anonymousId = this.getOrCreateAnonymousId();
|
|
51
|
+
if (typeof window !== "undefined") {
|
|
52
|
+
const savedUserId = localStorage.getItem("aurea_user_id");
|
|
53
|
+
if (savedUserId) {
|
|
54
|
+
this.userId = savedUserId;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Initialize the SDK
|
|
60
|
+
*/
|
|
61
|
+
init() {
|
|
62
|
+
if (this.initialized) {
|
|
63
|
+
console.warn("[Aurea SDK] Already initialized");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (this.config.respectDoNotTrack && typeof navigator !== "undefined" && (navigator.doNotTrack === "1" || navigator.msDoNotTrack === "1")) {
|
|
67
|
+
if (this.config.debug) {
|
|
68
|
+
console.log("[Aurea SDK] Do Not Track enabled, skipping initialization");
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.initialized = true;
|
|
73
|
+
if (this.config.autoTrack?.pageViews) {
|
|
74
|
+
this.trackPageLoad();
|
|
75
|
+
this.trackPageChanges();
|
|
76
|
+
}
|
|
77
|
+
if (this.config.autoTrack?.forms) {
|
|
78
|
+
this.trackForms();
|
|
79
|
+
}
|
|
80
|
+
if (this.config.autoTrack?.scrollDepth) {
|
|
81
|
+
this.trackScrollDepth();
|
|
82
|
+
}
|
|
83
|
+
this.startBatchTimer();
|
|
84
|
+
this.startPurchasePolling();
|
|
85
|
+
if (this.config.debug) {
|
|
86
|
+
console.log("[Aurea SDK] Initialized", {
|
|
87
|
+
sessionId: this.sessionId,
|
|
88
|
+
anonymousId: this.anonymousId,
|
|
89
|
+
userId: this.userId
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Track a custom event
|
|
95
|
+
*/
|
|
96
|
+
track(eventName, properties) {
|
|
97
|
+
const event = {
|
|
98
|
+
eventId: this.generateEventId(),
|
|
99
|
+
eventName,
|
|
100
|
+
properties: properties || {},
|
|
101
|
+
context: this.buildContext(),
|
|
102
|
+
timestamp: Date.now()
|
|
103
|
+
};
|
|
104
|
+
this.enqueueEvent(event);
|
|
105
|
+
if (this.config.debug) {
|
|
106
|
+
console.log("[Aurea SDK] Event tracked:", eventName, properties);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Identify a user
|
|
111
|
+
*/
|
|
112
|
+
identify(userId, traits) {
|
|
113
|
+
this.userId = userId;
|
|
114
|
+
if (typeof window !== "undefined") {
|
|
115
|
+
localStorage.setItem("aurea_user_id", userId);
|
|
116
|
+
if (traits) {
|
|
117
|
+
localStorage.setItem("aurea_user_traits", JSON.stringify(traits));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
this.track("user_identified", {
|
|
121
|
+
userId,
|
|
122
|
+
traits
|
|
123
|
+
});
|
|
124
|
+
if (this.config.debug) {
|
|
125
|
+
console.log("[Aurea SDK] User identified:", userId);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Track a page view
|
|
130
|
+
*/
|
|
131
|
+
page(name, properties) {
|
|
132
|
+
this.track("page_view", {
|
|
133
|
+
pageName: name || (typeof document !== "undefined" ? document.title : ""),
|
|
134
|
+
pageUrl: typeof window !== "undefined" ? window.location.href : "",
|
|
135
|
+
pagePath: typeof window !== "undefined" ? window.location.pathname : "",
|
|
136
|
+
pageSearch: typeof window !== "undefined" ? window.location.search : "",
|
|
137
|
+
referrer: typeof document !== "undefined" ? document.referrer : "",
|
|
138
|
+
...properties
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Track a conversion event
|
|
143
|
+
*/
|
|
144
|
+
conversion(data) {
|
|
145
|
+
this.track("conversion", {
|
|
146
|
+
conversionType: data.type,
|
|
147
|
+
revenue: data.revenue,
|
|
148
|
+
currency: data.currency || "USD",
|
|
149
|
+
orderId: data.orderId,
|
|
150
|
+
...data.properties
|
|
151
|
+
});
|
|
152
|
+
if (typeof sessionStorage !== "undefined") {
|
|
153
|
+
sessionStorage.setItem("aurea_converted", "true");
|
|
154
|
+
}
|
|
155
|
+
if (this.config.debug) {
|
|
156
|
+
console.log("[Aurea SDK] Conversion tracked:", data);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get or create session ID
|
|
161
|
+
*/
|
|
162
|
+
getOrCreateSessionId() {
|
|
163
|
+
if (typeof sessionStorage === "undefined") {
|
|
164
|
+
return this.generateId();
|
|
165
|
+
}
|
|
166
|
+
let sessionId = sessionStorage.getItem("aurea_session_id");
|
|
167
|
+
if (!sessionId) {
|
|
168
|
+
sessionId = this.generateId();
|
|
169
|
+
sessionStorage.setItem("aurea_session_id", sessionId);
|
|
170
|
+
}
|
|
171
|
+
return sessionId;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Get or create anonymous ID
|
|
175
|
+
*/
|
|
176
|
+
getOrCreateAnonymousId() {
|
|
177
|
+
if (typeof localStorage === "undefined") {
|
|
178
|
+
return this.generateId();
|
|
179
|
+
}
|
|
180
|
+
let anonymousId = localStorage.getItem("aurea_anonymous_id");
|
|
181
|
+
if (!anonymousId) {
|
|
182
|
+
anonymousId = this.generateId();
|
|
183
|
+
localStorage.setItem("aurea_anonymous_id", anonymousId);
|
|
184
|
+
}
|
|
185
|
+
return anonymousId;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Build event context
|
|
189
|
+
*/
|
|
190
|
+
buildContext() {
|
|
191
|
+
const url = typeof window !== "undefined" ? new URL(window.location.href) : new URL("http://localhost");
|
|
192
|
+
return {
|
|
193
|
+
page: typeof window !== "undefined" ? {
|
|
194
|
+
url: window.location.href,
|
|
195
|
+
path: window.location.pathname,
|
|
196
|
+
title: document.title,
|
|
197
|
+
referrer: document.referrer
|
|
198
|
+
} : void 0,
|
|
199
|
+
utm: {
|
|
200
|
+
source: url.searchParams.get("utm_source") || void 0,
|
|
201
|
+
medium: url.searchParams.get("utm_medium") || void 0,
|
|
202
|
+
campaign: url.searchParams.get("utm_campaign") || void 0,
|
|
203
|
+
term: url.searchParams.get("utm_term") || void 0,
|
|
204
|
+
content: url.searchParams.get("utm_content") || void 0
|
|
205
|
+
},
|
|
206
|
+
user: {
|
|
207
|
+
userId: this.userId,
|
|
208
|
+
anonymousId: this.anonymousId
|
|
209
|
+
},
|
|
210
|
+
session: {
|
|
211
|
+
sessionId: this.sessionId
|
|
212
|
+
},
|
|
213
|
+
device: typeof navigator !== "undefined" ? {
|
|
214
|
+
userAgent: navigator.userAgent,
|
|
215
|
+
screenWidth: window.screen?.width,
|
|
216
|
+
screenHeight: window.screen?.height,
|
|
217
|
+
language: navigator.language,
|
|
218
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
219
|
+
} : void 0
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Track initial page load
|
|
224
|
+
*/
|
|
225
|
+
trackPageLoad() {
|
|
226
|
+
if (typeof window !== "undefined") {
|
|
227
|
+
const justPurchased = localStorage.getItem("aurea_just_purchased");
|
|
228
|
+
const isThankYouPage = window.location.pathname.includes("/thank-you");
|
|
229
|
+
if (justPurchased === "true" && !isThankYouPage) {
|
|
230
|
+
console.log("[Aurea SDK] Purchase detected, redirecting to thank-you page...");
|
|
231
|
+
localStorage.removeItem("aurea_just_purchased");
|
|
232
|
+
window.location.href = "/thank-you?from_checkout=true";
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const referrer = document.referrer;
|
|
236
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
237
|
+
const fromCheckout = urlParams.get("from_checkout") === "true";
|
|
238
|
+
const whopReferrer = referrer.includes("whop.com");
|
|
239
|
+
if ((fromCheckout || whopReferrer || justPurchased === "true") && isThankYouPage) {
|
|
240
|
+
localStorage.removeItem("aurea_just_purchased");
|
|
241
|
+
this.track("checkout_return", {
|
|
242
|
+
referrer,
|
|
243
|
+
returnUrl: window.location.href,
|
|
244
|
+
fromWhop: whopReferrer,
|
|
245
|
+
landingPage: "/thank-you"
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
this.page();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Track page changes (for SPAs)
|
|
253
|
+
*/
|
|
254
|
+
trackPageChanges() {
|
|
255
|
+
if (typeof window === "undefined") return;
|
|
256
|
+
let lastPath = window.location.pathname;
|
|
257
|
+
const observer = new MutationObserver(() => {
|
|
258
|
+
if (window.location.pathname !== lastPath) {
|
|
259
|
+
lastPath = window.location.pathname;
|
|
260
|
+
this.page();
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
observer.observe(document.body, {
|
|
264
|
+
childList: true,
|
|
265
|
+
subtree: true
|
|
266
|
+
});
|
|
267
|
+
window.addEventListener("popstate", () => {
|
|
268
|
+
this.page();
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Track form submissions
|
|
273
|
+
*/
|
|
274
|
+
trackForms() {
|
|
275
|
+
if (typeof document === "undefined") return;
|
|
276
|
+
document.addEventListener("submit", (e) => {
|
|
277
|
+
const form = e.target;
|
|
278
|
+
const formId = form.id || form.name || "unknown";
|
|
279
|
+
this.track("form_submit", {
|
|
280
|
+
formId,
|
|
281
|
+
formAction: form.action,
|
|
282
|
+
formMethod: form.method
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Track scroll depth
|
|
288
|
+
*/
|
|
289
|
+
trackScrollDepth() {
|
|
290
|
+
if (typeof window === "undefined") return;
|
|
291
|
+
const depths = [25, 50, 75, 100];
|
|
292
|
+
const tracked = /* @__PURE__ */ new Set();
|
|
293
|
+
const checkScroll = () => {
|
|
294
|
+
const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight) * 100;
|
|
295
|
+
for (const depth of depths) {
|
|
296
|
+
if (scrollPercent >= depth && !tracked.has(depth)) {
|
|
297
|
+
tracked.add(depth);
|
|
298
|
+
this.track("scroll_depth", { depth });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
window.addEventListener("scroll", checkScroll, { passive: true });
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Enqueue event for batching
|
|
306
|
+
*/
|
|
307
|
+
enqueueEvent(event) {
|
|
308
|
+
this.eventQueue.push(event);
|
|
309
|
+
if (this.eventQueue.length >= (this.config.batchSize || 10)) {
|
|
310
|
+
this.flushEvents();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Send events to API
|
|
315
|
+
*/
|
|
316
|
+
async sendEvents(events) {
|
|
317
|
+
if (events.length === 0) return;
|
|
318
|
+
try {
|
|
319
|
+
const response = await fetch(`${this.config.apiUrl}/track/events`, {
|
|
320
|
+
method: "POST",
|
|
321
|
+
headers: {
|
|
322
|
+
"Content-Type": "application/json",
|
|
323
|
+
"X-Aurea-API-Key": this.config.apiKey,
|
|
324
|
+
"X-Aurea-Funnel-ID": this.config.funnelId
|
|
325
|
+
},
|
|
326
|
+
body: JSON.stringify({
|
|
327
|
+
events,
|
|
328
|
+
batch: true
|
|
329
|
+
}),
|
|
330
|
+
keepalive: true
|
|
331
|
+
});
|
|
332
|
+
if (!response.ok) {
|
|
333
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
334
|
+
}
|
|
335
|
+
if (this.config.debug) {
|
|
336
|
+
console.log("[Aurea SDK] Events sent successfully:", events.length);
|
|
337
|
+
}
|
|
338
|
+
} catch (error) {
|
|
339
|
+
console.error("[Aurea SDK] Failed to send events:", error);
|
|
340
|
+
if (typeof localStorage !== "undefined") {
|
|
341
|
+
const failedEvents = JSON.parse(localStorage.getItem("aurea_failed_events") || "[]") || [];
|
|
342
|
+
failedEvents.push(...events);
|
|
343
|
+
localStorage.setItem("aurea_failed_events", JSON.stringify(failedEvents));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Flush queued events
|
|
349
|
+
*/
|
|
350
|
+
flushEvents() {
|
|
351
|
+
if (this.eventQueue.length === 0) return;
|
|
352
|
+
const eventsToSend = [...this.eventQueue];
|
|
353
|
+
this.eventQueue = [];
|
|
354
|
+
this.sendEvents(eventsToSend);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Start batch timer
|
|
358
|
+
*/
|
|
359
|
+
startBatchTimer() {
|
|
360
|
+
if (typeof window === "undefined") return;
|
|
361
|
+
this.batchTimer = setInterval(() => {
|
|
362
|
+
this.flushEvents();
|
|
363
|
+
}, this.config.batchInterval || 2e3);
|
|
364
|
+
window.addEventListener("beforeunload", () => {
|
|
365
|
+
this.flushEvents();
|
|
366
|
+
});
|
|
367
|
+
document.addEventListener("visibilitychange", () => {
|
|
368
|
+
if (document.hidden) {
|
|
369
|
+
this.flushEvents();
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Poll for purchase completion
|
|
375
|
+
* Checks every 3 seconds if user has made a purchase
|
|
376
|
+
*/
|
|
377
|
+
startPurchasePolling() {
|
|
378
|
+
if (typeof window === "undefined") return;
|
|
379
|
+
this.checkForPurchase();
|
|
380
|
+
setInterval(() => {
|
|
381
|
+
this.checkForPurchase();
|
|
382
|
+
}, 3e3);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Check if user has completed a purchase
|
|
386
|
+
*/
|
|
387
|
+
async checkForPurchase() {
|
|
388
|
+
try {
|
|
389
|
+
const response = await fetch(
|
|
390
|
+
`${this.config.apiUrl?.replace("/api", "")}/api/check-purchase?anonymousId=${this.anonymousId}`
|
|
391
|
+
);
|
|
392
|
+
const data = await response.json();
|
|
393
|
+
if (data.hasPurchased) {
|
|
394
|
+
console.log("[Aurea SDK] Purchase detected! Redirecting to thank-you page...");
|
|
395
|
+
localStorage.setItem("aurea_just_purchased", "true");
|
|
396
|
+
window.location.href = "/thank-you?from_checkout=true";
|
|
397
|
+
}
|
|
398
|
+
} catch (error) {
|
|
399
|
+
if (this.config.debug) {
|
|
400
|
+
console.log("[Aurea SDK] Purchase check failed:", error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Generate unique ID
|
|
406
|
+
*/
|
|
407
|
+
generateId() {
|
|
408
|
+
return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Generate event ID
|
|
412
|
+
*/
|
|
413
|
+
generateEventId() {
|
|
414
|
+
return `evt_${this.generateId()}`;
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
var sdkInstance = null;
|
|
418
|
+
function initAurea(config) {
|
|
419
|
+
if (sdkInstance) {
|
|
420
|
+
console.warn("[Aurea SDK] SDK already initialized");
|
|
421
|
+
return sdkInstance;
|
|
422
|
+
}
|
|
423
|
+
sdkInstance = new AureaSDK(config);
|
|
424
|
+
sdkInstance.init();
|
|
425
|
+
if (typeof window !== "undefined") {
|
|
426
|
+
window.aurea = sdkInstance;
|
|
427
|
+
}
|
|
428
|
+
return sdkInstance;
|
|
429
|
+
}
|
|
430
|
+
function getAurea() {
|
|
431
|
+
return sdkInstance;
|
|
432
|
+
}
|
|
433
|
+
function trackEvent(name, properties) {
|
|
434
|
+
const aurea = getAurea();
|
|
435
|
+
if (aurea) {
|
|
436
|
+
aurea.track(name, properties);
|
|
437
|
+
} else {
|
|
438
|
+
console.warn("[Aurea SDK] SDK not initialized. Call initAurea() first.");
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function identifyUser(userId, traits) {
|
|
442
|
+
const aurea = getAurea();
|
|
443
|
+
if (aurea) {
|
|
444
|
+
aurea.identify(userId, traits);
|
|
445
|
+
} else {
|
|
446
|
+
console.warn("[Aurea SDK] SDK not initialized. Call initAurea() first.");
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
function trackConversion(data) {
|
|
450
|
+
const aurea = getAurea();
|
|
451
|
+
if (aurea) {
|
|
452
|
+
aurea.conversion(data);
|
|
453
|
+
} else {
|
|
454
|
+
console.warn("[Aurea SDK] SDK not initialized. Call initAurea() first.");
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function trackPage(name, properties) {
|
|
458
|
+
const aurea = getAurea();
|
|
459
|
+
if (aurea) {
|
|
460
|
+
aurea.page(name, properties);
|
|
461
|
+
} else {
|
|
462
|
+
console.warn("[Aurea SDK] SDK not initialized. Call initAurea() first.");
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
466
|
+
0 && (module.exports = {
|
|
467
|
+
getAurea,
|
|
468
|
+
identifyUser,
|
|
469
|
+
initAurea,
|
|
470
|
+
trackConversion,
|
|
471
|
+
trackEvent,
|
|
472
|
+
trackPage
|
|
473
|
+
});
|