@stacksee/analytics 0.9.4 → 0.9.5
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/providers/client.js +180 -186
- package/dist/providers/server.js +90 -94
- package/package.json +1 -1
- package/readme.md +28 -39
package/dist/providers/client.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var r = (
|
|
4
|
-
import { B as
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var p = (d, h, e) => h in d ? f(d, h, { enumerable: !0, configurable: !0, writable: !0, value: e }) : d[h] = e;
|
|
3
|
+
var r = (d, h, e) => p(d, typeof h != "symbol" ? h + "" : h, e);
|
|
4
|
+
import { B as u } from "../base.provider-AfFL5W_P.js";
|
|
5
5
|
import { i as a } from "../client-DTHZYkxx.js";
|
|
6
|
-
import { P as
|
|
7
|
-
class
|
|
8
|
-
constructor(
|
|
9
|
-
super({ debug:
|
|
6
|
+
import { P as z } from "../client-DTHZYkxx.js";
|
|
7
|
+
class w extends u {
|
|
8
|
+
constructor(e) {
|
|
9
|
+
super({ debug: e.debug, enabled: e.enabled });
|
|
10
10
|
r(this, "name", "Bento-Client");
|
|
11
11
|
r(this, "bento");
|
|
12
12
|
r(this, "initialized", !1);
|
|
13
13
|
r(this, "config");
|
|
14
14
|
r(this, "scriptLoaded", !1);
|
|
15
|
-
this.config =
|
|
15
|
+
this.config = e;
|
|
16
16
|
}
|
|
17
17
|
async initialize() {
|
|
18
18
|
if (this.isEnabled() && !this.initialized) {
|
|
@@ -24,119 +24,119 @@ class b extends o {
|
|
|
24
24
|
throw new Error("Bento requires a siteUuid");
|
|
25
25
|
try {
|
|
26
26
|
this.scriptLoaded || await this.loadBentoScript(), await this.waitForBento(), this.bento = window.bento, this.initialized = !0, this.log("Initialized successfully", this.config);
|
|
27
|
-
} catch (
|
|
28
|
-
throw console.error("[Bento-Client] Failed to initialize:",
|
|
27
|
+
} catch (e) {
|
|
28
|
+
throw console.error("[Bento-Client] Failed to initialize:", e), e;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async loadBentoScript() {
|
|
33
|
-
return new Promise((
|
|
33
|
+
return new Promise((e, i) => {
|
|
34
34
|
if (document.querySelector(
|
|
35
35
|
'script[src*="bentonow.com"]'
|
|
36
36
|
)) {
|
|
37
|
-
this.scriptLoaded = !0,
|
|
37
|
+
this.scriptLoaded = !0, e();
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
const t = document.createElement("script");
|
|
41
41
|
t.src = `https://fast.bentonow.com?site_uuid=${this.config.siteUuid}`, t.async = !0, t.defer = !0, t.onload = () => {
|
|
42
|
-
this.scriptLoaded = !0,
|
|
42
|
+
this.scriptLoaded = !0, e();
|
|
43
43
|
}, t.onerror = () => {
|
|
44
|
-
|
|
44
|
+
i(new Error("Failed to load Bento script"));
|
|
45
45
|
}, document.head.appendChild(t);
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
async waitForBento(
|
|
49
|
-
for (let s = 0; s <
|
|
48
|
+
async waitForBento(e = 50, i = 100) {
|
|
49
|
+
for (let s = 0; s < e; s++) {
|
|
50
50
|
if (window.bento)
|
|
51
51
|
return;
|
|
52
|
-
await new Promise((t) => setTimeout(t,
|
|
52
|
+
await new Promise((t) => setTimeout(t, i));
|
|
53
53
|
}
|
|
54
54
|
throw new Error("Bento SDK not available after loading script");
|
|
55
55
|
}
|
|
56
|
-
identify(
|
|
56
|
+
identify(e, i) {
|
|
57
57
|
if (!this.isEnabled() || !this.initialized || !this.bento) return;
|
|
58
|
-
const s = (
|
|
59
|
-
if (this.bento.identify(s),
|
|
60
|
-
const t = { ...
|
|
58
|
+
const s = (i == null ? void 0 : i.email) || e;
|
|
59
|
+
if (this.bento.identify(s), i) {
|
|
60
|
+
const t = { ...i };
|
|
61
61
|
delete t.email, Object.keys(t).length > 0 && this.bento.updateFields(t);
|
|
62
62
|
}
|
|
63
|
-
this.log("Identified user", { userId:
|
|
63
|
+
this.log("Identified user", { userId: e, email: s, traits: i });
|
|
64
64
|
}
|
|
65
|
-
track(
|
|
66
|
-
var t, n,
|
|
65
|
+
track(e, i) {
|
|
66
|
+
var t, n, l;
|
|
67
67
|
if (!this.isEnabled() || !this.initialized || !this.bento) return;
|
|
68
68
|
const s = {
|
|
69
|
-
...
|
|
70
|
-
category:
|
|
71
|
-
timestamp:
|
|
72
|
-
...
|
|
73
|
-
...
|
|
74
|
-
...(
|
|
69
|
+
...e.properties,
|
|
70
|
+
category: e.category,
|
|
71
|
+
timestamp: e.timestamp || Date.now(),
|
|
72
|
+
...e.userId && { userId: e.userId },
|
|
73
|
+
...e.sessionId && { sessionId: e.sessionId },
|
|
74
|
+
...(i == null ? void 0 : i.page) && {
|
|
75
75
|
page: {
|
|
76
|
-
url:
|
|
77
|
-
host:
|
|
78
|
-
path:
|
|
79
|
-
title:
|
|
80
|
-
protocol:
|
|
81
|
-
referrer:
|
|
82
|
-
...
|
|
76
|
+
url: i.page.url,
|
|
77
|
+
host: i.page.host,
|
|
78
|
+
path: i.page.path,
|
|
79
|
+
title: i.page.title,
|
|
80
|
+
protocol: i.page.protocol,
|
|
81
|
+
referrer: i.page.referrer,
|
|
82
|
+
...i.page.search && { search: i.page.search }
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
|
-
...(
|
|
86
|
-
...(
|
|
85
|
+
...(i == null ? void 0 : i.device) && { device: i.device },
|
|
86
|
+
...(i == null ? void 0 : i.utm) && { utm: i.utm },
|
|
87
87
|
// Include user email and traits as regular event properties
|
|
88
|
-
...((t =
|
|
89
|
-
...((n =
|
|
90
|
-
...((
|
|
88
|
+
...((t = i == null ? void 0 : i.user) == null ? void 0 : t.email) && { user_email: i.user.email },
|
|
89
|
+
...((n = i == null ? void 0 : i.user) == null ? void 0 : n.traits) && { user_traits: i.user.traits },
|
|
90
|
+
...((l = i == null ? void 0 : i.user) == null ? void 0 : l.userId) && { visitor: i.user.userId }
|
|
91
91
|
};
|
|
92
|
-
this.bento.track(
|
|
92
|
+
this.bento.track(e.action, s), this.log("Tracked event", { event: e, context: i });
|
|
93
93
|
}
|
|
94
|
-
pageView(
|
|
94
|
+
pageView(e, i) {
|
|
95
95
|
var s;
|
|
96
96
|
if (!(!this.isEnabled() || !this.initialized || !this.bento || !a())) {
|
|
97
|
-
if (this.bento.view(),
|
|
97
|
+
if (this.bento.view(), e || i != null && i.page) {
|
|
98
98
|
const t = {
|
|
99
|
-
...
|
|
99
|
+
...e,
|
|
100
100
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
101
|
-
...(
|
|
101
|
+
...(i == null ? void 0 : i.page) && {
|
|
102
102
|
page: {
|
|
103
|
-
url:
|
|
104
|
-
host:
|
|
105
|
-
path:
|
|
106
|
-
title:
|
|
107
|
-
protocol:
|
|
108
|
-
referrer:
|
|
109
|
-
...
|
|
103
|
+
url: i.page.url,
|
|
104
|
+
host: i.page.host,
|
|
105
|
+
path: i.page.path,
|
|
106
|
+
title: i.page.title,
|
|
107
|
+
protocol: i.page.protocol,
|
|
108
|
+
referrer: i.page.referrer,
|
|
109
|
+
...i.page.search && { search: i.page.search }
|
|
110
110
|
}
|
|
111
111
|
},
|
|
112
|
-
...((s =
|
|
112
|
+
...((s = i == null ? void 0 : i.user) == null ? void 0 : s.userId) && { visitor: i.user.userId }
|
|
113
113
|
};
|
|
114
114
|
this.bento.track("$view", t);
|
|
115
115
|
}
|
|
116
|
-
this.log("Tracked page view", { properties:
|
|
116
|
+
this.log("Tracked page view", { properties: e, context: i });
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
pageLeave(
|
|
119
|
+
pageLeave(e, i) {
|
|
120
120
|
var t;
|
|
121
121
|
if (!this.isEnabled() || !this.initialized || !this.bento || !a())
|
|
122
122
|
return;
|
|
123
123
|
const s = {
|
|
124
|
-
...
|
|
124
|
+
...e,
|
|
125
125
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
126
|
-
...(
|
|
126
|
+
...(i == null ? void 0 : i.page) && {
|
|
127
127
|
page: {
|
|
128
|
-
url:
|
|
129
|
-
host:
|
|
130
|
-
path:
|
|
131
|
-
title:
|
|
132
|
-
protocol:
|
|
133
|
-
referrer:
|
|
134
|
-
...
|
|
128
|
+
url: i.page.url,
|
|
129
|
+
host: i.page.host,
|
|
130
|
+
path: i.page.path,
|
|
131
|
+
title: i.page.title,
|
|
132
|
+
protocol: i.page.protocol,
|
|
133
|
+
referrer: i.page.referrer,
|
|
134
|
+
...i.page.search && { search: i.page.search }
|
|
135
135
|
}
|
|
136
136
|
},
|
|
137
|
-
...((t =
|
|
137
|
+
...((t = i == null ? void 0 : i.user) == null ? void 0 : t.userId) && { visitor: i.user.userId }
|
|
138
138
|
};
|
|
139
|
-
this.bento.track("$pageleave", s), this.log("Tracked page leave", { properties:
|
|
139
|
+
this.bento.track("$pageleave", s), this.log("Tracked page leave", { properties: e, context: i });
|
|
140
140
|
}
|
|
141
141
|
reset() {
|
|
142
142
|
!this.isEnabled() || !this.initialized || !this.bento || !a() || this.log("Reset user session - Note: Bento doesn't have a native reset method");
|
|
@@ -153,8 +153,8 @@ class b extends o {
|
|
|
153
153
|
* bentoProvider.tag('beta_tester');
|
|
154
154
|
* ```
|
|
155
155
|
*/
|
|
156
|
-
tag(
|
|
157
|
-
!this.isEnabled() || !this.initialized || !this.bento || !a() || (this.bento.tag(
|
|
156
|
+
tag(e) {
|
|
157
|
+
!this.isEnabled() || !this.initialized || !this.bento || !a() || (this.bento.tag(e), this.log("Added tag to user", { tag: e }));
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
160
|
* Get the current user's email address
|
|
@@ -206,8 +206,8 @@ class b extends o {
|
|
|
206
206
|
* }
|
|
207
207
|
* ```
|
|
208
208
|
*/
|
|
209
|
-
showSurveyForm(
|
|
210
|
-
!this.isEnabled() || !this.initialized || !this.bento || !a() || (this.bento.showSurveyForm(
|
|
209
|
+
showSurveyForm(e, i, s = "popup") {
|
|
210
|
+
!this.isEnabled() || !this.initialized || !this.bento || !a() || (this.bento.showSurveyForm(e, i, s), this.log("Showed survey form", { surveyId: i, type: s }));
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
213
213
|
* Validate an email address using Bento's spam check
|
|
@@ -223,14 +223,14 @@ class b extends o {
|
|
|
223
223
|
* }
|
|
224
224
|
* ```
|
|
225
225
|
*/
|
|
226
|
-
async spamCheck(
|
|
226
|
+
async spamCheck(e) {
|
|
227
227
|
if (!this.isEnabled() || !this.initialized || !this.bento || !a())
|
|
228
228
|
return !1;
|
|
229
229
|
try {
|
|
230
|
-
const
|
|
231
|
-
return this.log("Spam check completed", { email:
|
|
232
|
-
} catch (
|
|
233
|
-
return console.error("[Bento-Client] Spam check failed:",
|
|
230
|
+
const i = await this.bento.spamCheck(e);
|
|
231
|
+
return this.log("Spam check completed", { email: e, result: i }), i;
|
|
232
|
+
} catch (i) {
|
|
233
|
+
return console.error("[Bento-Client] Spam check failed:", i), !1;
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
// ============================================================================
|
|
@@ -276,14 +276,14 @@ class b extends o {
|
|
|
276
276
|
));
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
|
-
class
|
|
280
|
-
constructor(
|
|
281
|
-
super({ debug:
|
|
279
|
+
class m extends u {
|
|
280
|
+
constructor(e) {
|
|
281
|
+
super({ debug: e.debug, enabled: e.enabled });
|
|
282
282
|
r(this, "name", "Pirsch-Client");
|
|
283
283
|
r(this, "client");
|
|
284
284
|
r(this, "initialized", !1);
|
|
285
285
|
r(this, "config");
|
|
286
|
-
this.config =
|
|
286
|
+
this.config = e;
|
|
287
287
|
}
|
|
288
288
|
async initialize() {
|
|
289
289
|
if (this.isEnabled() && !this.initialized) {
|
|
@@ -294,98 +294,92 @@ class w extends o {
|
|
|
294
294
|
if (!this.config.identificationCode || typeof this.config.identificationCode != "string")
|
|
295
295
|
throw new Error("Pirsch requires an identificationCode");
|
|
296
296
|
try {
|
|
297
|
-
const { Pirsch:
|
|
298
|
-
this.client = new
|
|
297
|
+
const { Pirsch: e } = await import("../web-imCcOhDC.js").then((i) => i.w);
|
|
298
|
+
this.client = new e({
|
|
299
299
|
identificationCode: this.config.identificationCode,
|
|
300
300
|
...this.config.hostname && { hostname: this.config.hostname }
|
|
301
301
|
}), this.initialized = !0, this.log("Initialized successfully", this.config);
|
|
302
|
-
} catch (
|
|
302
|
+
} catch (e) {
|
|
303
303
|
throw console.error(
|
|
304
304
|
"[Pirsch-Client] Failed to initialize. Make sure pirsch-sdk is installed:",
|
|
305
|
-
|
|
306
|
-
),
|
|
305
|
+
e
|
|
306
|
+
), e;
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
identify(
|
|
310
|
+
identify(e, i) {
|
|
311
311
|
!this.isEnabled() || !this.initialized || !this.client || (this.client.event("user_identified", 0, {
|
|
312
|
-
userId:
|
|
313
|
-
...
|
|
312
|
+
userId: e,
|
|
313
|
+
...i
|
|
314
314
|
}).catch((s) => {
|
|
315
315
|
console.error("[Pirsch-Client] Failed to track identify event:", s);
|
|
316
|
-
}), this.log("Identified user via event", { userId:
|
|
316
|
+
}), this.log("Identified user via event", { userId: e, traits: i }));
|
|
317
317
|
}
|
|
318
|
-
async track(
|
|
318
|
+
async track(e, i) {
|
|
319
319
|
var t, n;
|
|
320
320
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
321
321
|
const s = {
|
|
322
|
-
...
|
|
323
|
-
category:
|
|
324
|
-
...
|
|
325
|
-
...
|
|
326
|
-
...(
|
|
327
|
-
page_path:
|
|
328
|
-
page_title:
|
|
329
|
-
page_referrer:
|
|
322
|
+
...e.properties,
|
|
323
|
+
category: e.category,
|
|
324
|
+
...e.userId && { userId: e.userId },
|
|
325
|
+
...e.sessionId && { sessionId: e.sessionId },
|
|
326
|
+
...(i == null ? void 0 : i.page) && {
|
|
327
|
+
page_path: i.page.path,
|
|
328
|
+
page_title: i.page.title,
|
|
329
|
+
page_referrer: i.page.referrer
|
|
330
330
|
},
|
|
331
|
-
...(
|
|
332
|
-
...(
|
|
333
|
-
...((t =
|
|
334
|
-
...((n =
|
|
331
|
+
...(i == null ? void 0 : i.device) && { device: i.device },
|
|
332
|
+
...(i == null ? void 0 : i.utm) && { utm: i.utm },
|
|
333
|
+
...((t = i == null ? void 0 : i.user) == null ? void 0 : t.email) && { user_email: i.user.email },
|
|
334
|
+
...((n = i == null ? void 0 : i.user) == null ? void 0 : n.traits) && { user_traits: i.user.traits }
|
|
335
335
|
};
|
|
336
336
|
try {
|
|
337
|
-
await this.client.event(
|
|
338
|
-
} catch (
|
|
339
|
-
console.error("[Pirsch-Client] Failed to track event:",
|
|
337
|
+
await this.client.event(e.action, 0, s), this.log("Tracked event", { event: e, context: i });
|
|
338
|
+
} catch (l) {
|
|
339
|
+
console.error("[Pirsch-Client] Failed to track event:", l);
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
|
-
pageView(
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
this.log("Tracked page view", { properties: i, context: e });
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
pageLeave(i, e) {
|
|
342
|
+
pageView(e, i) {
|
|
343
|
+
var l, g;
|
|
344
|
+
if (!this.isEnabled() || !this.initialized || !this.client || !a())
|
|
345
|
+
return;
|
|
346
|
+
const s = e && Object.keys(e).length > 0 ? Object.fromEntries(
|
|
347
|
+
Object.entries(e).filter(
|
|
348
|
+
([, o]) => typeof o == "string" || typeof o == "number" || typeof o == "boolean"
|
|
349
|
+
)
|
|
350
|
+
) : void 0, t = {
|
|
351
|
+
...((l = i == null ? void 0 : i.page) == null ? void 0 : l.url) && { url: i.page.url },
|
|
352
|
+
...((g = i == null ? void 0 : i.page) == null ? void 0 : g.title) && { title: i.page.title },
|
|
353
|
+
...s && { tags: s }
|
|
354
|
+
}, n = Object.keys(t).length > 0 ? t : void 0;
|
|
355
|
+
this.client.hit(n).catch((o) => {
|
|
356
|
+
console.error("[Pirsch-Client] Failed to track page view:", o);
|
|
357
|
+
}), this.log("Tracked page view", { properties: e, context: i });
|
|
358
|
+
}
|
|
359
|
+
pageLeave(e, i) {
|
|
366
360
|
if (!this.isEnabled() || !this.initialized || !this.client || !a())
|
|
367
361
|
return;
|
|
368
362
|
const s = {
|
|
369
|
-
...
|
|
370
|
-
...(
|
|
371
|
-
path:
|
|
372
|
-
title:
|
|
363
|
+
...e,
|
|
364
|
+
...(i == null ? void 0 : i.page) && {
|
|
365
|
+
path: i.page.path,
|
|
366
|
+
title: i.page.title
|
|
373
367
|
}
|
|
374
368
|
};
|
|
375
369
|
this.client.event("page_leave", 0, s).catch((t) => {
|
|
376
370
|
console.error("[Pirsch-Client] Failed to track page leave:", t);
|
|
377
|
-
}), this.log("Tracked page leave", { properties:
|
|
371
|
+
}), this.log("Tracked page leave", { properties: e, context: i });
|
|
378
372
|
}
|
|
379
373
|
reset() {
|
|
380
|
-
!this.isEnabled() || !this.initialized || !this.client || !a() || (this.client.event("session_reset", 0, {}).catch((
|
|
381
|
-
console.error("[Pirsch-Client] Failed to track session reset:",
|
|
374
|
+
!this.isEnabled() || !this.initialized || !this.client || !a() || (this.client.event("session_reset", 0, {}).catch((e) => {
|
|
375
|
+
console.error("[Pirsch-Client] Failed to track session reset:", e);
|
|
382
376
|
}), this.log("Reset user session"));
|
|
383
377
|
}
|
|
384
378
|
}
|
|
385
|
-
class
|
|
386
|
-
constructor(
|
|
387
|
-
var
|
|
388
|
-
super({ debug:
|
|
379
|
+
class v extends u {
|
|
380
|
+
constructor(e) {
|
|
381
|
+
var i, s, t, n, l;
|
|
382
|
+
super({ debug: e.debug, enabled: e.enabled });
|
|
389
383
|
r(this, "name", "Proxy");
|
|
390
384
|
r(this, "config");
|
|
391
385
|
r(this, "queue", []);
|
|
@@ -395,7 +389,7 @@ class y extends o {
|
|
|
395
389
|
r(this, "retryAttempts");
|
|
396
390
|
r(this, "retryBackoff");
|
|
397
391
|
r(this, "retryInitialDelay");
|
|
398
|
-
this.config =
|
|
392
|
+
this.config = e, this.batchSize = ((i = e.batch) == null ? void 0 : i.size) ?? 10, this.batchInterval = ((s = e.batch) == null ? void 0 : s.interval) ?? 5e3, this.retryAttempts = ((t = e.retry) == null ? void 0 : t.attempts) ?? 3, this.retryBackoff = ((n = e.retry) == null ? void 0 : n.backoff) ?? "exponential", this.retryInitialDelay = ((l = e.retry) == null ? void 0 : l.initialDelay) ?? 1e3, typeof window < "u" && (window.addEventListener("beforeunload", () => {
|
|
399
393
|
this.flush(!0);
|
|
400
394
|
}), document.addEventListener("visibilitychange", () => {
|
|
401
395
|
document.visibilityState === "hidden" && this.flush(!0);
|
|
@@ -404,26 +398,26 @@ class y extends o {
|
|
|
404
398
|
async initialize() {
|
|
405
399
|
this.isEnabled() && this.log("Initialized successfully", { endpoint: this.config.endpoint });
|
|
406
400
|
}
|
|
407
|
-
identify(
|
|
401
|
+
identify(e, i) {
|
|
408
402
|
this.isEnabled() && (this.queueEvent({
|
|
409
403
|
type: "identify",
|
|
410
|
-
userId:
|
|
411
|
-
traits:
|
|
412
|
-
}), this.log("Queued identify event", { userId:
|
|
404
|
+
userId: e,
|
|
405
|
+
traits: i
|
|
406
|
+
}), this.log("Queued identify event", { userId: e, traits: i }));
|
|
413
407
|
}
|
|
414
|
-
async track(
|
|
408
|
+
async track(e, i) {
|
|
415
409
|
this.isEnabled() && (this.queueEvent({
|
|
416
410
|
type: "track",
|
|
417
|
-
event:
|
|
418
|
-
context: this.enrichContext(
|
|
419
|
-
}), this.log("Queued track event", { event:
|
|
411
|
+
event: e,
|
|
412
|
+
context: this.enrichContext(i)
|
|
413
|
+
}), this.log("Queued track event", { event: e, context: i }));
|
|
420
414
|
}
|
|
421
|
-
pageView(
|
|
415
|
+
pageView(e, i) {
|
|
422
416
|
this.isEnabled() && (this.queueEvent({
|
|
423
417
|
type: "pageView",
|
|
424
|
-
properties:
|
|
425
|
-
context: this.enrichContext(
|
|
426
|
-
}), this.log("Queued page view event", { properties:
|
|
418
|
+
properties: e,
|
|
419
|
+
context: this.enrichContext(i)
|
|
420
|
+
}), this.log("Queued page view event", { properties: e, context: i }));
|
|
427
421
|
}
|
|
428
422
|
async reset() {
|
|
429
423
|
this.isEnabled() && (this.queueEvent({
|
|
@@ -436,27 +430,27 @@ class y extends o {
|
|
|
436
430
|
/**
|
|
437
431
|
* Manually flush all queued events
|
|
438
432
|
*/
|
|
439
|
-
async flush(
|
|
433
|
+
async flush(e = !1) {
|
|
440
434
|
if (this.queue.length === 0) return;
|
|
441
|
-
const
|
|
442
|
-
this.queue = [], this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = void 0), await this.sendEvents(
|
|
435
|
+
const i = [...this.queue];
|
|
436
|
+
this.queue = [], this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = void 0), await this.sendEvents(i, e);
|
|
443
437
|
}
|
|
444
|
-
queueEvent(
|
|
445
|
-
if (this.queue.push(
|
|
446
|
-
this.flush().catch((
|
|
447
|
-
console.error("[Proxy] Failed to flush events:",
|
|
438
|
+
queueEvent(e) {
|
|
439
|
+
if (this.queue.push(e), this.queue.length >= this.batchSize) {
|
|
440
|
+
this.flush().catch((i) => {
|
|
441
|
+
console.error("[Proxy] Failed to flush events:", i);
|
|
448
442
|
});
|
|
449
443
|
return;
|
|
450
444
|
}
|
|
451
445
|
this.flushTimer || (this.flushTimer = setTimeout(() => {
|
|
452
|
-
this.flush().catch((
|
|
453
|
-
console.error("[Proxy] Failed to flush events:",
|
|
446
|
+
this.flush().catch((i) => {
|
|
447
|
+
console.error("[Proxy] Failed to flush events:", i);
|
|
454
448
|
});
|
|
455
449
|
}, this.batchInterval));
|
|
456
450
|
}
|
|
457
|
-
async sendEvents(
|
|
458
|
-
const s = { events:
|
|
459
|
-
if (
|
|
451
|
+
async sendEvents(e, i = !1) {
|
|
452
|
+
const s = { events: e };
|
|
453
|
+
if (i && typeof navigator < "u" && navigator.sendBeacon) {
|
|
460
454
|
const t = new Blob([JSON.stringify(s)], {
|
|
461
455
|
type: "application/json"
|
|
462
456
|
});
|
|
@@ -465,7 +459,7 @@ class y extends o {
|
|
|
465
459
|
}
|
|
466
460
|
await this.sendWithRetry(s);
|
|
467
461
|
}
|
|
468
|
-
async sendWithRetry(
|
|
462
|
+
async sendWithRetry(e, i = 0) {
|
|
469
463
|
try {
|
|
470
464
|
const s = await fetch(this.config.endpoint, {
|
|
471
465
|
method: "POST",
|
|
@@ -473,39 +467,39 @@ class y extends o {
|
|
|
473
467
|
"Content-Type": "application/json",
|
|
474
468
|
...this.config.headers
|
|
475
469
|
},
|
|
476
|
-
body: JSON.stringify(
|
|
470
|
+
body: JSON.stringify(e),
|
|
477
471
|
// Don't include credentials by default
|
|
478
472
|
credentials: "same-origin"
|
|
479
473
|
});
|
|
480
474
|
if (!s.ok)
|
|
481
475
|
throw new Error(`HTTP ${s.status}: ${s.statusText}`);
|
|
482
|
-
this.log(`Sent ${
|
|
476
|
+
this.log(`Sent ${e.events.length} events successfully`);
|
|
483
477
|
} catch (s) {
|
|
484
|
-
if (
|
|
485
|
-
const t = this.calculateRetryDelay(
|
|
486
|
-
return this.log(`Retry attempt ${
|
|
478
|
+
if (i < this.retryAttempts) {
|
|
479
|
+
const t = this.calculateRetryDelay(i);
|
|
480
|
+
return this.log(`Retry attempt ${i + 1} after ${t}ms`, { error: s }), await new Promise((n) => setTimeout(n, t)), this.sendWithRetry(e, i + 1);
|
|
487
481
|
}
|
|
488
482
|
throw console.error("[Proxy] Failed to send events after retries:", s), s;
|
|
489
483
|
}
|
|
490
484
|
}
|
|
491
|
-
calculateRetryDelay(
|
|
492
|
-
return this.retryBackoff === "exponential" ? this.retryInitialDelay * 2 **
|
|
485
|
+
calculateRetryDelay(e) {
|
|
486
|
+
return this.retryBackoff === "exponential" ? this.retryInitialDelay * 2 ** e : this.retryInitialDelay * (e + 1);
|
|
493
487
|
}
|
|
494
|
-
enrichContext(
|
|
495
|
-
return typeof window > "u" ?
|
|
496
|
-
...
|
|
488
|
+
enrichContext(e) {
|
|
489
|
+
return typeof window > "u" ? e || {} : {
|
|
490
|
+
...e,
|
|
497
491
|
page: {
|
|
498
492
|
path: window.location.pathname,
|
|
499
493
|
title: document.title,
|
|
500
494
|
referrer: document.referrer,
|
|
501
|
-
...
|
|
495
|
+
...e == null ? void 0 : e.page,
|
|
502
496
|
url: window.location.href
|
|
503
497
|
},
|
|
504
498
|
user: {
|
|
505
|
-
...
|
|
499
|
+
...e == null ? void 0 : e.user
|
|
506
500
|
},
|
|
507
501
|
device: {
|
|
508
|
-
...
|
|
502
|
+
...e == null ? void 0 : e.device,
|
|
509
503
|
userAgent: navigator.userAgent,
|
|
510
504
|
language: navigator.language,
|
|
511
505
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
@@ -522,9 +516,9 @@ class y extends o {
|
|
|
522
516
|
}
|
|
523
517
|
}
|
|
524
518
|
export {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
519
|
+
u as BaseAnalyticsProvider,
|
|
520
|
+
w as BentoClientProvider,
|
|
521
|
+
m as PirschClientProvider,
|
|
522
|
+
z as PostHogClientProvider,
|
|
523
|
+
v as ProxyProvider
|
|
530
524
|
};
|
package/dist/providers/server.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { B as
|
|
5
|
-
import { P } from "../server-DjEk1fUD.js";
|
|
6
|
-
class
|
|
1
|
+
var P = Object.defineProperty;
|
|
2
|
+
var z = (n, t, i) => t in n ? P(n, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : n[t] = i;
|
|
3
|
+
var p = (n, t, i) => z(n, typeof t != "symbol" ? t + "" : t, i);
|
|
4
|
+
import { B as I } from "../base.provider-AfFL5W_P.js";
|
|
5
|
+
import { P as _ } from "../server-DjEk1fUD.js";
|
|
6
|
+
class A extends I {
|
|
7
7
|
constructor(i) {
|
|
8
8
|
super({ debug: i.debug, enabled: i.enabled });
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
p(this, "name", "Bento-Server");
|
|
10
|
+
p(this, "client");
|
|
11
|
+
p(this, "initialized", !1);
|
|
12
|
+
p(this, "config");
|
|
13
|
+
p(this, "currentUserEmail");
|
|
14
14
|
this.config = i;
|
|
15
15
|
}
|
|
16
16
|
async initialize() {
|
|
@@ -23,7 +23,7 @@ class w extends c {
|
|
|
23
23
|
if (!((e = this.config.authentication) != null && e.secretKey) || typeof this.config.authentication.secretKey != "string")
|
|
24
24
|
throw new Error("Bento requires authentication.secretKey");
|
|
25
25
|
try {
|
|
26
|
-
const { Analytics: r } = await import("../bento-node-sdk.esm-CWEAoj97.js"), { debug:
|
|
26
|
+
const { Analytics: r } = await import("../bento-node-sdk.esm-CWEAoj97.js"), { debug: s, enabled: a, ...o } = this.config;
|
|
27
27
|
this.client = new r(o), this.initialized = !0, this.log("Initialized successfully", {
|
|
28
28
|
siteUuid: this.config.siteUuid
|
|
29
29
|
});
|
|
@@ -43,25 +43,25 @@ class w extends c {
|
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
this.currentUserEmail = r;
|
|
46
|
-
const
|
|
47
|
-
delete
|
|
46
|
+
const s = e ? { ...e } : {};
|
|
47
|
+
delete s.email, this.client.V1.addSubscriber({
|
|
48
48
|
email: r,
|
|
49
|
-
fields:
|
|
49
|
+
fields: s
|
|
50
50
|
}).catch((a) => {
|
|
51
51
|
console.error("[Bento-Server] Failed to identify user:", a);
|
|
52
52
|
}), this.log("Identified user", { userId: i, email: r, traits: e });
|
|
53
53
|
}
|
|
54
54
|
async track(i, e) {
|
|
55
|
-
var o,
|
|
55
|
+
var o, l, h, d;
|
|
56
56
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
57
|
-
const r = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail || ((
|
|
57
|
+
const r = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail || ((l = e == null ? void 0 : e.user) == null ? void 0 : l.userId) || i.userId;
|
|
58
58
|
if (!r || !r.includes("@")) {
|
|
59
59
|
console.warn(
|
|
60
60
|
"[Bento-Server] Skipping event - Bento requires an email address. Anonymous events are not currently supported by the Bento Node SDK. For now, use the Bento client provider for anonymous tracking. If you're using a proxy, use the hybrid pattern as described in the docs. For identified users, call identify() with a valid email before tracking events."
|
|
61
61
|
);
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
-
const
|
|
64
|
+
const s = {
|
|
65
65
|
...i.properties,
|
|
66
66
|
category: i.category,
|
|
67
67
|
timestamp: i.timestamp || Date.now(),
|
|
@@ -81,20 +81,20 @@ class w extends c {
|
|
|
81
81
|
...(e == null ? void 0 : e.utm) && { utm: e.utm },
|
|
82
82
|
site: this.config.siteUuid,
|
|
83
83
|
...((h = e == null ? void 0 : e.user) == null ? void 0 : h.userId) && { visitor: e.user.userId }
|
|
84
|
-
}, a = ((
|
|
84
|
+
}, a = ((d = e == null ? void 0 : e.user) == null ? void 0 : d.traits) || {};
|
|
85
85
|
try {
|
|
86
86
|
await this.client.V1.track({
|
|
87
87
|
email: r,
|
|
88
88
|
type: `$${i.action}`,
|
|
89
|
-
details:
|
|
89
|
+
details: s,
|
|
90
90
|
fields: a
|
|
91
91
|
}), this.log("Tracked event", { event: i, context: e });
|
|
92
|
-
} catch (
|
|
93
|
-
console.error("[Bento-Server] Failed to track event:",
|
|
92
|
+
} catch (g) {
|
|
93
|
+
console.error("[Bento-Server] Failed to track event:", g);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
pageView(i, e) {
|
|
97
|
-
var o,
|
|
97
|
+
var o, l, h;
|
|
98
98
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
99
99
|
const r = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail;
|
|
100
100
|
if (!r || !r.includes("@")) {
|
|
@@ -103,7 +103,7 @@ class w extends c {
|
|
|
103
103
|
);
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
-
const
|
|
106
|
+
const s = {
|
|
107
107
|
...i,
|
|
108
108
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
109
109
|
...(e == null ? void 0 : e.page) && {
|
|
@@ -118,15 +118,15 @@ class w extends c {
|
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
120
|
site: this.config.siteUuid,
|
|
121
|
-
...((
|
|
121
|
+
...((l = e == null ? void 0 : e.user) == null ? void 0 : l.userId) && { visitor: e.user.userId }
|
|
122
122
|
}, a = ((h = e == null ? void 0 : e.user) == null ? void 0 : h.traits) || {};
|
|
123
123
|
this.client.V1.track({
|
|
124
124
|
email: r,
|
|
125
125
|
type: "$view",
|
|
126
|
-
details:
|
|
126
|
+
details: s,
|
|
127
127
|
fields: a
|
|
128
|
-
}).catch((
|
|
129
|
-
console.error("[Bento-Server] Failed to track page view:",
|
|
128
|
+
}).catch((d) => {
|
|
129
|
+
console.error("[Bento-Server] Failed to track page view:", d);
|
|
130
130
|
}), this.log("Tracked page view", { properties: i, context: e });
|
|
131
131
|
}
|
|
132
132
|
async reset() {
|
|
@@ -136,13 +136,13 @@ class w extends c {
|
|
|
136
136
|
this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
class
|
|
139
|
+
class K extends I {
|
|
140
140
|
constructor(i) {
|
|
141
141
|
super({ debug: i.debug, enabled: i.enabled });
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
p(this, "name", "Pirsch-Server");
|
|
143
|
+
p(this, "client");
|
|
144
|
+
p(this, "initialized", !1);
|
|
145
|
+
p(this, "config");
|
|
146
146
|
this.config = i;
|
|
147
147
|
}
|
|
148
148
|
async initialize() {
|
|
@@ -152,8 +152,8 @@ class k extends c {
|
|
|
152
152
|
if (!this.config.clientSecret || typeof this.config.clientSecret != "string")
|
|
153
153
|
throw new Error("Pirsch requires a clientSecret (or access key)");
|
|
154
154
|
try {
|
|
155
|
-
const { Pirsch: i } = await import("../index-zS7gy63J.js").then((a) => a.i), { debug: e, enabled: r, ...
|
|
156
|
-
this.client = new i(
|
|
155
|
+
const { Pirsch: i } = await import("../index-zS7gy63J.js").then((a) => a.i), { debug: e, enabled: r, ...s } = this.config;
|
|
156
|
+
this.client = new i(s), this.initialized = !0, this.log("Initialized successfully", {
|
|
157
157
|
hostname: this.config.hostname
|
|
158
158
|
});
|
|
159
159
|
} catch (i) {
|
|
@@ -170,7 +170,7 @@ class k extends c {
|
|
|
170
170
|
url: "https://identify",
|
|
171
171
|
ip: "0.0.0.0",
|
|
172
172
|
user_agent: "analytics-library"
|
|
173
|
-
},
|
|
173
|
+
}, s = {
|
|
174
174
|
userId: i,
|
|
175
175
|
...e && Object.fromEntries(
|
|
176
176
|
Object.entries(e).filter(
|
|
@@ -178,60 +178,56 @@ class k extends c {
|
|
|
178
178
|
)
|
|
179
179
|
)
|
|
180
180
|
};
|
|
181
|
-
this.client.event("user_identified", r, 0,
|
|
181
|
+
this.client.event("user_identified", r, 0, s).catch((a) => {
|
|
182
182
|
console.error("[Pirsch-Server] Failed to track identify event:", a);
|
|
183
183
|
}), this.log("Identified user via event", { userId: i, traits: e });
|
|
184
184
|
}
|
|
185
185
|
async track(i, e) {
|
|
186
|
-
var
|
|
186
|
+
var g, f, y, c, m, v, b, w, u, S, E;
|
|
187
187
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
188
|
-
const r = {
|
|
189
|
-
url: ((
|
|
190
|
-
ip:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
...((h = e == null ? void 0 : e.page) == null ? void 0 : h.referrer) && { referrer: e.page.referrer }
|
|
196
|
-
}, a = {
|
|
188
|
+
const r = e, s = ((g = r == null ? void 0 : r.device) == null ? void 0 : g.ip) || "0.0.0.0", a = ((f = r == null ? void 0 : r.server) == null ? void 0 : f.userAgent) || ((y = r == null ? void 0 : r.device) == null ? void 0 : y.userAgent) || "unknown", l = {
|
|
189
|
+
url: ((c = e == null ? void 0 : e.page) == null ? void 0 : c.url) || ((m = e == null ? void 0 : e.page) != null && m.protocol && ((v = e == null ? void 0 : e.page) != null && v.host) && ((b = e == null ? void 0 : e.page) != null && b.path) ? `${e.page.protocol}://${e.page.host}${e.page.path}` : (w = e == null ? void 0 : e.page) != null && w.path ? `https://${this.config.hostname}${e.page.path}` : "https://event"),
|
|
190
|
+
ip: s,
|
|
191
|
+
user_agent: a,
|
|
192
|
+
...((u = e == null ? void 0 : e.page) == null ? void 0 : u.title) && { title: e.page.title },
|
|
193
|
+
...((S = e == null ? void 0 : e.page) == null ? void 0 : S.referrer) && { referrer: e.page.referrer }
|
|
194
|
+
}, d = {
|
|
197
195
|
...Object.fromEntries(
|
|
198
196
|
Object.entries(i.properties).filter(
|
|
199
|
-
([,
|
|
197
|
+
([, k]) => typeof k == "string" || typeof k == "number" || typeof k == "boolean"
|
|
200
198
|
)
|
|
201
199
|
),
|
|
202
200
|
category: i.category,
|
|
203
201
|
timestamp: String(i.timestamp || Date.now()),
|
|
204
202
|
...i.userId && { userId: i.userId },
|
|
205
203
|
...i.sessionId && { sessionId: i.sessionId },
|
|
206
|
-
...((
|
|
204
|
+
...((E = e == null ? void 0 : e.user) == null ? void 0 : E.email) && { user_email: e.user.email }
|
|
207
205
|
};
|
|
208
206
|
try {
|
|
209
|
-
await this.client.event(i.action,
|
|
210
|
-
} catch (
|
|
211
|
-
console.error("[Pirsch-Server] Failed to track event:",
|
|
207
|
+
await this.client.event(i.action, l, 0, d), this.log("Tracked event", { event: i, context: e });
|
|
208
|
+
} catch (k) {
|
|
209
|
+
console.error("[Pirsch-Server] Failed to track event:", k);
|
|
212
210
|
}
|
|
213
211
|
}
|
|
214
212
|
pageView(i, e) {
|
|
215
|
-
var
|
|
213
|
+
var h, d, g, f, y, c, m, v, b, w;
|
|
216
214
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
217
|
-
const r = {
|
|
218
|
-
url: ((
|
|
219
|
-
ip:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
...((a = e == null ? void 0 : e.page) == null ? void 0 : a.title) && { title: e.page.title },
|
|
224
|
-
...((o = e == null ? void 0 : e.page) == null ? void 0 : o.referrer) && { referrer: e.page.referrer },
|
|
215
|
+
const r = e, s = ((h = r == null ? void 0 : r.device) == null ? void 0 : h.ip) || "0.0.0.0", a = ((d = r == null ? void 0 : r.server) == null ? void 0 : d.userAgent) || ((g = r == null ? void 0 : r.device) == null ? void 0 : g.userAgent) || "unknown", l = {
|
|
216
|
+
url: ((f = e == null ? void 0 : e.page) == null ? void 0 : f.url) || ((y = e == null ? void 0 : e.page) != null && y.protocol && ((c = e == null ? void 0 : e.page) != null && c.host) && ((m = e == null ? void 0 : e.page) != null && m.path) ? `${e.page.protocol}://${e.page.host}${e.page.path}` : (v = e == null ? void 0 : e.page) != null && v.path ? `https://${this.config.hostname}${e.page.path}` : "https://pageview"),
|
|
217
|
+
ip: s,
|
|
218
|
+
user_agent: a,
|
|
219
|
+
...((b = e == null ? void 0 : e.page) == null ? void 0 : b.title) && { title: e.page.title },
|
|
220
|
+
...((w = e == null ? void 0 : e.page) == null ? void 0 : w.referrer) && { referrer: e.page.referrer },
|
|
225
221
|
...i && {
|
|
226
222
|
tags: Object.fromEntries(
|
|
227
223
|
Object.entries(i).filter(
|
|
228
|
-
([,
|
|
224
|
+
([, u]) => typeof u == "string" || typeof u == "number" || typeof u == "boolean"
|
|
229
225
|
)
|
|
230
226
|
)
|
|
231
227
|
}
|
|
232
228
|
};
|
|
233
|
-
this.client.hit(
|
|
234
|
-
console.error("[Pirsch-Server] Failed to track page view:",
|
|
229
|
+
this.client.hit(l).catch((u) => {
|
|
230
|
+
console.error("[Pirsch-Server] Failed to track page view:", u);
|
|
235
231
|
}), this.log("Tracked page view", { properties: i, context: e });
|
|
236
232
|
}
|
|
237
233
|
async reset() {
|
|
@@ -249,68 +245,68 @@ class k extends c {
|
|
|
249
245
|
this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
|
|
250
246
|
}
|
|
251
247
|
}
|
|
252
|
-
async function
|
|
248
|
+
async function B(n, t, i) {
|
|
253
249
|
var e, r;
|
|
254
250
|
try {
|
|
255
|
-
const
|
|
256
|
-
if (!
|
|
251
|
+
const s = await n.json();
|
|
252
|
+
if (!s.events || !Array.isArray(s.events))
|
|
257
253
|
throw new Error("Invalid payload: missing events array");
|
|
258
|
-
const a = i != null && i.extractIp ? i.extractIp(
|
|
259
|
-
for (const
|
|
254
|
+
const a = i != null && i.extractIp ? i.extractIp(n) : F(n), o = i != null && i.enrichContext ? i.enrichContext(n) : {};
|
|
255
|
+
for (const l of s.events)
|
|
260
256
|
try {
|
|
261
|
-
switch (
|
|
257
|
+
switch (l.type) {
|
|
262
258
|
case "track": {
|
|
263
259
|
const h = {
|
|
264
|
-
...
|
|
260
|
+
...l.context,
|
|
265
261
|
...o,
|
|
266
262
|
device: {
|
|
267
|
-
...(e =
|
|
263
|
+
...(e = l.context) == null ? void 0 : e.device,
|
|
268
264
|
// Add IP (using type assertion for extended fields)
|
|
269
265
|
// biome-ignore lint/suspicious/noExplicitAny: IP field not in base device type
|
|
270
266
|
...a ? { ip: a } : {}
|
|
271
267
|
}
|
|
272
268
|
};
|
|
273
|
-
await
|
|
274
|
-
userId:
|
|
275
|
-
sessionId:
|
|
269
|
+
await t.track(l.event.action, l.event.properties, {
|
|
270
|
+
userId: l.event.userId,
|
|
271
|
+
sessionId: l.event.sessionId,
|
|
276
272
|
// biome-ignore lint/suspicious/noExplicitAny: Generic context forwarding requires type assertion
|
|
277
273
|
context: h
|
|
278
274
|
});
|
|
279
275
|
break;
|
|
280
276
|
}
|
|
281
277
|
case "identify": {
|
|
282
|
-
|
|
278
|
+
t.identify(l.userId, l.traits);
|
|
283
279
|
break;
|
|
284
280
|
}
|
|
285
281
|
case "pageView": {
|
|
286
282
|
const h = {
|
|
287
|
-
...
|
|
283
|
+
...l.context,
|
|
288
284
|
...o,
|
|
289
285
|
device: {
|
|
290
|
-
...(r =
|
|
286
|
+
...(r = l.context) == null ? void 0 : r.device,
|
|
291
287
|
// biome-ignore lint/suspicious/noExplicitAny: IP field not in base device type
|
|
292
288
|
// Add IP (using type assertion for extended fields)
|
|
293
289
|
...a ? { ip: a } : {}
|
|
294
290
|
}
|
|
295
291
|
};
|
|
296
|
-
|
|
292
|
+
t.pageView(l.properties, h);
|
|
297
293
|
break;
|
|
298
294
|
}
|
|
299
295
|
case "reset":
|
|
300
296
|
break;
|
|
301
297
|
default:
|
|
302
|
-
console.warn("[Proxy] Unknown event type:",
|
|
298
|
+
console.warn("[Proxy] Unknown event type:", l);
|
|
303
299
|
}
|
|
304
300
|
} catch (h) {
|
|
305
301
|
i != null && i.onError ? i.onError(h) : console.error("[Proxy] Failed to process event:", h);
|
|
306
302
|
}
|
|
307
|
-
} catch (
|
|
308
|
-
throw i != null && i.onError ? i.onError(
|
|
303
|
+
} catch (s) {
|
|
304
|
+
throw i != null && i.onError ? i.onError(s) : console.error("[Proxy] Failed to ingest events:", s), s;
|
|
309
305
|
}
|
|
310
306
|
}
|
|
311
|
-
function
|
|
307
|
+
function F(n) {
|
|
312
308
|
var i;
|
|
313
|
-
const
|
|
309
|
+
const t = [
|
|
314
310
|
"x-forwarded-for",
|
|
315
311
|
"x-real-ip",
|
|
316
312
|
"cf-connecting-ip",
|
|
@@ -318,26 +314,26 @@ function b(l) {
|
|
|
318
314
|
"x-client-ip",
|
|
319
315
|
"x-cluster-client-ip"
|
|
320
316
|
];
|
|
321
|
-
for (const e of
|
|
322
|
-
const r =
|
|
317
|
+
for (const e of t) {
|
|
318
|
+
const r = n.headers.get(e);
|
|
323
319
|
if (r)
|
|
324
320
|
return (i = r.split(",")[0]) == null ? void 0 : i.trim();
|
|
325
321
|
}
|
|
326
322
|
}
|
|
327
|
-
function
|
|
323
|
+
function O(n, t) {
|
|
328
324
|
return async (i) => {
|
|
329
325
|
try {
|
|
330
|
-
return await
|
|
326
|
+
return await B(i, n, t), new Response("OK", { status: 200 });
|
|
331
327
|
} catch (e) {
|
|
332
328
|
return console.error("[Proxy] Handler error:", e), new Response("Internal Server Error", { status: 500 });
|
|
333
329
|
}
|
|
334
330
|
};
|
|
335
331
|
}
|
|
336
332
|
export {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
333
|
+
I as BaseAnalyticsProvider,
|
|
334
|
+
A as BentoServerProvider,
|
|
335
|
+
K as PirschServerProvider,
|
|
336
|
+
_ as PostHogServerProvider,
|
|
337
|
+
O as createProxyHandler,
|
|
338
|
+
B as ingestProxyEvents
|
|
343
339
|
};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -2,38 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A highly typed, zero-dependency, provider-agnostic analytics library for TypeScript applications. Works seamlessly on both client and server sides with full type safety for your custom events.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- [
|
|
10
|
-
- [Quick Start](
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- [3. Server-Side Usage](#3-server-side-usage)
|
|
14
|
-
- [Async Tracking](#async-tracking-when-to-await-vs-fire-and-forget)
|
|
15
|
-
- [Fire-and-forget (Client-side typical usage)](#fire-and-forget-client-side-typical-usage)
|
|
16
|
-
- [Await for critical events (Server-side typical usage)](#await-for-critical-events-server-side-typical-usage)
|
|
17
|
-
- [Error handling](#error-handling)
|
|
18
|
-
- [Best practices](#best-practices)
|
|
19
|
-
- [A complete example](#a-complete-example)
|
|
20
|
-
- [Advanced Usage](#advanced-usage)
|
|
21
|
-
- [Creating a Typed Analytics Service](#creating-a-typed-analytics-service)
|
|
22
|
-
- [Event Categories](#event-categories)
|
|
23
|
-
- [Adding Custom Providers](#adding-custom-providers)
|
|
24
|
-
- [Client-Only and Server-Only Providers](#client-only-and-server-only-providers)
|
|
25
|
-
- [Using Multiple Providers](#using-multiple-providers)
|
|
26
|
-
- [Server Deployments and waitUntil](#server-deployments-and-waituntil)
|
|
27
|
-
- [Vercel Functions](#vercel-functions)
|
|
28
|
-
- [Cloudflare Workers](#cloudflare-workers)
|
|
29
|
-
- [Netlify Functions](#netlify-functions)
|
|
30
|
-
- [API Reference](#api-reference)
|
|
31
|
-
- [Client API](#client-api)
|
|
32
|
-
- [Server API](#server-api)
|
|
33
|
-
- [Type Helpers](#type-helpers)
|
|
34
|
-
- [Best Practices](#best-practices)
|
|
35
|
-
- [Contributing](#contributing)
|
|
36
|
-
- [License](#license)
|
|
5
|
+
> **📚 [Full Documentation](https://stacksee-analytics.vercel.app)** - For complete guides, examples, and API reference, visit our documentation site.
|
|
6
|
+
|
|
7
|
+
## Quick Links
|
|
8
|
+
|
|
9
|
+
- 📖 [Documentation](https://stacksee-analytics.vercel.app)
|
|
10
|
+
- 🚀 [Quick Start](https://stacksee-analytics.vercel.app/docs/quick-start)
|
|
11
|
+
- 🔌 [Providers](https://stacksee-analytics.vercel.app/docs/providers)
|
|
12
|
+
- 💡 [Core Concepts](https://stacksee-analytics.vercel.app/docs/core-concepts)
|
|
37
13
|
|
|
38
14
|
## Features
|
|
39
15
|
|
|
@@ -53,15 +29,15 @@ The library includes built-in support for popular analytics services, with more
|
|
|
53
29
|
|
|
54
30
|
| Provider | Type | Documentation |
|
|
55
31
|
|----------|------|---------------|
|
|
56
|
-
| **PostHog** | Product Analytics | [
|
|
57
|
-
| **Bento** | Email Marketing & Events | [
|
|
58
|
-
| **Pirsch** | Privacy-Focused Web Analytics | [
|
|
32
|
+
| **PostHog** | Product Analytics | [View Docs](https://stacksee-analytics.vercel.app/docs/providers/posthog) |
|
|
33
|
+
| **Bento** | Email Marketing & Events | [View Docs](https://stacksee-analytics.vercel.app/docs/providers/bento) |
|
|
34
|
+
| **Pirsch** | Privacy-Focused Web Analytics | [View Docs](https://stacksee-analytics.vercel.app/docs/providers/pirsch) |
|
|
59
35
|
|
|
60
36
|
### Community & Custom Providers
|
|
61
37
|
|
|
62
38
|
Want to use a different analytics service? Check out our guide:
|
|
63
39
|
|
|
64
|
-
**[Creating Custom Providers →](
|
|
40
|
+
**[Creating Custom Providers →](https://stacksee-analytics.vercel.app/docs/providers/custom)**
|
|
65
41
|
|
|
66
42
|
You can easily create providers for:
|
|
67
43
|
- Google Analytics
|
|
@@ -72,7 +48,7 @@ You can easily create providers for:
|
|
|
72
48
|
- Loops
|
|
73
49
|
- Any analytics service with a JavaScript SDK
|
|
74
50
|
|
|
75
|
-
**[View all provider documentation →](
|
|
51
|
+
**[View all provider documentation →](https://stacksee-analytics.vercel.app/docs/providers)**
|
|
76
52
|
|
|
77
53
|
## Installation
|
|
78
54
|
|
|
@@ -89,7 +65,7 @@ pnpm install @bentonow/bento-node-sdk
|
|
|
89
65
|
pnpm install pirsch-sdk
|
|
90
66
|
```
|
|
91
67
|
|
|
92
|
-
> **See also:** [Provider Documentation](
|
|
68
|
+
> **See also:** [Provider Documentation](https://stacksee-analytics.vercel.app/docs/providers) for detailed setup guides for each provider.
|
|
93
69
|
|
|
94
70
|
## Quick Start
|
|
95
71
|
|
|
@@ -745,7 +721,7 @@ export const appEvents = {
|
|
|
745
721
|
|
|
746
722
|
Want to integrate with a different analytics service? See our comprehensive guide:
|
|
747
723
|
|
|
748
|
-
**[Creating Custom Providers →](
|
|
724
|
+
**[Creating Custom Providers →](https://stacksee-analytics.vercel.app/docs/providers/custom)**
|
|
749
725
|
|
|
750
726
|
Quick example:
|
|
751
727
|
|
|
@@ -1064,6 +1040,19 @@ const analytics = createServerAnalytics<AppEvents>({
|
|
|
1064
1040
|
7. **Document events** - Add comments to explain when each event should be fired
|
|
1065
1041
|
8. **Create provider instances once** - Reuse provider instances across your app
|
|
1066
1042
|
|
|
1043
|
+
---
|
|
1044
|
+
|
|
1045
|
+
## Learn More
|
|
1046
|
+
|
|
1047
|
+
This README provides a quick overview. For comprehensive documentation, guides, and examples:
|
|
1048
|
+
|
|
1049
|
+
**📚 [Visit the Full Documentation](https://stacksee-analytics.vercel.app)**
|
|
1050
|
+
|
|
1051
|
+
- [Quick Start Guide](https://stacksee-analytics.vercel.app/docs/quick-start)
|
|
1052
|
+
- [Core Concepts](https://stacksee-analytics.vercel.app/docs/core-concepts)
|
|
1053
|
+
- [Provider Setup Guides](https://stacksee-analytics.vercel.app/docs/providers)
|
|
1054
|
+
- [API Reference](https://stacksee-analytics.vercel.app/docs/api-reference)
|
|
1055
|
+
|
|
1067
1056
|
## Contributing
|
|
1068
1057
|
|
|
1069
1058
|
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
|