@stacksee/analytics 0.7.0 → 0.8.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/dist/providers/client.d.ts +3 -0
- package/dist/providers/client.js +262 -122
- package/dist/providers/proxy/client.d.ts +56 -0
- package/dist/providers/proxy/server.d.ts +55 -0
- package/dist/providers/proxy/types.d.ts +64 -0
- package/dist/providers/server.d.ts +2 -0
- package/dist/providers/server.js +205 -122
- package/package.json +1 -1
|
@@ -5,3 +5,6 @@ export { BentoClientProvider } from './bento/client.js';
|
|
|
5
5
|
export type { BentoClientConfig } from './bento/client.js';
|
|
6
6
|
export { PirschClientProvider } from './pirsch/client.js';
|
|
7
7
|
export type { PirschClientConfig } from './pirsch/client.js';
|
|
8
|
+
export { ProxyProvider } from './proxy/client.js';
|
|
9
|
+
export type { ProxyProviderConfig } from './proxy/client.js';
|
|
10
|
+
export type { ProxyBatchConfig, ProxyRetryConfig, ProxyEvent, ProxyPayload, ProxyTrackEvent, ProxyIdentifyEvent, ProxyPageViewEvent, ProxyResetEvent, } from './proxy/types.js';
|
package/dist/providers/client.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { B as
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var f = (h, n, i) => n in h ? u(h, n, { enumerable: !0, configurable: !0, writable: !0, value: i }) : h[n] = i;
|
|
3
|
+
var r = (h, n, i) => f(h, typeof n != "symbol" ? n + "" : n, i);
|
|
4
|
+
import { B as o } from "../base.provider-AfFL5W_P.js";
|
|
5
5
|
import { i as l } from "../client-DTHZYkxx.js";
|
|
6
|
-
import { P as
|
|
7
|
-
class
|
|
8
|
-
constructor(
|
|
9
|
-
super({ debug:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.config =
|
|
6
|
+
import { P as E } from "../client-DTHZYkxx.js";
|
|
7
|
+
class y extends o {
|
|
8
|
+
constructor(i) {
|
|
9
|
+
super({ debug: i.debug, enabled: i.enabled });
|
|
10
|
+
r(this, "name", "Bento-Client");
|
|
11
|
+
r(this, "bento");
|
|
12
|
+
r(this, "initialized", !1);
|
|
13
|
+
r(this, "config");
|
|
14
|
+
r(this, "scriptLoaded", !1);
|
|
15
|
+
this.config = i;
|
|
16
16
|
}
|
|
17
17
|
async initialize() {
|
|
18
18
|
if (this.isEnabled() && !this.initialized) {
|
|
@@ -24,109 +24,109 @@ class m extends h {
|
|
|
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 (i) {
|
|
28
|
+
throw console.error("[Bento-Client] Failed to initialize:", i), i;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async loadBentoScript() {
|
|
33
|
-
return new Promise((
|
|
33
|
+
return new Promise((i, e) => {
|
|
34
34
|
if (document.querySelector(
|
|
35
35
|
'script[src*="bentonow.com"]'
|
|
36
36
|
)) {
|
|
37
|
-
this.scriptLoaded = !0,
|
|
37
|
+
this.scriptLoaded = !0, i();
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
this.scriptLoaded = !0,
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
}, document.head.appendChild(
|
|
40
|
+
const t = document.createElement("script");
|
|
41
|
+
t.src = `https://cdn.bentonow.com/v1/${this.config.siteUuid}/bento.js`, t.async = !0, t.onload = () => {
|
|
42
|
+
this.scriptLoaded = !0, i();
|
|
43
|
+
}, t.onerror = () => {
|
|
44
|
+
e(new Error("Failed to load Bento script"));
|
|
45
|
+
}, document.head.appendChild(t);
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
async waitForBento(
|
|
49
|
-
for (let s = 0; s <
|
|
48
|
+
async waitForBento(i = 50, e = 100) {
|
|
49
|
+
for (let s = 0; s < i; s++) {
|
|
50
50
|
if (window.bento)
|
|
51
51
|
return;
|
|
52
|
-
await new Promise((
|
|
52
|
+
await new Promise((t) => setTimeout(t, e));
|
|
53
53
|
}
|
|
54
54
|
throw new Error("Bento SDK not available after loading script");
|
|
55
55
|
}
|
|
56
|
-
identify(
|
|
56
|
+
identify(i, e) {
|
|
57
57
|
if (!this.isEnabled() || !this.initialized || !this.bento) return;
|
|
58
|
-
const s = (
|
|
59
|
-
if (this.bento.identify(s),
|
|
60
|
-
const
|
|
61
|
-
delete
|
|
58
|
+
const s = (e == null ? void 0 : e.email) || i;
|
|
59
|
+
if (this.bento.identify(s), e) {
|
|
60
|
+
const t = { ...e };
|
|
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: i, email: s, traits: e });
|
|
64
64
|
}
|
|
65
|
-
track(
|
|
66
|
-
var
|
|
65
|
+
track(i, e) {
|
|
66
|
+
var t, a;
|
|
67
67
|
if (!this.isEnabled() || !this.initialized || !this.bento) return;
|
|
68
68
|
const s = {
|
|
69
|
-
...
|
|
70
|
-
category:
|
|
71
|
-
timestamp:
|
|
72
|
-
...
|
|
73
|
-
...
|
|
74
|
-
...(
|
|
69
|
+
...i.properties,
|
|
70
|
+
category: i.category,
|
|
71
|
+
timestamp: i.timestamp || Date.now(),
|
|
72
|
+
...i.userId && { userId: i.userId },
|
|
73
|
+
...i.sessionId && { sessionId: i.sessionId },
|
|
74
|
+
...(e == null ? void 0 : e.page) && {
|
|
75
75
|
page: {
|
|
76
|
-
path:
|
|
77
|
-
title:
|
|
78
|
-
referrer:
|
|
76
|
+
path: e.page.path,
|
|
77
|
+
title: e.page.title,
|
|
78
|
+
referrer: e.page.referrer
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
...(
|
|
82
|
-
...(
|
|
81
|
+
...(e == null ? void 0 : e.device) && { device: e.device },
|
|
82
|
+
...(e == null ? void 0 : e.utm) && { utm: e.utm },
|
|
83
83
|
// Include user email and traits as regular event properties
|
|
84
|
-
...((
|
|
85
|
-
...((
|
|
84
|
+
...((t = e == null ? void 0 : e.user) == null ? void 0 : t.email) && { user_email: e.user.email },
|
|
85
|
+
...((a = e == null ? void 0 : e.user) == null ? void 0 : a.traits) && { user_traits: e.user.traits }
|
|
86
86
|
};
|
|
87
|
-
this.bento.track(
|
|
87
|
+
this.bento.track(i.action, s), this.log("Tracked event", { event: i, context: e });
|
|
88
88
|
}
|
|
89
|
-
pageView(
|
|
89
|
+
pageView(i, e) {
|
|
90
90
|
if (!(!this.isEnabled() || !this.initialized || !this.bento || !l())) {
|
|
91
|
-
if (this.bento.view(),
|
|
91
|
+
if (this.bento.view(), i || e != null && e.page) {
|
|
92
92
|
const s = {
|
|
93
|
-
...
|
|
94
|
-
...(
|
|
95
|
-
path:
|
|
96
|
-
title:
|
|
97
|
-
referrer:
|
|
93
|
+
...i,
|
|
94
|
+
...(e == null ? void 0 : e.page) && {
|
|
95
|
+
path: e.page.path,
|
|
96
|
+
title: e.page.title,
|
|
97
|
+
referrer: e.page.referrer
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
this.bento.track("$pageview", s);
|
|
101
101
|
}
|
|
102
|
-
this.log("Tracked page view", { properties:
|
|
102
|
+
this.log("Tracked page view", { properties: i, context: e });
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
-
pageLeave(
|
|
105
|
+
pageLeave(i, e) {
|
|
106
106
|
if (!this.isEnabled() || !this.initialized || !this.bento || !l())
|
|
107
107
|
return;
|
|
108
108
|
const s = {
|
|
109
|
-
...
|
|
110
|
-
...(
|
|
111
|
-
path:
|
|
112
|
-
title:
|
|
113
|
-
referrer:
|
|
109
|
+
...i,
|
|
110
|
+
...(e == null ? void 0 : e.page) && {
|
|
111
|
+
path: e.page.path,
|
|
112
|
+
title: e.page.title,
|
|
113
|
+
referrer: e.page.referrer
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
|
-
this.bento.track("$pageleave", s), this.log("Tracked page leave", { properties:
|
|
116
|
+
this.bento.track("$pageleave", s), this.log("Tracked page leave", { properties: i, context: e });
|
|
117
117
|
}
|
|
118
118
|
reset() {
|
|
119
119
|
!this.isEnabled() || !this.initialized || !this.bento || !l() || this.log("Reset user session - Note: Bento doesn't have a native reset method");
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
class
|
|
123
|
-
constructor(
|
|
124
|
-
super({ debug:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
this.config =
|
|
122
|
+
class w extends o {
|
|
123
|
+
constructor(i) {
|
|
124
|
+
super({ debug: i.debug, enabled: i.enabled });
|
|
125
|
+
r(this, "name", "Pirsch-Client");
|
|
126
|
+
r(this, "client");
|
|
127
|
+
r(this, "initialized", !1);
|
|
128
|
+
r(this, "config");
|
|
129
|
+
this.config = i;
|
|
130
130
|
}
|
|
131
131
|
async initialize() {
|
|
132
132
|
if (this.isEnabled() && !this.initialized) {
|
|
@@ -137,97 +137,237 @@ class b extends h {
|
|
|
137
137
|
if (!this.config.identificationCode || typeof this.config.identificationCode != "string")
|
|
138
138
|
throw new Error("Pirsch requires an identificationCode");
|
|
139
139
|
try {
|
|
140
|
-
const { Pirsch:
|
|
141
|
-
this.client = new
|
|
140
|
+
const { Pirsch: i } = await import("../web-CvEQewPd.js").then((e) => e.w);
|
|
141
|
+
this.client = new i({
|
|
142
142
|
identificationCode: this.config.identificationCode,
|
|
143
143
|
...this.config.hostname && { hostname: this.config.hostname }
|
|
144
144
|
}), this.initialized = !0, this.log("Initialized successfully", this.config);
|
|
145
|
-
} catch (
|
|
145
|
+
} catch (i) {
|
|
146
146
|
throw console.error(
|
|
147
147
|
"[Pirsch-Client] Failed to initialize. Make sure pirsch-sdk is installed:",
|
|
148
|
-
|
|
149
|
-
),
|
|
148
|
+
i
|
|
149
|
+
), i;
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
identify(
|
|
153
|
+
identify(i, e) {
|
|
154
154
|
!this.isEnabled() || !this.initialized || !this.client || (this.client.event("user_identified", 0, {
|
|
155
|
-
userId:
|
|
156
|
-
...
|
|
155
|
+
userId: i,
|
|
156
|
+
...e
|
|
157
157
|
}).catch((s) => {
|
|
158
158
|
console.error("[Pirsch-Client] Failed to track identify event:", s);
|
|
159
|
-
}), this.log("Identified user via event", { userId:
|
|
159
|
+
}), this.log("Identified user via event", { userId: i, traits: e }));
|
|
160
160
|
}
|
|
161
|
-
async track(
|
|
162
|
-
var
|
|
161
|
+
async track(i, e) {
|
|
162
|
+
var t, a;
|
|
163
163
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
164
164
|
const s = {
|
|
165
|
-
...
|
|
166
|
-
category:
|
|
167
|
-
...
|
|
168
|
-
...
|
|
169
|
-
...(
|
|
170
|
-
page_path:
|
|
171
|
-
page_title:
|
|
172
|
-
page_referrer:
|
|
165
|
+
...i.properties,
|
|
166
|
+
category: i.category,
|
|
167
|
+
...i.userId && { userId: i.userId },
|
|
168
|
+
...i.sessionId && { sessionId: i.sessionId },
|
|
169
|
+
...(e == null ? void 0 : e.page) && {
|
|
170
|
+
page_path: e.page.path,
|
|
171
|
+
page_title: e.page.title,
|
|
172
|
+
page_referrer: e.page.referrer
|
|
173
173
|
},
|
|
174
|
-
...(
|
|
175
|
-
...(
|
|
176
|
-
...((
|
|
177
|
-
...((
|
|
174
|
+
...(e == null ? void 0 : e.device) && { device: e.device },
|
|
175
|
+
...(e == null ? void 0 : e.utm) && { utm: e.utm },
|
|
176
|
+
...((t = e == null ? void 0 : e.user) == null ? void 0 : t.email) && { user_email: e.user.email },
|
|
177
|
+
...((a = e == null ? void 0 : e.user) == null ? void 0 : a.traits) && { user_traits: e.user.traits }
|
|
178
178
|
};
|
|
179
179
|
try {
|
|
180
|
-
await this.client.event(
|
|
181
|
-
} catch (
|
|
182
|
-
console.error("[Pirsch-Client] Failed to track event:",
|
|
180
|
+
await this.client.event(i.action, 0, s), this.log("Tracked event", { event: i, context: e });
|
|
181
|
+
} catch (d) {
|
|
182
|
+
console.error("[Pirsch-Client] Failed to track event:", d);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
pageView(
|
|
185
|
+
pageView(i, e) {
|
|
186
186
|
if (!(!this.isEnabled() || !this.initialized || !this.client || !l())) {
|
|
187
187
|
if (this.client.hit().catch((s) => {
|
|
188
188
|
console.error("[Pirsch-Client] Failed to track page view:", s);
|
|
189
|
-
}),
|
|
189
|
+
}), i && Object.keys(i).length > 0) {
|
|
190
190
|
const s = {
|
|
191
|
-
...
|
|
192
|
-
...(
|
|
193
|
-
path:
|
|
194
|
-
title:
|
|
195
|
-
referrer:
|
|
191
|
+
...i,
|
|
192
|
+
...(e == null ? void 0 : e.page) && {
|
|
193
|
+
path: e.page.path,
|
|
194
|
+
title: e.page.title,
|
|
195
|
+
referrer: e.page.referrer
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
|
-
this.client.event("page_view", 0, s).catch((
|
|
198
|
+
this.client.event("page_view", 0, s).catch((t) => {
|
|
199
199
|
console.error(
|
|
200
200
|
"[Pirsch-Client] Failed to track page view event:",
|
|
201
|
-
|
|
201
|
+
t
|
|
202
202
|
);
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
|
-
this.log("Tracked page view", { properties:
|
|
205
|
+
this.log("Tracked page view", { properties: i, context: e });
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
pageLeave(
|
|
208
|
+
pageLeave(i, e) {
|
|
209
209
|
if (!this.isEnabled() || !this.initialized || !this.client || !l())
|
|
210
210
|
return;
|
|
211
211
|
const s = {
|
|
212
|
-
...
|
|
213
|
-
...(
|
|
214
|
-
path:
|
|
215
|
-
title:
|
|
212
|
+
...i,
|
|
213
|
+
...(e == null ? void 0 : e.page) && {
|
|
214
|
+
path: e.page.path,
|
|
215
|
+
title: e.page.title
|
|
216
216
|
}
|
|
217
217
|
};
|
|
218
|
-
this.client.event("page_leave", 0, s).catch((
|
|
219
|
-
console.error("[Pirsch-Client] Failed to track page leave:",
|
|
220
|
-
}), this.log("Tracked page leave", { properties:
|
|
218
|
+
this.client.event("page_leave", 0, s).catch((t) => {
|
|
219
|
+
console.error("[Pirsch-Client] Failed to track page leave:", t);
|
|
220
|
+
}), this.log("Tracked page leave", { properties: i, context: e });
|
|
221
221
|
}
|
|
222
222
|
reset() {
|
|
223
|
-
!this.isEnabled() || !this.initialized || !this.client || !l() || (this.client.event("session_reset", 0, {}).catch((
|
|
224
|
-
console.error("[Pirsch-Client] Failed to track session reset:",
|
|
223
|
+
!this.isEnabled() || !this.initialized || !this.client || !l() || (this.client.event("session_reset", 0, {}).catch((i) => {
|
|
224
|
+
console.error("[Pirsch-Client] Failed to track session reset:", i);
|
|
225
225
|
}), this.log("Reset user session"));
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
|
+
class m extends o {
|
|
229
|
+
constructor(i) {
|
|
230
|
+
var e, s, t, a, d;
|
|
231
|
+
super({ debug: i.debug, enabled: i.enabled });
|
|
232
|
+
r(this, "name", "Proxy");
|
|
233
|
+
r(this, "config");
|
|
234
|
+
r(this, "queue", []);
|
|
235
|
+
r(this, "flushTimer");
|
|
236
|
+
r(this, "batchSize");
|
|
237
|
+
r(this, "batchInterval");
|
|
238
|
+
r(this, "retryAttempts");
|
|
239
|
+
r(this, "retryBackoff");
|
|
240
|
+
r(this, "retryInitialDelay");
|
|
241
|
+
this.config = i, this.batchSize = ((e = i.batch) == null ? void 0 : e.size) ?? 10, this.batchInterval = ((s = i.batch) == null ? void 0 : s.interval) ?? 5e3, this.retryAttempts = ((t = i.retry) == null ? void 0 : t.attempts) ?? 3, this.retryBackoff = ((a = i.retry) == null ? void 0 : a.backoff) ?? "exponential", this.retryInitialDelay = ((d = i.retry) == null ? void 0 : d.initialDelay) ?? 1e3, typeof window < "u" && (window.addEventListener("beforeunload", () => {
|
|
242
|
+
this.flush(!0);
|
|
243
|
+
}), document.addEventListener("visibilitychange", () => {
|
|
244
|
+
document.visibilityState === "hidden" && this.flush(!0);
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
async initialize() {
|
|
248
|
+
this.isEnabled() && this.log("Initialized successfully", { endpoint: this.config.endpoint });
|
|
249
|
+
}
|
|
250
|
+
identify(i, e) {
|
|
251
|
+
this.isEnabled() && (this.queueEvent({
|
|
252
|
+
type: "identify",
|
|
253
|
+
userId: i,
|
|
254
|
+
traits: e
|
|
255
|
+
}), this.log("Queued identify event", { userId: i, traits: e }));
|
|
256
|
+
}
|
|
257
|
+
async track(i, e) {
|
|
258
|
+
this.isEnabled() && (this.queueEvent({
|
|
259
|
+
type: "track",
|
|
260
|
+
event: i,
|
|
261
|
+
context: this.enrichContext(e)
|
|
262
|
+
}), this.log("Queued track event", { event: i, context: e }));
|
|
263
|
+
}
|
|
264
|
+
pageView(i, e) {
|
|
265
|
+
this.isEnabled() && (this.queueEvent({
|
|
266
|
+
type: "pageView",
|
|
267
|
+
properties: i,
|
|
268
|
+
context: this.enrichContext(e)
|
|
269
|
+
}), this.log("Queued page view event", { properties: i, context: e }));
|
|
270
|
+
}
|
|
271
|
+
async reset() {
|
|
272
|
+
this.isEnabled() && (this.queueEvent({
|
|
273
|
+
type: "reset"
|
|
274
|
+
}), this.log("Queued reset event"));
|
|
275
|
+
}
|
|
276
|
+
async shutdown() {
|
|
277
|
+
await this.flush(!0), this.log("Shutdown complete");
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Manually flush all queued events
|
|
281
|
+
*/
|
|
282
|
+
async flush(i = !1) {
|
|
283
|
+
if (this.queue.length === 0) return;
|
|
284
|
+
const e = [...this.queue];
|
|
285
|
+
this.queue = [], this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = void 0), await this.sendEvents(e, i);
|
|
286
|
+
}
|
|
287
|
+
queueEvent(i) {
|
|
288
|
+
if (this.queue.push(i), this.queue.length >= this.batchSize) {
|
|
289
|
+
this.flush().catch((e) => {
|
|
290
|
+
console.error("[Proxy] Failed to flush events:", e);
|
|
291
|
+
});
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
this.flushTimer || (this.flushTimer = setTimeout(() => {
|
|
295
|
+
this.flush().catch((e) => {
|
|
296
|
+
console.error("[Proxy] Failed to flush events:", e);
|
|
297
|
+
});
|
|
298
|
+
}, this.batchInterval));
|
|
299
|
+
}
|
|
300
|
+
async sendEvents(i, e = !1) {
|
|
301
|
+
const s = { events: i };
|
|
302
|
+
if (e && typeof navigator < "u" && navigator.sendBeacon) {
|
|
303
|
+
const t = new Blob([JSON.stringify(s)], {
|
|
304
|
+
type: "application/json"
|
|
305
|
+
});
|
|
306
|
+
navigator.sendBeacon(this.config.endpoint, t) || console.warn("[Proxy] Failed to send events via beacon");
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
await this.sendWithRetry(s);
|
|
310
|
+
}
|
|
311
|
+
async sendWithRetry(i, e = 0) {
|
|
312
|
+
try {
|
|
313
|
+
const s = await fetch(this.config.endpoint, {
|
|
314
|
+
method: "POST",
|
|
315
|
+
headers: {
|
|
316
|
+
"Content-Type": "application/json",
|
|
317
|
+
...this.config.headers
|
|
318
|
+
},
|
|
319
|
+
body: JSON.stringify(i),
|
|
320
|
+
// Don't include credentials by default
|
|
321
|
+
credentials: "same-origin"
|
|
322
|
+
});
|
|
323
|
+
if (!s.ok)
|
|
324
|
+
throw new Error(`HTTP ${s.status}: ${s.statusText}`);
|
|
325
|
+
this.log(`Sent ${i.events.length} events successfully`);
|
|
326
|
+
} catch (s) {
|
|
327
|
+
if (e < this.retryAttempts) {
|
|
328
|
+
const t = this.calculateRetryDelay(e);
|
|
329
|
+
return this.log(`Retry attempt ${e + 1} after ${t}ms`, { error: s }), await new Promise((a) => setTimeout(a, t)), this.sendWithRetry(i, e + 1);
|
|
330
|
+
}
|
|
331
|
+
throw console.error("[Proxy] Failed to send events after retries:", s), s;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
calculateRetryDelay(i) {
|
|
335
|
+
return this.retryBackoff === "exponential" ? this.retryInitialDelay * 2 ** i : this.retryInitialDelay * (i + 1);
|
|
336
|
+
}
|
|
337
|
+
enrichContext(i) {
|
|
338
|
+
return typeof window > "u" ? i || {} : {
|
|
339
|
+
...i,
|
|
340
|
+
page: {
|
|
341
|
+
path: window.location.pathname,
|
|
342
|
+
title: document.title,
|
|
343
|
+
referrer: document.referrer,
|
|
344
|
+
...i == null ? void 0 : i.page,
|
|
345
|
+
url: window.location.href
|
|
346
|
+
},
|
|
347
|
+
user: {
|
|
348
|
+
...i == null ? void 0 : i.user
|
|
349
|
+
},
|
|
350
|
+
device: {
|
|
351
|
+
...i == null ? void 0 : i.device,
|
|
352
|
+
userAgent: navigator.userAgent,
|
|
353
|
+
language: navigator.language,
|
|
354
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
355
|
+
screen: {
|
|
356
|
+
width: window.screen.width,
|
|
357
|
+
height: window.screen.height
|
|
358
|
+
},
|
|
359
|
+
viewport: {
|
|
360
|
+
width: window.innerWidth,
|
|
361
|
+
height: window.innerHeight
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
}
|
|
228
367
|
export {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
368
|
+
o as BaseAnalyticsProvider,
|
|
369
|
+
y as BentoClientProvider,
|
|
370
|
+
w as PirschClientProvider,
|
|
371
|
+
E as PostHogClientProvider,
|
|
372
|
+
m as ProxyProvider
|
|
233
373
|
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { BaseEvent, EventContext } from '../../core/events/types.js';
|
|
2
|
+
import { BaseAnalyticsProvider } from '../base.provider.js';
|
|
3
|
+
import { ProxyBatchConfig, ProxyRetryConfig } from './types.js';
|
|
4
|
+
export interface ProxyProviderConfig {
|
|
5
|
+
/**
|
|
6
|
+
* The endpoint to send events to (e.g., '/api/events')
|
|
7
|
+
*/
|
|
8
|
+
endpoint: string;
|
|
9
|
+
/**
|
|
10
|
+
* Batching configuration
|
|
11
|
+
*/
|
|
12
|
+
batch?: ProxyBatchConfig;
|
|
13
|
+
/**
|
|
14
|
+
* Retry configuration
|
|
15
|
+
*/
|
|
16
|
+
retry?: ProxyRetryConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Custom headers to include in requests
|
|
19
|
+
*/
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
/**
|
|
22
|
+
* Enable debug logging
|
|
23
|
+
*/
|
|
24
|
+
debug?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Enable/disable the provider
|
|
27
|
+
*/
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare class ProxyProvider extends BaseAnalyticsProvider {
|
|
31
|
+
name: string;
|
|
32
|
+
private config;
|
|
33
|
+
private queue;
|
|
34
|
+
private flushTimer?;
|
|
35
|
+
private readonly batchSize;
|
|
36
|
+
private readonly batchInterval;
|
|
37
|
+
private readonly retryAttempts;
|
|
38
|
+
private readonly retryBackoff;
|
|
39
|
+
private readonly retryInitialDelay;
|
|
40
|
+
constructor(config: ProxyProviderConfig);
|
|
41
|
+
initialize(): Promise<void>;
|
|
42
|
+
identify(userId: string, traits?: Record<string, unknown>): void;
|
|
43
|
+
track(event: BaseEvent, context?: EventContext): Promise<void>;
|
|
44
|
+
pageView(properties?: Record<string, unknown>, context?: EventContext): void;
|
|
45
|
+
reset(): Promise<void>;
|
|
46
|
+
shutdown(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Manually flush all queued events
|
|
49
|
+
*/
|
|
50
|
+
flush(useBeacon?: boolean): Promise<void>;
|
|
51
|
+
private queueEvent;
|
|
52
|
+
private sendEvents;
|
|
53
|
+
private sendWithRetry;
|
|
54
|
+
private calculateRetryDelay;
|
|
55
|
+
private enrichContext;
|
|
56
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ServerAnalytics } from '../../server.js';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for ingesting proxy events
|
|
4
|
+
*/
|
|
5
|
+
export interface IngestProxyEventsConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Enrich context with server-side data
|
|
8
|
+
*/
|
|
9
|
+
enrichContext?: (request: Request) => Record<string, unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Extract IP address from request
|
|
12
|
+
* Default: Uses standard headers (X-Forwarded-For, X-Real-IP)
|
|
13
|
+
*/
|
|
14
|
+
extractIp?: (request: Request) => string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Error handler
|
|
17
|
+
*/
|
|
18
|
+
onError?: (error: unknown) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Ingests events from ProxyProvider and replays them through server analytics
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Next.js App Router
|
|
26
|
+
* export async function POST(req: Request) {
|
|
27
|
+
* await ingestProxyEvents(req, serverAnalytics);
|
|
28
|
+
* return new Response('OK');
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* // With custom IP extraction
|
|
32
|
+
* export async function POST(req: Request) {
|
|
33
|
+
* await ingestProxyEvents(req, serverAnalytics, {
|
|
34
|
+
* extractIp: (req) => req.headers.get('cf-connecting-ip') // Cloudflare
|
|
35
|
+
* });
|
|
36
|
+
* return new Response('OK');
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function ingestProxyEvents<TEventMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TUserTraits extends Record<string, unknown> = Record<string, unknown>>(request: Request, analytics: ServerAnalytics<TEventMap, TUserTraits>, config?: IngestProxyEventsConfig): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Creates a Request handler for common frameworks
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* // Next.js App Router
|
|
47
|
+
* export const POST = createProxyHandler(serverAnalytics);
|
|
48
|
+
*
|
|
49
|
+
* // With custom config
|
|
50
|
+
* export const POST = createProxyHandler(serverAnalytics, {
|
|
51
|
+
* extractIp: (req) => req.headers.get('cf-connecting-ip')
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function createProxyHandler<TEventMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TUserTraits extends Record<string, unknown> = Record<string, unknown>>(analytics: ServerAnalytics<TEventMap, TUserTraits>, config?: IngestProxyEventsConfig): (request: Request) => Promise<Response>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { BaseEvent, EventContext } from '../../core/events/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Proxy event types for batching and sending to server
|
|
4
|
+
*/
|
|
5
|
+
export type ProxyTrackEvent = {
|
|
6
|
+
type: "track";
|
|
7
|
+
event: BaseEvent;
|
|
8
|
+
context?: EventContext;
|
|
9
|
+
};
|
|
10
|
+
export type ProxyIdentifyEvent = {
|
|
11
|
+
type: "identify";
|
|
12
|
+
userId: string;
|
|
13
|
+
traits?: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
export type ProxyPageViewEvent = {
|
|
16
|
+
type: "pageView";
|
|
17
|
+
properties?: Record<string, unknown>;
|
|
18
|
+
context?: EventContext;
|
|
19
|
+
};
|
|
20
|
+
export type ProxyResetEvent = {
|
|
21
|
+
type: "reset";
|
|
22
|
+
};
|
|
23
|
+
export type ProxyEvent = ProxyTrackEvent | ProxyIdentifyEvent | ProxyPageViewEvent | ProxyResetEvent;
|
|
24
|
+
/**
|
|
25
|
+
* Payload sent to the proxy endpoint
|
|
26
|
+
*/
|
|
27
|
+
export interface ProxyPayload {
|
|
28
|
+
events: ProxyEvent[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for batching behavior
|
|
32
|
+
*/
|
|
33
|
+
export interface ProxyBatchConfig {
|
|
34
|
+
/**
|
|
35
|
+
* Maximum number of events before auto-flush
|
|
36
|
+
* @default 10
|
|
37
|
+
*/
|
|
38
|
+
size?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Maximum time in ms before auto-flush
|
|
41
|
+
* @default 5000
|
|
42
|
+
*/
|
|
43
|
+
interval?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Configuration for retry behavior
|
|
47
|
+
*/
|
|
48
|
+
export interface ProxyRetryConfig {
|
|
49
|
+
/**
|
|
50
|
+
* Maximum retry attempts
|
|
51
|
+
* @default 3
|
|
52
|
+
*/
|
|
53
|
+
attempts?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Backoff strategy
|
|
56
|
+
* @default 'exponential'
|
|
57
|
+
*/
|
|
58
|
+
backoff?: "exponential" | "linear";
|
|
59
|
+
/**
|
|
60
|
+
* Initial delay in ms
|
|
61
|
+
* @default 1000
|
|
62
|
+
*/
|
|
63
|
+
initialDelay?: number;
|
|
64
|
+
}
|
|
@@ -5,3 +5,5 @@ export { BentoServerProvider } from './bento/server.js';
|
|
|
5
5
|
export type { BentoServerConfig, BentoAnalyticsOptions } from './bento/server.js';
|
|
6
6
|
export { PirschServerProvider } from './pirsch/server.js';
|
|
7
7
|
export type { PirschServerConfig } from './pirsch/server.js';
|
|
8
|
+
export { ingestProxyEvents, createProxyHandler } from './proxy/server.js';
|
|
9
|
+
export type { IngestProxyEventsConfig } from './proxy/server.js';
|
package/dist/providers/server.js
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { B as
|
|
5
|
-
import { P as
|
|
6
|
-
class
|
|
7
|
-
constructor(
|
|
8
|
-
super({ debug:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.config =
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var y = (l, n, i) => n in l ? f(l, n, { enumerable: !0, configurable: !0, writable: !0, value: i }) : l[n] = i;
|
|
3
|
+
var d = (l, n, i) => y(l, typeof n != "symbol" ? n + "" : n, i);
|
|
4
|
+
import { B as p } from "../base.provider-AfFL5W_P.js";
|
|
5
|
+
import { P as z } from "../server-DjEk1fUD.js";
|
|
6
|
+
class v extends p {
|
|
7
|
+
constructor(i) {
|
|
8
|
+
super({ debug: i.debug, enabled: i.enabled });
|
|
9
|
+
d(this, "name", "Bento-Server");
|
|
10
|
+
d(this, "client");
|
|
11
|
+
d(this, "initialized", !1);
|
|
12
|
+
d(this, "config");
|
|
13
|
+
d(this, "currentUserEmail");
|
|
14
|
+
this.config = i;
|
|
15
15
|
}
|
|
16
16
|
async initialize() {
|
|
17
|
-
var
|
|
17
|
+
var i, e;
|
|
18
18
|
if (this.isEnabled() && !this.initialized) {
|
|
19
19
|
if (!this.config.siteUuid || typeof this.config.siteUuid != "string")
|
|
20
20
|
throw new Error("Bento requires a siteUuid");
|
|
21
|
-
if (!((
|
|
21
|
+
if (!((i = this.config.authentication) != null && i.publishableKey) || typeof this.config.authentication.publishableKey != "string")
|
|
22
22
|
throw new Error("Bento requires authentication.publishableKey");
|
|
23
|
-
if (!((
|
|
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:
|
|
27
|
-
this.client = new
|
|
26
|
+
const { Analytics: s } = await import("../bento-node-sdk.esm-C4HG7SVz.js"), { debug: a, enabled: t, ...o } = this.config;
|
|
27
|
+
this.client = new s(o), this.initialized = !0, this.log("Initialized successfully", {
|
|
28
28
|
siteUuid: this.config.siteUuid
|
|
29
29
|
});
|
|
30
|
-
} catch (
|
|
30
|
+
} catch (s) {
|
|
31
31
|
throw console.error(
|
|
32
32
|
"[Bento-Server] Failed to initialize. Make sure @bentonow/bento-node-sdk is installed:",
|
|
33
|
-
|
|
34
|
-
),
|
|
33
|
+
s
|
|
34
|
+
), s;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
identify(
|
|
38
|
+
identify(i, e) {
|
|
39
39
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
40
|
-
const
|
|
41
|
-
this.currentUserEmail =
|
|
42
|
-
const a =
|
|
40
|
+
const s = (e == null ? void 0 : e.email) || i;
|
|
41
|
+
this.currentUserEmail = s;
|
|
42
|
+
const a = e ? { ...e } : {};
|
|
43
43
|
delete a.email, this.client.V1.addSubscriber({
|
|
44
|
-
email:
|
|
44
|
+
email: s,
|
|
45
45
|
fields: a
|
|
46
|
-
}).catch((
|
|
47
|
-
console.error("[Bento-Server] Failed to identify user:",
|
|
48
|
-
}), this.log("Identified user", { userId:
|
|
46
|
+
}).catch((t) => {
|
|
47
|
+
console.error("[Bento-Server] Failed to identify user:", t);
|
|
48
|
+
}), this.log("Identified user", { userId: i, email: s, traits: e });
|
|
49
49
|
}
|
|
50
|
-
async track(
|
|
51
|
-
var
|
|
50
|
+
async track(i, e) {
|
|
51
|
+
var o, r, h;
|
|
52
52
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
53
|
-
const
|
|
54
|
-
...
|
|
55
|
-
category:
|
|
56
|
-
timestamp:
|
|
57
|
-
...
|
|
58
|
-
...(
|
|
53
|
+
const s = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail || ((r = e == null ? void 0 : e.user) == null ? void 0 : r.userId) || i.userId || "anonymous@unknown.com", a = {
|
|
54
|
+
...i.properties,
|
|
55
|
+
category: i.category,
|
|
56
|
+
timestamp: i.timestamp || Date.now(),
|
|
57
|
+
...i.sessionId && { sessionId: i.sessionId },
|
|
58
|
+
...(e == null ? void 0 : e.page) && {
|
|
59
59
|
page: {
|
|
60
|
-
path:
|
|
61
|
-
title:
|
|
62
|
-
referrer:
|
|
60
|
+
path: e.page.path,
|
|
61
|
+
title: e.page.title,
|
|
62
|
+
referrer: e.page.referrer
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
|
-
...(
|
|
66
|
-
...(
|
|
67
|
-
},
|
|
65
|
+
...(e == null ? void 0 : e.device) && { device: e.device },
|
|
66
|
+
...(e == null ? void 0 : e.utm) && { utm: e.utm }
|
|
67
|
+
}, t = ((h = e == null ? void 0 : e.user) == null ? void 0 : h.traits) || {};
|
|
68
68
|
try {
|
|
69
69
|
await this.client.V1.track({
|
|
70
|
-
email:
|
|
71
|
-
type: `$${
|
|
70
|
+
email: s,
|
|
71
|
+
type: `$${i.action}`,
|
|
72
72
|
details: a,
|
|
73
|
-
fields:
|
|
74
|
-
}), this.log("Tracked event", { event:
|
|
75
|
-
} catch (
|
|
76
|
-
console.error("[Bento-Server] Failed to track event:",
|
|
73
|
+
fields: t
|
|
74
|
+
}), this.log("Tracked event", { event: i, context: e });
|
|
75
|
+
} catch (u) {
|
|
76
|
+
console.error("[Bento-Server] Failed to track event:", u);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
pageView(
|
|
80
|
-
var
|
|
79
|
+
pageView(i, e) {
|
|
80
|
+
var o, r;
|
|
81
81
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
82
|
-
const
|
|
83
|
-
...
|
|
84
|
-
...(
|
|
85
|
-
path:
|
|
86
|
-
title:
|
|
87
|
-
referrer:
|
|
82
|
+
const s = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail || "anonymous@unknown.com", a = {
|
|
83
|
+
...i,
|
|
84
|
+
...(e == null ? void 0 : e.page) && {
|
|
85
|
+
path: e.page.path,
|
|
86
|
+
title: e.page.title,
|
|
87
|
+
referrer: e.page.referrer
|
|
88
88
|
}
|
|
89
|
-
},
|
|
89
|
+
}, t = ((r = e == null ? void 0 : e.user) == null ? void 0 : r.traits) || {};
|
|
90
90
|
this.client.V1.track({
|
|
91
|
-
email:
|
|
91
|
+
email: s,
|
|
92
92
|
type: "$pageview",
|
|
93
93
|
details: a,
|
|
94
|
-
fields:
|
|
95
|
-
}).catch((
|
|
96
|
-
console.error("[Bento-Server] Failed to track page view:",
|
|
97
|
-
}), this.log("Tracked page view", { properties:
|
|
94
|
+
fields: t
|
|
95
|
+
}).catch((h) => {
|
|
96
|
+
console.error("[Bento-Server] Failed to track page view:", h);
|
|
97
|
+
}), this.log("Tracked page view", { properties: i, context: e });
|
|
98
98
|
}
|
|
99
99
|
async reset() {
|
|
100
100
|
!this.isEnabled() || !this.initialized || !this.client || (this.currentUserEmail = void 0, this.log("Reset user session"));
|
|
@@ -103,14 +103,14 @@ class b extends f {
|
|
|
103
103
|
this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
class
|
|
107
|
-
constructor(
|
|
108
|
-
super({ debug:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.config =
|
|
106
|
+
class E extends p {
|
|
107
|
+
constructor(i) {
|
|
108
|
+
super({ debug: i.debug, enabled: i.enabled });
|
|
109
|
+
d(this, "name", "Pirsch-Server");
|
|
110
|
+
d(this, "client");
|
|
111
|
+
d(this, "initialized", !1);
|
|
112
|
+
d(this, "config");
|
|
113
|
+
this.config = i;
|
|
114
114
|
}
|
|
115
115
|
async initialize() {
|
|
116
116
|
if (this.isEnabled() && !this.initialized) {
|
|
@@ -119,106 +119,189 @@ class w extends f {
|
|
|
119
119
|
if (!this.config.clientSecret || typeof this.config.clientSecret != "string")
|
|
120
120
|
throw new Error("Pirsch requires a clientSecret (or access key)");
|
|
121
121
|
try {
|
|
122
|
-
const { Pirsch:
|
|
123
|
-
this.client = new
|
|
122
|
+
const { Pirsch: i } = await import("../index-bgxxv-IJ.js").then((t) => t.i), { debug: e, enabled: s, ...a } = this.config;
|
|
123
|
+
this.client = new i(a), this.initialized = !0, this.log("Initialized successfully", {
|
|
124
124
|
hostname: this.config.hostname
|
|
125
125
|
});
|
|
126
|
-
} catch (
|
|
126
|
+
} catch (i) {
|
|
127
127
|
throw console.error(
|
|
128
128
|
"[Pirsch-Server] Failed to initialize. Make sure pirsch-sdk is installed:",
|
|
129
|
-
|
|
130
|
-
),
|
|
129
|
+
i
|
|
130
|
+
), i;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
identify(
|
|
134
|
+
identify(i, e) {
|
|
135
135
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
136
|
-
const
|
|
136
|
+
const s = {
|
|
137
137
|
url: "https://identify",
|
|
138
138
|
ip: "0.0.0.0",
|
|
139
139
|
user_agent: "analytics-library"
|
|
140
140
|
}, a = {
|
|
141
|
-
userId:
|
|
142
|
-
...
|
|
143
|
-
Object.entries(
|
|
144
|
-
([,
|
|
141
|
+
userId: i,
|
|
142
|
+
...e && Object.fromEntries(
|
|
143
|
+
Object.entries(e).filter(
|
|
144
|
+
([, t]) => typeof t == "string" || typeof t == "number" || typeof t == "boolean"
|
|
145
145
|
)
|
|
146
146
|
)
|
|
147
147
|
};
|
|
148
|
-
this.client.event("user_identified",
|
|
149
|
-
console.error("[Pirsch-Server] Failed to track identify event:",
|
|
150
|
-
}), this.log("Identified user via event", { userId:
|
|
148
|
+
this.client.event("user_identified", s, 0, a).catch((t) => {
|
|
149
|
+
console.error("[Pirsch-Server] Failed to track identify event:", t);
|
|
150
|
+
}), this.log("Identified user via event", { userId: i, traits: e });
|
|
151
151
|
}
|
|
152
|
-
async track(
|
|
153
|
-
var
|
|
152
|
+
async track(i, e) {
|
|
153
|
+
var o, r, h, u;
|
|
154
154
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
155
|
-
const
|
|
156
|
-
url: ((
|
|
155
|
+
const s = {
|
|
156
|
+
url: ((o = e == null ? void 0 : e.page) == null ? void 0 : o.path) || "https://event",
|
|
157
157
|
ip: "0.0.0.0",
|
|
158
158
|
// Server-side should provide real IP if available
|
|
159
159
|
user_agent: "analytics-library",
|
|
160
160
|
// Server-side should provide real UA if available
|
|
161
|
-
...((
|
|
162
|
-
...((
|
|
163
|
-
},
|
|
161
|
+
...((r = e == null ? void 0 : e.page) == null ? void 0 : r.title) && { title: e.page.title },
|
|
162
|
+
...((h = e == null ? void 0 : e.page) == null ? void 0 : h.referrer) && { referrer: e.page.referrer }
|
|
163
|
+
}, t = {
|
|
164
164
|
...Object.fromEntries(
|
|
165
|
-
Object.entries(
|
|
166
|
-
([,
|
|
165
|
+
Object.entries(i.properties).filter(
|
|
166
|
+
([, c]) => typeof c == "string" || typeof c == "number" || typeof c == "boolean"
|
|
167
167
|
)
|
|
168
168
|
),
|
|
169
|
-
category:
|
|
170
|
-
timestamp: String(
|
|
171
|
-
...
|
|
172
|
-
...
|
|
173
|
-
...((
|
|
169
|
+
category: i.category,
|
|
170
|
+
timestamp: String(i.timestamp || Date.now()),
|
|
171
|
+
...i.userId && { userId: i.userId },
|
|
172
|
+
...i.sessionId && { sessionId: i.sessionId },
|
|
173
|
+
...((u = e == null ? void 0 : e.user) == null ? void 0 : u.email) && { user_email: e.user.email }
|
|
174
174
|
};
|
|
175
175
|
try {
|
|
176
|
-
await this.client.event(
|
|
177
|
-
} catch (
|
|
178
|
-
console.error("[Pirsch-Server] Failed to track event:",
|
|
176
|
+
await this.client.event(i.action, s, 0, t), this.log("Tracked event", { event: i, context: e });
|
|
177
|
+
} catch (c) {
|
|
178
|
+
console.error("[Pirsch-Server] Failed to track event:", c);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
pageView(
|
|
182
|
-
var a,
|
|
181
|
+
pageView(i, e) {
|
|
182
|
+
var a, t, o;
|
|
183
183
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
184
|
-
const
|
|
185
|
-
url: ((a =
|
|
184
|
+
const s = {
|
|
185
|
+
url: ((a = e == null ? void 0 : e.page) == null ? void 0 : a.path) || "https://pageview",
|
|
186
186
|
ip: "0.0.0.0",
|
|
187
187
|
// Server-side should provide real IP if available
|
|
188
188
|
user_agent: "analytics-library",
|
|
189
189
|
// Server-side should provide real UA if available
|
|
190
|
-
...((
|
|
191
|
-
...((
|
|
192
|
-
...
|
|
190
|
+
...((t = e == null ? void 0 : e.page) == null ? void 0 : t.title) && { title: e.page.title },
|
|
191
|
+
...((o = e == null ? void 0 : e.page) == null ? void 0 : o.referrer) && { referrer: e.page.referrer },
|
|
192
|
+
...i && {
|
|
193
193
|
tags: Object.fromEntries(
|
|
194
|
-
Object.entries(
|
|
195
|
-
([,
|
|
194
|
+
Object.entries(i).filter(
|
|
195
|
+
([, r]) => typeof r == "string" || typeof r == "number" || typeof r == "boolean"
|
|
196
196
|
)
|
|
197
197
|
)
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
|
-
this.client.hit(
|
|
201
|
-
console.error("[Pirsch-Server] Failed to track page view:",
|
|
202
|
-
}), this.log("Tracked page view", { properties:
|
|
200
|
+
this.client.hit(s).catch((r) => {
|
|
201
|
+
console.error("[Pirsch-Server] Failed to track page view:", r);
|
|
202
|
+
}), this.log("Tracked page view", { properties: i, context: e });
|
|
203
203
|
}
|
|
204
204
|
async reset() {
|
|
205
205
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
206
|
-
const
|
|
206
|
+
const i = {
|
|
207
207
|
url: "https://session-reset",
|
|
208
208
|
ip: "0.0.0.0",
|
|
209
209
|
user_agent: "analytics-library"
|
|
210
210
|
};
|
|
211
|
-
await this.client.event("session_reset",
|
|
212
|
-
console.error("[Pirsch-Server] Failed to track session reset:",
|
|
211
|
+
await this.client.event("session_reset", i, 0, {}).catch((e) => {
|
|
212
|
+
console.error("[Pirsch-Server] Failed to track session reset:", e);
|
|
213
213
|
}), this.log("Reset user session");
|
|
214
214
|
}
|
|
215
215
|
async shutdown() {
|
|
216
216
|
this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
|
+
async function g(l, n, i) {
|
|
220
|
+
var e, s;
|
|
221
|
+
try {
|
|
222
|
+
const a = await l.json();
|
|
223
|
+
if (!a.events || !Array.isArray(a.events))
|
|
224
|
+
throw new Error("Invalid payload: missing events array");
|
|
225
|
+
const t = i != null && i.extractIp ? i.extractIp(l) : m(l), o = i != null && i.enrichContext ? i.enrichContext(l) : {};
|
|
226
|
+
for (const r of a.events)
|
|
227
|
+
try {
|
|
228
|
+
switch (r.type) {
|
|
229
|
+
case "track": {
|
|
230
|
+
const h = {
|
|
231
|
+
...r.context,
|
|
232
|
+
...o,
|
|
233
|
+
device: {
|
|
234
|
+
...(e = r.context) == null ? void 0 : e.device,
|
|
235
|
+
// Add IP (using type assertion for extended fields)
|
|
236
|
+
...t ? { ip: t } : {}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
await n.track(r.event.action, r.event.properties, {
|
|
240
|
+
userId: r.event.userId,
|
|
241
|
+
sessionId: r.event.sessionId,
|
|
242
|
+
context: h
|
|
243
|
+
});
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
case "identify": {
|
|
247
|
+
n.identify(r.userId, r.traits);
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
case "pageView": {
|
|
251
|
+
const h = {
|
|
252
|
+
...r.context,
|
|
253
|
+
...o,
|
|
254
|
+
device: {
|
|
255
|
+
...(s = r.context) == null ? void 0 : s.device,
|
|
256
|
+
// Add IP (using type assertion for extended fields)
|
|
257
|
+
...t ? { ip: t } : {}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
n.pageView(r.properties, h);
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
case "reset":
|
|
264
|
+
break;
|
|
265
|
+
default:
|
|
266
|
+
console.warn("[Proxy] Unknown event type:", r);
|
|
267
|
+
}
|
|
268
|
+
} catch (h) {
|
|
269
|
+
i != null && i.onError ? i.onError(h) : console.error("[Proxy] Failed to process event:", h);
|
|
270
|
+
}
|
|
271
|
+
} catch (a) {
|
|
272
|
+
throw i != null && i.onError ? i.onError(a) : console.error("[Proxy] Failed to ingest events:", a), a;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function m(l) {
|
|
276
|
+
var i;
|
|
277
|
+
const n = [
|
|
278
|
+
"x-forwarded-for",
|
|
279
|
+
"x-real-ip",
|
|
280
|
+
"cf-connecting-ip",
|
|
281
|
+
// Cloudflare
|
|
282
|
+
"x-client-ip",
|
|
283
|
+
"x-cluster-client-ip"
|
|
284
|
+
];
|
|
285
|
+
for (const e of n) {
|
|
286
|
+
const s = l.headers.get(e);
|
|
287
|
+
if (s)
|
|
288
|
+
return (i = s.split(",")[0]) == null ? void 0 : i.trim();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function k(l, n) {
|
|
292
|
+
return async (i) => {
|
|
293
|
+
try {
|
|
294
|
+
return await g(i, l, n), new Response("OK", { status: 200 });
|
|
295
|
+
} catch (e) {
|
|
296
|
+
return console.error("[Proxy] Handler error:", e), new Response("Internal Server Error", { status: 500 });
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}
|
|
219
300
|
export {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
301
|
+
p as BaseAnalyticsProvider,
|
|
302
|
+
v as BentoServerProvider,
|
|
303
|
+
E as PirschServerProvider,
|
|
304
|
+
z as PostHogServerProvider,
|
|
305
|
+
k as createProxyHandler,
|
|
306
|
+
g as ingestProxyEvents
|
|
224
307
|
};
|